On Nov 30, 2012, at 2:20 PM, Jason Orendorff wrote:
The ordinary [[Construct]] internal method (which is what the new
operator actually uses) when invoked upon a constructor function
performs two steps. It first instantiates a new object instances (and
sets its [[Prototype]] internal property). It then calls the constructor
function using the new object as the this value so that the constructor
can perform initialization.
In the past on this list we have discussed the utility of being able to
separately over-ride the [[Construct]] and [[Call]] behavior of a
function (and Proxies enable this). What Jason is proposing is a
variation of this. Instead of exposing a @@method that completely
replaces [[Construct]] he is proposing a method that replaces the
allocation step of [[Construct]]. Such a method, in addition to
performing actual allocation, could also perform any allocation time
initialization that should be separate from the constructor
functionality. This permits the constructor function to be super invoked
without doing allocation-time initialization upon the subclass instance.
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] would be defined as:
Let creator be Foo.[Get]
2 ) Let newObj be creator.call(foo). //Foo is passed as the this value
to @@create
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]].
Allen Wirfs-Brock wrote:
>
> On Nov 30, 2012, at 2:20 PM, Jason Orendorff wrote:
>
> The ordinary [[Construct]] internal method (which is what the new
> operator actually uses) when invoked upon a constructor function
> performs two steps. It first instantiates a new object instances (and
> sets its [[Prototype]] internal property). It then calls the constructor
> function using the new object as the this value so that the constructor
> can perform initialization.
>
> In the past on this list we have discussed the utility of being able to
> separately over-ride the [[Construct]] and [[Call]] behavior of a
> function (and Proxies enable this). What Jason is proposing is a
> variation of this. Instead of exposing a @@method that completely
> replaces [[Construct]] he is proposing a method that replaces the
> allocation step of [[Construct]]. Such a method, in addition to
> performing actual allocation, could also perform any allocation time
> initialization that should be separate from the constructor
> functionality. This permits the constructor function to be super invoked
> without doing allocation-time initialization upon the subclass instance.
>
> 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
Herby
Allen Wirfs-Brock wrote:
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]].