<br><br><div class="gmail_quote">On Thu, Sep 29, 2011 at 6:20 PM, Brendan Eich <span dir="ltr"><<a href="mailto:brendan@mozilla.com">brendan@mozilla.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">

<div style="word-wrap:break-word"><div><div class="im"><div>On Sep 30, 2011, at 1:11 AM, Erik Arvidsson wrote:</div><br><blockquote type="cite"><div>On Thu, Sep 29, 2011 at 17:08, Bob Nystrom <<a href="mailto:rnystrom@google.com" target="_blank">rnystrom@google.com</a>> wrote:<br>

<blockquote type="cite">class Monster {<br></blockquote><blockquote type="cite">  constructor(<a href="http://this.name" target="_blank">this.name</a>, this.health) {}<br></blockquote></div></blockquote><div><br></div></div>

I <3 this. It beats the (public name, public health) variant in my view by being explicit and not dragging in p-words.</div></div></blockquote><div><br></div><div>Yeah, me too. The big win for me here is that I find this confusing:</div>

<div><br></div><div><font class="Apple-style-span" face="'courier new', monospace">class Point {</font></div><div><font class="Apple-style-span" face="'courier new', monospace">  constructor(public x, public y) {</font></div>

<div><font class="Apple-style-span" face="'courier new', monospace">    x = 2; // is this valid? does it assign to this.x or just the local argument variable?</font></div><div><font class="Apple-style-span" face="'courier new', monospace">  }</font></div>

<div><font class="Apple-style-span" face="'courier new', monospace">}</font></div><div><br></div><div>Using this.x in the constructor parameter list maintains a consistent "always use this. to assign to object properties", which I like.</div>

<div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;"><div style="word-wrap:break-word"><div>This is great, and I'm still a sections fan, but they mix badly if there are any hints or smells of object literal data property initialiser synax.</div>

</div></blockquote><div><br></div><div>Right. Personally, I'm not a fan of mixing object literal style into classes (though I see the appeal from a unification perspective). Maybe that's just my long C++/C#/Java habits.</div>

<div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;"><div style="word-wrap:break-word"><div> You (Bob) dodge that by using let, Oliver used var (and IIRC Bob started with var; so did ES4)</div>

</div></blockquote><div><br></div><div>Yup. I actually prefer "var" slightly though I understand it gives Mark hives (and for good reason). I don't really have much of a keyword preference here at all as long as it's really short. Could be "thing" for all I care. :)</div>

<div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;"><div style="word-wrap:break-word"><div> -- however, Oliver and ES4 by fiat put data properties on the instance, methods on the prototype.</div>

</div></blockquote><div><br></div><div>That feels a little... non-orthogonal? to me. Inside a class when you're defining some property, there's two things you need to specify:</div><div><br></div><div>1. What flavor of property it is: function, constant, field, etc.</div>

<div>2. What object it gets defined on: constructor, prototype, instance.</div><div><br></div><div>Mixing those together so that 1 determines 2 feels kind of arbitrary and not as flexible. I like the idea of the grammar informing one and sections informing 2. Maybe that's just me.</div>

<div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;"><div style="word-wrap:break-word"><div>Separately, and a while ago, Alex pointed out that mutable prototype data properties, e..g let attackers = []; in this Monster example, are a footgun. People fail to shadow and mutate a shared singleton.</div>

</div></blockquote><div><br></div><div>Yeah, I worry about that too, though I'm leery of giving up generality to dodge that. (People complain as it is that class syntax is too rigid.)</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">

<div style="word-wrap:break-word"><div>So why do we need declarative syntax for data properties on the prototype at all? Data properties on prototypes are exceedingly rare and usually a bug.</div></div></blockquote><div>
<br>
</div><div>We want a syntax for properties on the constructor, so is it worth it to specifically forbid that notation outside of the class: section?</div><div><br></div><div>If we <i>did</i> want to go down the path of a more rigid class pattern (i.e. no data props on prototype, etc.) then I think we could support all of the combinations we care about with a pretty terse notation:</div>

<div><br></div><div><div><font class="Apple-style-span" face="'courier new', monospace">class Point extends SomeBaseClass {</font></div><div><font class="Apple-style-span" face="'courier new', monospace">  // Constructor.</font></div>

<div><font class="Apple-style-span" face="'courier new', monospace">  constructor(this.x, this.y) {</font></div><div><font class="Apple-style-span" face="'courier new', monospace">    class.lastPoint = this;</font></div>

<div><font class="Apple-style-span" face="'courier new', monospace">  }</font></div><div><font class="Apple-style-span" face="'courier new', monospace"><br></font></div><div><font class="Apple-style-span" face="'courier new', monospace">  // Constant on class.</font></div>

<div><font class="Apple-style-span" face="'courier new', monospace">  const ZERO = new Point(0, 0);</font></div><div><font class="Apple-style-span" face="'courier new', monospace"><br></font></div><div><font class="Apple-style-span" face="'courier new', monospace">  // Data property on class.</font></div>

<div><font class="Apple-style-span" face="'courier new', monospace">  var lastPoint = undefined; // or let</font></div><div><font class="Apple-style-span" face="'courier new', monospace"><br></font></div>
<div>
<font class="Apple-style-span" face="'courier new', monospace">  // Function on class.</font></div><div><font class="Apple-style-span" face="'courier new', monospace">  class add(a, b) {</font></div><div>
<font class="Apple-style-span" face="'courier new', monospace">    return a.add(b);</font></div>
<div><font class="Apple-style-span" face="'courier new', monospace">  }</font></div><div><font class="Apple-style-span" face="'courier new', monospace"><br></font></div><div><font class="Apple-style-span" face="'courier new', monospace">  // Nested class (data property on class whose value is a class).</font></div>

<div><font class="Apple-style-span" face="'courier new', monospace">  class Foo {</font></div><div><font class="Apple-style-span" face="'courier new', monospace">    ...</font></div><div><font class="Apple-style-span" face="'courier new', monospace">  }</font></div>

<div><font class="Apple-style-span" face="'courier new', monospace"><br></font></div><div><font class="Apple-style-span" face="'courier new', monospace">  // Constant on prototype: not supported</font></div>

<div><font class="Apple-style-span" face="'courier new', monospace">  // Data property on prototype: not supported</font></div><div><font class="Apple-style-span" face="'courier new', monospace"><br></font></div>

<div><font class="Apple-style-span" face="'courier new', monospace">  // Function on prototype.</font></div><div><font class="Apple-style-span" face="'courier new', monospace">  add(other) {</font></div><div>

<font class="Apple-style-span" face="'courier new', monospace">    return new Point(this.x + other.x, this.y + other.y);</font></div><div><font class="Apple-style-span" face="'courier new', monospace">  }</font></div>

<div><font class="Apple-style-span" face="'courier new', monospace">}</font></div></div><div><br></div><div>This gets rid of sections, and gets rid of "static" by using "class" instead. It avoids the "class class" problem for nested classes by declaring by fiat that a nested class goes on the constructor.</div>

<div><br></div><div>Thoughts?</div><div></div></div><br><div>- bob</div>