[ES Harmony Proxies] Fundamental trap definition (refinement) and derived traps definitions

David Bruant bruant at enseirb-matmeca.fr
Mon Jan 24 15:44:41 PST 2011


If 'getPropertyNames' and 'getPropertyDescriptor' becomes derived traps,
then one question arises:
Should derived traps be defined only thanks to fundamental traps or
thanks to what Mark Miller called in a previous e-mail "remaining traps"
(what I understand as all the rest, modulo obviously avoiding
interdepencies issues)? This question doesn't need to be asked if
'getPropertyNames' and 'getPropertyDescriptor' are fundamental, but
since some default behavior of derived traps requires them, it's a
different story if they become derived.

Let's assume for the rest of this e-mail that they become derived.
The current defaut 'enumerate' trap uses both 'getPropertyNames' and
'getPropertyDescriptor'. We have (at least) two choices: keep the
current definition that uses them or doing one which only uses
'getOwnPropertyNames' and 'getOwnPropertyDescriptor'.
If someone decides to explicitly implement only the 5 fundamental +
'getPropertyNames' and 'getPropertyDescriptor', then depending on the
enumerate definition we choose, the result will be different if the
handler's get(Own)Property(Descriptor|Names) definitions aren't
consistent with the "climbing prototype chain" idea.

I am just raising the question now, I do not have strong convictions on
what should be the rational behind default dehaviors. I would suggest to
only use fundamental traps (even though it may result in longer code).
This way we /could/ provide some garantees like prototype chain climbing
and delegation to fundamental trap of prototypes if they are proxies
themselves. If people aren't satisfied with this garantee, they can
redefine the method anyway.
But I kind of like the idea that if my prototype chain is filled with
proxies, method (like enumerate) which are supposed to climb the proto
chain do it for me even though I have redefined methods which are
usually supposed to climb it such as getPropertyDescriptor.

Another concern on derived trapped definition is other traps returned
values. I however notice that this point is written in the open issue of
dealing with inconsistent data returned by handler traps, so i won't go



Le 24/01/2011 22:41, Tom Van Cutsem a écrit :
> David,
> Your intuition of what constitutes a fundamental vs. a derived trap is
> correct. Strictly speaking, the Proxy API could do with just the
> fundamental traps. The motivation for providing the optional derived
> traps was that overriding derived traps often allows proxy
> implementors to implement the operation more efficiently (usually with
> less object allocations).
> As for your suggestion of turning 'getPropertyNames' and
> 'getPropertyDescriptor' into derived traps: I think you're correct. We
> could specify getPropertyNames and getPropertyDescriptor in terms of
> their "own" siblings + a prototype-chain-walk.
> I recall a discussion with Mark where this issue was briefly discussed
> before. At that time, I was concerned by the fact that you could
> equally well define getOwnPropertyDescriptor as the derived trap, in
> terms of getPropertyDescriptor + getOwnPropertyNames, as follows:
> getOwnPropertyDescriptor: function(name) {
>  var desc = this.getPropertyDescriptor(name);
>  var ownnames = this.getOwnPropertyNames();
>  if (ownnames.indexOf(name) !== -1)
>    return desc;
>  else
>    return undefined;
> }
> But applying the principle of minimizing the amount of allocations in
> default trap implementations, your definition is strictly the better one.
> I'm in favor of any change that can minimize the amount of fundamental
> traps, so I'm in favor of adopting your change. Maybe Mark still
> recalls reasons for why these traps were categorized as fundamental
> traps in the first place.
> Cheers,
> Tom
> 2011/1/23 Brendan Eich <brendan at mozilla.com <mailto:brendan at mozilla.com>>
>     I think David has a point. The fundamental vs. derived distinction
>     is, as I understand it, what Mark wrote recently, and David's
>     application of it is sound (we do that prototype-walk with
>     shadowing "duplicate removal" when starting a for-in loop in
>     SpiderMonkey). Tom should weigh in.
>     But proxies have a proto chain for instanceof and good old
>     prototype-based delegation purposes, even though their traps could
>     ignore the proto parameter. The instanceof operator will not, and
>     note how there is no getPrototypeOf trap, either.
>     This is a feature. I asked early on in the development of proxies
>     whether the alternative, of putting the proto-chain walk "on the
>     outside" of the proxy's handler traps was considered, and Mark
>     pointed out the obvious: that doing so is strictly less flexible
>     for cases where a proxy wants to do something different.
>     But this greater-flexibility design decision does not mean the
>     universal, object -invariant (ignoring mutable __proto__)
>     instanceof and getPrototypeOf (and ES3's isPrototypeOf) relations
>     should be outside of a proxy's control. The Proxy.create proto
>     parameter is the way to control those relations, for the life of a
>     given proxy, and modulo property lookup trap freedom to do other
>     things than just delegate up the proto chain.
>     /be
>     On Jan 23, 2011, at 8:43 AM, François REMY wrote:
>>     Moreover, should a Proxy really have a prototype ?
>>     I mean, what’s the point about having a prototype, since the
>>     “get” method can return everything you would like for any property ?
>>     I think getProtototypeOf should be defined as a new trap. And its
>>     default behaviour should be to return null (or Object.prototype,
>>     but I think null is the intented behavior of a proxy).
>>     On the other hand, overriding getPropertyNames should not be
>>     allowed. getPropertyNames should *always* return the
>>     concatenation of the properties returned by getOwnPropertyNames()
>>     and by getPrototypeOf(this).getPropertyNames(). It makes no sense
>>     otherwhise.
>>     I understand that we may want to redefine the way an ECMAScript
>>     Object can handle the native commands, but I’m strongly against
>>     anything that can conduce to illogical results (if there’s not an
>>     use case that justify it, naturally). The definition of
>>     getPropertyNames is clear and being able to redefine it locally
>>     seems me wrong. A proxy can modify is own behavior, not the
>>     behavior of the ES engine. Being able to have getPropertyNames
>>     and getOwnPropertyNames returning incompatible results is
>>     somewhat hurting me. Is there any reason we should allow that ?
>>     Any use case ?
>>     I’m issuing the same concerns for the “has” trap. It think it
>>     should not be a trap. It should always return hasOwn(key) ||
>>     prototype.has(key). Each one of hasOwn and prototype can be tuned
>>     by the proxy, but not the “has” itself. We’re not removing
>>     features, but we prevent bad usage of it. Whatever the user code
>>     do, the ‘has’ behavior will stay logical.
>>     Another thing I don’t quite understand is the difference between
>>     “keys” and “enumerate”. If there’s no strong difference, it
>>     should be the same trap (same logic: enumerate should return the
>>     concatenation of this.keys and this.prototype.keys). Having two
>>     different but similar traps will cause confusion. Maybe there’s a
>>     need for this difference however. I just didn’t understand why
>>     such a difference should exist, but at least I see more possible
>>     usages than the first three traps I “contested”.
>>     Anyway, if we should retain only one thing from the discussions
>>     we already have seen on the Proxy hub, is that it’s a great
>>     feature, but one that still needs some work before implementation ;-)
>>     Regards,
>>     François
>>     *From:* David Bruant <mailto:bruant at enseirb-matmeca.fr>
>>     *Sent:* Sunday, January 23, 2011 4:24 PM
>>     *To:* es-discuss <mailto:es-discuss at mozilla.org>
>>     *Cc:* Mark S. Miller <mailto:erights at google.com>
>>     *Subject:* [ES Harmony Proxies] Fundamental trap definition
>>     Hi,
>>     I am wondering if getPropertyDescriptor and getPropertyNames
>>     fundamental traps shouldn't rather be derived traps since they
>>     could have a pretty straightforward default implementation.
>>     One implementation of getPropertyNames could be :
>>     --------------------------
>>     Object.getPropertyNames = function(o){
>>         var objectToInspect;
>>         var result = [];
>>         for(objectToInspect = o;
>>             objectToInspect !== null;
>>             objectToInspect = Object.getPrototypeOf(objectToInspect))
>>         {
>>                 result =
>>     result.concat(Object.getOwnPropertyNames(objectToInspect));
>>         }
>>         return result.removeDuplicates(); // the removeDuplicates
>>     method is made up, but you get the point
>>     }
>>     --------------------------
>>     This seem to fit the proposal
>>     (http://wiki.ecmascript.org/doku.php?id=harmony:extended_object_api&s=getpropertydescriptor
>>     <http://wiki.ecmascript.org/doku.php?id=harmony:extended_object_api&s=getpropertydescriptor>)
>>     expectations). This could be also the default getPropertyNames
>>     trap implementation.
>>     I haven't really seen a strong definition of what fundamental
>>     traps are in the proposal. On Mark Miller's e-mail
>>     (https://mail.mozilla.org/pipermail/es-discuss/2011-January/012601.html)
>>     is written:
>>     [a trap is fundamental if] there is no coherent default behavior
>>     to fall back to that would be defined in terms of the remaining
>>     traps. (please tell me if I misinterpret what you meant)
>>     If we're going with this definition, then getPropertyDescriptor
>>     and getPropertyNames should probably be derived traps since they
>>     can clearly be defined thanks to other traps (respectively
>>     getOwnPropertyDescriptorand getOwnPropertyNamesas I showed above)
>>     which seems to be coherent fallback behavior.
>>     Instead of a formal definition, this could be a rational for
>>     deciding what is a fundamental trap and what isn't.
>>     In the 5 remaining traps (getOwnPropertyDescriptor,
>>     getOwnPropertyNames, defineProperty, delete, fix), I don't see
>>     any that could be defined thanks to the others. They seem to be
>>     also the fundamental actions that one can perform on a single object:
>>     Property-wise:
>>     - create/configure a property (defineProperty)
>>     - delete a property (delete)
>>     - retrieve a property (getOwnPropertyDescriptor. Can be used to
>>     separate the create and configure cases of defineProperty)
>>     Property-set-wise:
>>     - retrieve the property set (getOwnPropertyNames. More can be
>>     found later on each property with getOwnPropertyDescriptor)
>>     - prevent further extension (and optional reconfigurations for
>>     seal and freeze)(fix)
>>     The prototype can be retrieved thanks to Object.getPrototypeOf
>>     (which cannot be trapped for consistency purposes) and all
>>     actions can be performed by climbing the prototype chain.
>>     Any thoughts on the fundamental trap definition?
>>     Or on the idea of turning getPropertyDescriptor and
>>     getPropertyNames into derived traps with the suggested definition?
>>     David
>>     ------------------------------------------------------------------------
>>     _______________________________________________
>>     es-discuss mailing list
>>     es-discuss at mozilla.org <mailto:es-discuss at mozilla.org>
>>     https://mail.mozilla.org/listinfo/es-discuss
>>     _______________________________________________
>>     es-discuss mailing list
>>     es-discuss at mozilla.org <mailto:es-discuss at mozilla.org>
>>     https://mail.mozilla.org/listinfo/es-discuss
>     _______________________________________________
>     es-discuss mailing list
>     es-discuss at mozilla.org <mailto:es-discuss at mozilla.org>
>     https://mail.mozilla.org/listinfo/es-discuss

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

More information about the es-discuss mailing list