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