(Weak){Set|Map} subclassing

Herby Vojčík herby at mailbox.sk
Tue Dec 4 05:37:32 PST 2012

Allen Wirfs-Brock wrote:
> On Dec 3, 2012, at 3:03 PM, Jason Orendorff wrote:
>> On Sat, Dec 1, 2012 at 2:38 PM, Allen Wirfs-Brock
>> <allen at wirfs-brock.com <mailto:allen at wirfs-brock.com>> wrote:
>>     The simplification I've thought about is eliminating [[Construct]]
>>     as an internal method/Proxy trap and just making the call
>>     @@Create/call consturctor sequence the evaluation semantics of the
>>     new operator. But I've not yet convinced myself that this is
>>     sufficient to capture all of the "called as constructor"/"called
>>     as a function" semantic silliness that some chapter 15 built-ins
>>     have. I'm also not sure that DOM and friends don't have other
>>     dependencies on a reified [[Construt]]
>> The simplification I had in mind was changing [[Construct]] from an
>> internal method/Proxy trap to an ordinary .@@construct method. There
>> would be a @@construct/constructor split rather than a
>> [[Construct]]/@@create/constructor split.
>> But on reflection, it didn't seem like that would be simpler in
>> practice. Having two separately hookable phases of object construction
>> is just right. A class can easily customize either behavior in a way
>> that not only works, but will still work when the class is subclassed
>> further.
>> -j
> OK, so it sounds like we have a plan. I'll update the spec. to use @@create.

Maybe it has been lost somewhere 
but I'd like to propose a little bit around call vs. init separation, 
that fits into this restructuting, copying older post here:

 > Overall, I like this approach. However, I don't think @@create belongs
 > on the prototype object. This make the @@create functionality for a
 > particular kind of object available to anyone who gets their hands on an
 > instance object of the class. This smells like a capability leak.
 > Instead, I would make @@create a property of the actual constructor
 > function and I would place the default @@create on Function.prototype,
 > which all functions inherit from.
 > So roughly speaking, Foo.[[Constructor]](...args) would be defined as:
 > 1) Let creator be Foo.[[Get]](@@create)
 > 2 ) Let newObj be creator.call(foo). //Foo is passed as the this value
 > to @@create
 > 3) Let ctorResult be Foo.[[call]](newObj,args)
 > 4) If Type(ctorResult) is Object, return ctorResult
 > 5) else return newObj

I have just thought about this, and came to similar conclusion, but not
using @@create, but by splitting [[Construct]] into [[Alloc]] and
[[Init]]. My reasoning was more about speccing that [[Init]] is used
instead of [[Call]] in new as well as in super(...). So I don't care if
[[Alloc]] is [[Alloc]] or @@create.

But I did not know whether there is will to respecify [[Construct]]. If
there is, would it be reasonable to define [[Call]] on functions as well
as [[Init]] on constructor functions, as invoke it instead of [[Call]]
in [[Construct]] (and also super(...), but there the [[Call]] is buried
deeper in some abstract operation)? The default [[Init]] is to delegate
to [[Call]], but is potentially different.


As a _second_ step / food for thought, not a part of previous proposal,
so please take them separately, thanks, [[Construct]] could be
refactored from internal operation ([[...]]) into abstract spec
operation, and constructor could be tested by presence of [[Init]].

 > The definition of the Function.prototype.@@create would be loosely
 > function() {
 > return Object.create(this.prototype);
 > }
 > Allen


More information about the es-discuss mailing list