Allen Wirfs-Brock (2013-02-20T18:57:59.000Z)
On Feb 20, 2013, at 9:24 AM, Tom Van Cutsem wrote:

> 2013/2/18 Andreas Rossberg <rossberg at google.com>
> On 16 February 2013 20:36, Allen Wirfs-Brock <allen at wirfs-brock.com> wrote:
> 
>  > It's to simplify the MOP and that simplification is directly reflected as a simplification to the Proxy hander interface. Instead of  6 traps (preventExtensions, isExtensible, freeze, isFrozen, seal, isSealed) only two are needed.
> >
> > Also, having an explicit frozen object state simplifies some of the object invariants which would otherwise perform explicitly specified accesses to the target object which would be observable (if the target is itself a proxy).
> 
> Well, that is either a breaking change, such that implementations can
> not actually be lazy about it, or it doesn't really remove complexity,
> since you still need to infer the state as a fallback (i.e., it's just
> an optimisation).
> 
> I don't necessarily oppose making that breaking change, but we have to
> be aware that, even though it's an optimisation, the change is yet
> another complication of the object model. The additional state
> modifies the meaning of per-property descriptors on a second level.
> IIUC, defineProperty now has to check against that state, and
> getOwnPropertyDescriptor somehow has to take it into account, too. For
> direct proxies, the respective traps have to extend their validation
> logic. Overall, not a simplification, as far as I can see.
> 
> I've been thinking some more about get/setIntegrity and I've come to the same conclusion. While get/setIntegrity gets rid of 4 traps (sealed/isSealed/frozen/isFrozen), it does so at the expense of extra complexity in other parts of the MOP, in particular, adding yet more state to check and update in [[GetOwnProperty]] and [[DefineOwnProperty]].
> 
> Allen, in light of this, wouldn't you agree that it's better to keep the extra traps?

Actually, no.  Reducing API complexity (in this case, the Proxy handler API) at the expense of a little bit of added spec. complexity seems like a very reasonable trade-off.  Plus, we are talking about spec. complexity, not necessarily implementation complexity.  An implementation is free to distribute the complexity however it chooses.  For example, if an implementation always sets all of an objet's  property descriptors to configurable: false when [[SetIntegrity]]("frozen") is performed (which Object.freeze is specified to do in ES5) then there shouldn't be any extra work that needs to be done in the ordinary implementations of  [[GetOwnProperty]] or [[DefineOwnProperty]].

Also, I'm concerned that we have been overloading the meaning of the [[Extensible]] state by hanging other meanings off of it, because it is the only "integrity state" we currently have at the object level.  For example, we have tentative agreement at the timevalue of Date objects can not be modified if [[Extensible]] is false and that RegExp.prototype.compile will not update an RegExp instance if [[Extensible]] is false.  Both of these seem like things that would be better to associate with an explicit "frozen" object state. We are also, from ES5, using [[Extensible]] to control whether [[Prototype]] can be modified.  This is a case where I think a new state might be appropriate as it seems very reasonable for an object to want to fix [[Prototype]] but still allow own properties to be added

Finally, I still think we should further consider the feasibly of a breaking change where 
     Object.preventExtensions(obj); for ( let k of Object.getOwnPropertyKeys(obj)) Object.defineProperty(obj,k,{configurable:false});
is no longer equivalent to 
      Object.freeze(obj)
in terms of causing Object.isFrozen(obj) to return false.

I think I previously asked if anybody is aware of situations where Object.isFrozen tests are done but Object.freeze is not used to set objects to the frozen state.  So far, no answers.  Anybody?

Allen







> 
> Cheers,
> Tom

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20130220/ea2b2fc2/attachment.html>
github at esdiscuss.org (2013-07-12T02:26:27.628Z)
On Feb 20, 2013, at 9:24 AM, Tom Van Cutsem wrote:

> 2013/2/18 Andreas Rossberg <rossberg at google.com>
> On 16 February 2013 20:36, Allen Wirfs-Brock <allen at wirfs-brock.com> wrote:
> 
>  > It's to simplify the MOP and that simplification is directly reflected as a simplification to the Proxy hander interface. Instead of  6 traps (preventExtensions, isExtensible, freeze, isFrozen, seal, isSealed) only two are needed.
> >
> > Also, having an explicit frozen object state simplifies some of the object invariants which would otherwise perform explicitly specified accesses to the target object which would be observable (if the target is itself a proxy).
> 
> Well, that is either a breaking change, such that implementations can
> not actually be lazy about it, or it doesn't really remove complexity,
> since you still need to infer the state as a fallback (i.e., it's just
> an optimisation).
> 
> I don't necessarily oppose making that breaking change, but we have to
> be aware that, even though it's an optimisation, the change is yet
> another complication of the object model. The additional state
> modifies the meaning of per-property descriptors on a second level.
> IIUC, defineProperty now has to check against that state, and
> getOwnPropertyDescriptor somehow has to take it into account, too. For
> direct proxies, the respective traps have to extend their validation
> logic. Overall, not a simplification, as far as I can see.
> 
> I've been thinking some more about get/setIntegrity and I've come to the same conclusion. While get/setIntegrity gets rid of 4 traps (sealed/isSealed/frozen/isFrozen), it does so at the expense of extra complexity in other parts of the MOP, in particular, adding yet more state to check and update in [[GetOwnProperty]] and [[DefineOwnProperty]].
> 
> Allen, in light of this, wouldn't you agree that it's better to keep the extra traps?

Actually, no.  Reducing API complexity (in this case, the Proxy handler API) at the expense of a little bit of added spec. complexity seems like a very reasonable trade-off.  Plus, we are talking about spec. complexity, not necessarily implementation complexity.  An implementation is free to distribute the complexity however it chooses.  For example, if an implementation always sets all of an objet's  property descriptors to configurable: false when [[SetIntegrity]]("frozen") is performed (which Object.freeze is specified to do in ES5) then there shouldn't be any extra work that needs to be done in the ordinary implementations of  [[GetOwnProperty]] or [[DefineOwnProperty]].

Also, I'm concerned that we have been overloading the meaning of the [[Extensible]] state by hanging other meanings off of it, because it is the only "integrity state" we currently have at the object level.  For example, we have tentative agreement at the timevalue of Date objects can not be modified if [[Extensible]] is false and that RegExp.prototype.compile will not update an RegExp instance if [[Extensible]] is false.  Both of these seem like things that would be better to associate with an explicit "frozen" object state. We are also, from ES5, using [[Extensible]] to control whether [[Prototype]] can be modified.  This is a case where I think a new state might be appropriate as it seems very reasonable for an object to want to fix [[Prototype]] but still allow own properties to be added

Finally, I still think we should further consider the feasibly of a breaking change where

    Object.preventExtensions(obj);
    for (let k of Object.getOwnPropertyKeys(obj))
      Object.defineProperty(obj,k,{configurable:false});

is no longer equivalent to 

    Object.freeze(obj)

in terms of causing `Object.isFrozen(obj)` to return false.

I think I previously asked if anybody is aware of situations where `Object.isFrozen` tests are done but `Object.freeze` is not used to set objects to the frozen state.  So far, no answers.  Anybody?

Allen







> 
> Cheers,
> Tom

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