On Sep 14, 2014, at 4:23 PM, Brendan Eich wrote:

> Kevin Smith wrote:
>> If we want to merge allocation with initialization, then I'm going to want 
>> to invoke C# (yet again):
>> 
>>    class ColoredPoint extends Point {
>>        constructor(x, y, color) : super(x, y) {
>>           this.color = color;
>>        }
>>    }
> 
> Gotta credt C#'s parents, C++, which would require Point not super.
> 
> I think you are really onto something here. We do not want anything looking 
> like an expression-statement in the constructor body, which besides being 
> verbose has unwanted degrees of freedom (requiring TDZ for `this`, running 
> into the dead code problem Jeff cited, etc.).

the dead code problem (and we can debate whether it is actually a significant 
problem) goes away with alternative 2 (no automatic mew super in derived class 
constructors. 

The TDZ constrained `this` is an elegant solution which we had a good consensus 
on at the last TC39 meeting. Since then we have developed has it further 
unifies various allocation patterns that come up in JS object constructions.  
Everybody really need to really work through all the use cases given in the 
Gists and similarly work through them all with what every other alternatives 
they may think would be better. 

> 
> It sure seems to me that we rather want a special form in the constructor 
> head. This came up in ES4.

the C/C# constructor header approach butts heads with other ES features and 
isn't expressive for the sort of dynamic classes that ES allows.

In terms of headbutting, consider

`constructor({a: x, b: y), [a1,a2,a3,...arest], c ) : super(??, ??) {}//  what 
do I put here to super call the constructor with only the first two arguments)`

perhaps:

`constructor{a: x, b: y), [a1,a2,a3,...arest], c ) : super(arguments[0], 
arguments[1]) {}`

but that means that the special header form must allow arbitrary expressions.  
Are those expression in the parameter scope of the body scope.

Most importantly, a single constrained expression isn't expressive enough.  The 
problem, is that a subclass constructor may need to perform arbitrary compelx 
computations before super newing the its base constructor.  For example, 
consider a TypeArray subclass constructor that filters various collections 
passed to to the derived  constructor to produce a simple list iterator that it 
passed to the  base constructor.

The constrained super expression is a slippery slope that leads you to a cliff. 
Better to go with the full generality and expressiveness of the function body.

> 
> Separately I agree `this = new super(x, y);` is just crazy long and very 
> likely to be left out in whole or in part (the `new`).

If left-out, programs will fail quickly and noisily (reference errors) 
especially with the no auto super design alternative.

And this hardly seems like a significant length issue as we are talking about 
something that at typically occurs only once per subclass with an extends 
clause. And not even for all subclasses.

and ignoring white space we are taking about either +5 characters ("this=") or 
8 characters ("this=new") if you think the alternative is is just "super" 
without a "new".  But in https://gist.github.com/allenwb/291035fbf910eab8e9a6 
we addressed why it is really a bad idea to make "super(a,b)"  be a 
[[Construct]] operation rather than a [[Call]] operation. Basically, JS is 
currently very consistent in that `new foo()` and `foo()` do not have the same 
language level meanings.  It would be a big WTFJS if we changed things such 
that  sometimes the syntax for a [[Call]] really means a [[Construct]].  
Especially, if that meaning is dependent upon how the enclosing function was 
invoked rather than being statically determined.  Example, in the rationale 
document.

As I mentioned a couple of times in conversations, those of use who worked on 
developing this design found that the syntax really grows upon you.  It's big 
advantage is that is is unambiguously explicit.  If you want to invoke a 
constructor "as a constructor" you always say `new`. `new foo()` or new 
super(), it doesn't make a difference, `new` always means [[Constructor]]. If 
you want to invoke a constructor "as a function" you do a normal function 
invocation.  Again, either `foo()` or `super()`.  It's the same.  The [[Call]] 
syntax is never repurpose to mean [[Construct]] so there are no special cases 
to explain or remember.  Also, if you want to designate the `this` value used 
within a constructor you always explicit say `this=`, whether it is `this = 
super()' or `this=mayFactoy()` or `this = new Proxy(new super(), {...});`. 
Again, it is always explicit, no magic `super` calls that magically sets `this` 
as a side-effect.

It's this explicitness that grows on you.  The code actually says what it means.

Allen

_______________________________________________
es-discuss mailing list
[email protected]
https://mail.mozilla.org/listinfo/es-discuss

Reply via email to