new instantiation design alternatives

Allen Wirfs-Brock allen at wirfs-brock.com
Mon Sep 15 11:08:29 PDT 2014


On Sep 14, 2014, at 9:24 PM, Brendan Eich wrote:

> Allen Wirfs-Brock wrote:
>> 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.
> 
> You meant "or", I'm sure. Kevin replied "yes" and "yes", which is funny, but either way, parameters are in scope. That's a no-brainer. Why is this a dilemma?

Because, if it is in the parameter scope, rather than the body scope then Kevin's "gimmeSomeComplexSuperArgsYo" function can't be an inner function of the constructor.  It has to be an unencapsualted function outside of the class definition.  If it is in the body scope it is code that physically outside of the { }'s but evaluated as if it was inside the {}'s.

> 
>> 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.
> 
> FWIW, I wouldn't want such a thing!

that was just a quick off-the cuff for instance.  I probably wouldn't recommend that particular design either.  But the point is that while "invoke the super class constructor first" is probably the most common use case (that's why I favor the auto-super design alternative) for other use cases you may need to perform arbitrary complex computations before invoking the super class constructor.  And JS is a statement-based  language or arbitrary computation means potentially multiple statements. 
> 
> In the C++ family (Andreas is right, there's a history and lineage to consider), the special head form may require you to keep it simple and put any such conditioning in the base class, or an intermediary. This doesn't bite back much.

C++/C# aren't the only C syntax  object-based language.  Other very widely used C syntax languages (eg, Java) don't use that special head form at all.  So it is hard to argue that the C++/C# header form is universally familiar.  (BTW, what percentage of JS programmers now come from a C++/C#/Java background.  Seems kind of backwards looking). 

Also, most of the cited precedent language are subclass===subtype languages, unlike JS,  Ruby, etc. So we need to think extra hard about whether precedent is relevant.

> 
> Are you sure you've sorted use-cases by use-frequency?

I didn't claim they were.  In the gist, the use cases are roughly ordered by increasing complexity and secondarily by likely use-case frequency. 
> 
> 
>> 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.
> 
> You need to demonstrate this, instead of assuming it.

It's certainly something I've encountered many times.  And it's just a special of the general pattern of a method doing a super-call to the method it over-rides.  Sometimes you want to do a super call first ( "after" in AOP or Lisp parlance), sometimes you want to do the super call at the end (a "before" wrapper) and sometimes you want to do it in the middle ("around").  Lots of examples of all of these exist in real world code.

> 
>>> 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 then people will take TC39's name in vain. Every time.
> 
> We're trying to get this right, so arguing about design means minimizing spank-the-user-to-write-boilerplate footguns. Saying "there's an error" does not refute. There had better be an error! But can't we do better?
> 
>> It's this explicitness that grows on you.  The code actually says what it means.
> 
> Classes as sugar, not as salt. The way this is headed, people will go back to functions. I'm not kidding.

I have to respectfully disagree with this unprovable conjecture.

But feel free to propose and champion a complete alternative proposal that address all aspects of object instantiation design. That's probably a better approach than trying to incrementally change details of a coherent design until it is something completely different.  

Allen




More information about the es-discuss mailing list