@@new

Allen Wirfs-Brock allen at wirfs-brock.com
Wed Jun 18 12:08:51 PDT 2014


On Jun 18, 2014, at 11:41 AM, Brendan Eich wrote:

> Allen Wirfs-Brock wrote:
>> Except in the current design there is no special reinterpretation of the constructor method body semantics.  The constructor method definition simply provides body of the constructor function and semantically is exactly the same as the body that is provided in a Function definition. See http://people.mozilla.org/~jorendorff/es6-draft.html#sec-runtime-semantics-classdefinitionevaluation <http://people.mozilla.org/%7Ejorendorff/es6-draft.html#sec-runtime-semantics-classdefinitionevaluation> and in particular step 10 which calls http://people.mozilla.org/~jorendorff/es6-draft.html#sec-runtime-semantics-definemethod <http://people.mozilla.org/%7Ejorendorff/es6-draft.html#sec-runtime-semantics-definemethod> which just calls http://people.mozilla.org/~jorendorff/es6-draft.html#sec-functioncreate <http://people.mozilla.org/%7Ejorendorff/es6-draft.html#sec-functioncreate> .  No special processing of the body anywhere along that path.  The only special treatment prior to step 10 is about choosing a default constructor body if a constructor method isn't provided in the class declaration.
> 
> Fair point, things have changed. Still, here are some other bits of magic that make constructor(){} as ClassElement not just a method definition. Here's another:
> 
> * 'constructor' is not enumerable but methods are.
> 
Yes, but that's just preserving the 'constructor' property attribute conventions established by function definition.  Nothing to do with the semantics of the actual constructor body or that a "class" object".

>> 
>> It is an alternative syntax for providing a the body of a function, but it has no unique semantics.  That seems significant to me.
> 
> Not so much to me, and one could argue for static [@@new](){} sugar similarly.

I think that fact that these really are semantically equivalent:

 function F(x) {this.foo=};
 class F  {constructor(x) {this.foo=x}};

is pretty important to the evolutionary nature ES6 classes.

> 
> The most important thing here (I agree with Andreas R.) is -- if possible -- avoiding uninitialized object observability.

I agree that uninitialized observability is a pain and has been a on-going source of reentrancy bugs in the the more complex built-in constructors.  I want to explore whether making the constructor arguments available to @@create provides an alternative way to eliminate that issue.

Also, much of the initialization checking complexity in the legacy built-ins is about maintain backwards compatibility for edgy use cases (for example, installing a built-in constructor that has factory called behavior as an instance method on one of its instances and then invoking it as as a method).  Jason's explicit split between "called as a function" and "called as a method" make it easier to specify that but I'm not sure the other forward facing complexities it introduces is worth the spec. simplification we get for a few legacy built-in constructors.

There is a lot of legacy compatibility vs. future functionality trade-offs that have been made in the current design. It's good to look at those trade-off and see if any of them need to be rebalanced.  But we need to be careful about the scope of changes we are considering and whether in the end we actually get to a better place.  

Allen



More information about the es-discuss mailing list