<html><head></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><div><div>On Sep 30, 2011, at 12:22 AM, Erik Arvidsson wrote:</div><br class="Apple-interchange-newline"><blockquote type="cite"><div>4. Allow const classes<br></div></blockquote><div><br></div>Hold this thought...</div><div><br></div><div><br><blockquote type="cite"><div>The question is do we have to solve these? I argue that we don't have<br>to solve these for ES.next. By postponing these we can provide an even<br>simpler class proposal that provides sugar to how people do<br>inheritance today using ES5.<br></div></blockquote><div><br></div>Obviously I like your thinking! Don't take my nit-picking below wrong. Please do pick or prove harmless-if-not-beneficial every nit.</div><div><br></div><div><br><blockquote type="cite"><div>class Derived extends Base { // Object literal body<br>  constructor(x) {  // constructor<br>    this._x = x;  // no special form<br>    // Disallow return expr?<br>  }  // optional comma from @awbjs<br>  get x() { return this._x; }<br>  prop: 42,<br>  method() {}  // method form @awbjs<br>};<br></div></blockquote><div><br></div>Waldemar had some objections to comma elision in object literals, they would apply here too or need to be overcome. If we support only methods, then class body syntax can be its own thing, and drop otiose commas or other separators. But your prop:42 needs a , after it, Waldemar's counterexample used [privateName] as the next key and that would instead "index" into the previous property's value.</div><div><br></div><div>So why do we need prototype data properties? I'd drop them as my (4), and keep const classes (since Mark will insist, and the desugaring is easy enough -- more below).</div><div><br></div><div><br><blockquote type="cite"><div>This is syntactic sugar for<br><br>var Derived = Base <| function(x) {<br>  this._x = x;<br>}.prototype.{<br>  get x() { ... },<br>  prop: 42,<br>  method() {}<br>  constructor: Derived // hand wave here, needs {enumerable: false}<br>and reference to something not yet available.<br></div></blockquote><div><br></div>No need for "constructor: Derived // hand wave..." because <| clones (or unobservably mutates) its RHS function, and functions get .prototype properties with magic .constructor back-links for free. The mustache you use in the desugaring *extends* Derived.prototype, it does not lose the default .constructor back-link in that object.</div><div><br></div><div>However, you do need a .constructor at the end, so the constructor and not its prototype is assigned to var Derived.</div><div><br></div><div>Nit: s/var/let/ -- class should bind as let does, block-scoped and hoisted with temporal dead zone.</div><div><br></div><div>Ok, here's the const class desugaring:</div><div><br></div><div><span class="Apple-style-span" style="font-family: monospace; ">const Derived =</span></div><div><span class="Apple-style-span" style="font-family: monospace; "> Object.freeze(</span></div><div><span class="Apple-style-span" style="font-family: monospace; ">  Object.freeze(</span></div><div><span class="Apple-style-span" style="font-family: monospace; ">   Base <| function(x) {</span><span class="Apple-style-span" style="font-family: monospace; "><br></span><span class="Apple-style-span" style="font-family: monospace; ">    this._x = x;</span></div><div><span class="Apple-style-span" style="font-family: monospace; ">    Object.seal(this);<br></span><span class="Apple-style-span" style="font-family: monospace; ">   }.prototype.{</span><span class="Apple-style-span" style="font-family: monospace; "><br></span><span class="Apple-style-span" style="font-family: monospace; ">    get x() { ... },</span><span class="Apple-style-span" style="font-family: monospace; "><br></span><span class="Apple-style-span" style="font-family: monospace; ">    prop: 42,</span><span class="Apple-style-span" style="font-family: monospace; "><br></span><span class="Apple-style-span" style="font-family: monospace; ">    method() {}</span><span class="Apple-style-span" style="font-family: monospace; "><br></span></div><div><span class="Apple-style-span" style="font-family: monospace; ">   }</span></div><div><span class="Apple-style-span" style="font-family: monospace; ">  ).constructor</span></div><div><span class="Apple-style-span" style="font-family: monospace; "> );</span></div><div><span class="Apple-style-span" style="font-family: monospace; "><br></span></div><div><span class="Apple-style-span" style="font-family: monospace; ">If you buy this, then I think class methods and other properties of the constructor are equally easy. We can defer them, but they do not add novel challenges as const instance variables and barriers to prevent partially initialized objects from leaking do. The only vexing issue is what syntax to use? A "static" keyword is at this point traditional, but we all hate it. Are we being too pure?</span></div><div><span class="Apple-style-span" style="font-family: monospace; "><br></span></div><div><span class="Apple-style-span" style="font-family: monospace; ">/be</span></div></body></html>