Good-bye constructor functions?

Allen Wirfs-Brock allen at wirfs-brock.com
Mon Jan 7 16:54:56 PST 2013


On Jan 7, 2013, at 4:09 PM, Herby Vojčík wrote:

> 
> 
> Allen Wirfs-Brock wrote:
>> OK, I ready you proposal.  I'll summaries it:
>> 
>> class Sub extends Super {
>>    constructor (...args) {
>>        super(...args);  //or super.constructor(...args)  because they mean the same thing.
>>   }
>> }
>> 
>> creates an (almost) ordinary object that is the initial value of the Sub binding.  The [[Prototype]] of Sub is the value of Super. Sub is created with a "prototype" property whose value is a new ordinary object whose [[Prototype]] values is Super.prototype.  Sub.prototype has a method property named "constructor" whose value is a super bound method function with the user specified body.  There is nothing special about this method, it it just like any other method defined in a class declaration.  In particular it does not have a [[Construct]] internal property.
>> 
>> The only thing exotic about Sub is that the object has a [[Construct]] internal method.  It does not have a [[Call]] internal method.  The definition of its [[Construct]] in almost JS pseudo code is:
>> 
>>       //internal method  this.[[Constructor]](argList):
>>       let newObj = this.@@create();  //eg Sub.@@create();
>>       let replacementObj = this.prototype.constructor.apply(newObj, argList);
>>       if (typeof replacementObj == "object"&&  replacementObj !== null) return replacementObj
>>       return newObj;
>> 
>> Implications:
>>    Sub === Sub.prototype.constructor evaluates to false.
>>    To create a new instance of Sub say:
>>            new Sub()
>>    The following is a TypeError, because Sub does not have a [[Call]] internal method:
>>           Sub()
>>    The following is a TypeError, because Sub.prototype.constructor does not have a [[Construct]] internal method:
>>            new Sub.prototype.constructor()
>>     Sub.prototype.constructor can be called directly or as a method invocation including via a super call a subclass of Sub.
>> 
>> It seems to me, all you have accomplished here is to make it illegal
>> to call a class object directly as a function. If we were starting
> 
> From technical PoV*, yes.
> Oh, and I fixed the super / new inconsistency.

I just don't see such an inconsistency in the current ES6 spec. draft.  A constructor is just a function that is usually called with a this value.  This is true whether it is called by the [[Constructor]] internal method or via a super/super.constructor call.  In either case, the  primary purpose of the constructor is to perform initialization actions upon the this value.  Where is the inconsistency?

The only anomaly I see is that a handful of legacy built-ins do completely different things for new operator originated calls in contrast to regular function calls.   There is no confusion in the spec. about this and the mechanism for accomplishing it. However such split behavior can't be declaratively defined in a normal function or class declaration.   In the other thread at  https://mail.mozilla.org/pipermail/es-discuss/2013-January/027864.html  I described how this split behavior an be procedurally described in such declarations and also described how the same technique can be applied to the offending built-in constructors (r any user defined class constructor) to discriminate between initialization and "called" behavior, even when called via super.

The only "fix" I saw that you made to super was that in you sketch constructor methods defined via a class definition are only used for instance initialization, so there doesn't need to be any code to determine between initialization and call behavior.  Constructor behavior is always initialization behavior.  

However, you don't support non-new invocation behavior, at all, on class objects so you can't use a class to self-host an implementation of, for example, RegExp.  You also, don't do any thing to support correct initialization of subclass of built-ins such as RegExp and Number that have different behaviors for "called as constructor" and "called as function".

Allen



-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20130107/d787c373/attachment.html>


More information about the es-discuss mailing list