[[SetInheritance]] (was: General comments response (was Re: ES6 Rev13 Review: MOP-refactoring, symbols, proxies, Reflect module))

Tom Van Cutsem tomvc.be at gmail.com
Mon Dec 31 03:08:15 PST 2012


2012/12/30 Allen Wirfs-Brock <allen at wirfs-brock.com>

>
> On Dec 29, 2012, at 2:37 PM, Tom Van Cutsem wrote:
>  > * [[SetInheritance]]/Reflect.setPrototypeOf: I'm not sure this was
> agreed upon. Especially since __proto__ is currently specified as a data
> property. This means there is no setter that separately reifies the ability
> to set the prototype. Thus, it's perfectly possible to just exclude
> [[SetInheritance]] and Reflect.setPrototypeOf from the spec.
>
> No, [[SetInheritence]] needs to be part of the MOP.  Certainly to define
> the semantics of __proto__ takes more than just saying it is a data
> property. Regardless of whether  it is ultimately reflected as that or as
> an accessor property the semantics of setting it has to be specified in
> some manner that likes it to the value that is retrieved by
> [[GetInheritance]].  Also, there are already in the spec. at least three
> forms of objects (ordinary, exotic symbols, exotic proxies) with different
> implementations of [[SetInheritance]] so an internal MOP method has already
> proven to be a useful specification device.
>

Ok. I did a search for [[SetInheritance]] in the Rev13 draft and the only
place this method was called was from Reflect.setPrototypeOf and the Proxy
"setPrototypeOf" trap default. That's why I thought it could easily be
removed. I now see the note that appendix B3.1 (specifying __proto__) is
not yet up-to-date. Probably when it's updated, this part of the spec will
also call [[SetInheritance]].


> Whether or not it is reflected as a Proxy trap is a separate matter.  When
> this was discussed recently on es-discuss, the point was made that even if
> [[SetInhertance]] intersession by a trap is disallowed (ie, a trap can't
> prevent [[SetInheritance]] with the same value from being automatically
> invoked on the target) it is still important to get a notification that
> [[SetInheritiance]] has occurred. This is similar, to other traps whose
> handler behaviors are restricted but were still deemed useful from a
> notification perspective.  I believe that the conclusion of that discussion
> we seemed to have agreement that [[GetInhertiance]] should be handled in
> this same manner.
>

It seems there are two routes we can take
a) Introduce a "setPrototypeOf" trap (as currently specified), with the
invariant check that the new prototype must match that of the target if
setPrototypeOf returns true (a return value of "false" would mean the proxy
rejected the prototype change).

b) Not treat __proto__ as a magical property on proxies, and get rid of the
"setPrototypeOf" trap. This implies that aProxy.__proto__ = val just
triggers the "set" trap. This delegates the choice of whether to treat
__proto__ as magical or not to every individual proxy handler.

Reflect.setPrototypeOf is not essential and simply there to provide a point
> of further discussion. I think it is desirable that the Reflect.* interface
> be an accurate reflection of the internal MOP.


I agree that if we take choice (a) (i.e. introduce a "setPrototypeOf" trap)
then we should also have the corresponding Reflect.setPrototypeOf primitive.


> Any and all, restrictions that are applied to __prototype__ can also be
> applied to Reflect.setPrototypeOf.  In fact, the specification of it can be
> essentially:
>
>  function setPrototypeOf(target, parent) {
>    target.__proto__ = parent
>  };
>

Yep.


> I'm also of the school that if we are going to accept a mutable
> inheritance chain as a standard part of the language then we might as well
> embrace it rather than treating is as the black sheep that we try to
> pretend isn't really there.
>

Agreed. Although we should make an effort to make it easy for
sandboxes/dialects to remove the feature from the language.

That said, I think this issue is orthogonal to our choice of whether or not
to expose "setPrototypeOf" as part of the MOP. Even if we do expose it, any
sandbox that wants to take away the ability the set the prototype can
simply poison Reflect.setPrototypeOf in addition to deleting
Object.prototype.__proto__.

Cheers,
Tom
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20121231/e3fe2206/attachment.html>


More information about the es-discuss mailing list