[Harmony proxies] Opinion on the open issue (How to deal with inconsistent data returned by handler traps?)

David Bruant bruant at enseirb-matmeca.fr
Fri Mar 18 04:57:49 PDT 2011


Le 16/03/2011 10:25, Tom Van Cutsem a écrit :
> David,
>
> This open issue is indeed one that merits further discussion here.
>
> Some thoughts and comments:
> * I think we did come to an agreement that custom property attributes
> were seen as very useful for communicating new kinds of meta-data
> about objects, and that they ought to be preserved. See also this bug:
> <https://bugzilla.mozilla.org/show_bug.cgi?id=601379>
> That would solve one of the issues you raise.
Ok. I'll follow on the bug.
However, from what I understand, it (and the current
Object.defineProperty semantics) does not fully let the user to define
his/her attributes names and semantics.
In the proxy semantics strawman, Object.defineProperty step 3:
"Let desc be the result of calling ToPropertyDescriptor with Attributes
as the argument."
The /ToPropertyDescriptor/ call normalizes 'configurable', 'enumerable',
'writable' to booleans and throw if 'get' or 'set' isn't callable. This
prevents people from passing differently typed values.

I think we need the other communication side too. [[GetOwnProperty]]
calls /ToCompletePropertyDescriptor/ which also calls
/ToPropertyDescriptor/. So if I want to use a different type for the
usual attribute names (which, in my opinion, are common names), I
cannot. Moreover, the property descriptors returned by
Object.getOwnPropertyDescriptor are forced to have an 'enumerable' and
'configurable' property (and others depending on data or accessor
descriptor). If I want to decide my own attributes&semantics and do not
care about the "forced" one, then I am paying a performance/semantics
overhead for no obvious reason. This can be annoying if I want to return
a proxy as the property descriptor or if I want to iterate over property
attributes through a for-in loop or Object.getOwnPropertyNames+Array
method (forEach, every, reduce...).
What is your position on this point? Is there also a bug number for this
one?

> * The place where argument/return value validation is most critical is
> where fundamental traps are called by the runtime itself, not by
> client code, because of a missing derived trap. The question here is:
> how should the default implementation of a derived trap deal with
> inconsistent data returned by the fundamental trap on which it relies?
The way I see it, default implementations of derived traps are just a
convenience. In my opinion, they should be the exact reflection of their
related ECMAScript object method/internal method and not do more data
validation/formatting than these do.
As a convenience, proxy programmers should be aware of limitations and
conventions in default implementation expectations. We can document
them, it won't be hard at all.
And if programmers decide to not respect the conventions in what they
return from their fundamental traps, then they are exposing themselves
to inconsistencies. Either they accept it and consider that as feature
and not bug or they can always implement derived traps if they aren't
satisfied with how the default derived trap behaves.

No matter what is decided for derived traps default implementations
(current spec, current spec + data validation/formatting, other spec),
there are going to be people for which this doesn't fit their use cases,
so they will have to re-implement them. So I would be in favor of having
default implementations which are consistent with ES objects behavior
and perform no further checks (which will also improve performance).

I would like to point out that internal data validation/massaging is
always surprising from the programming/debugging point of view. A
programmer doesn't always know the restrictions ("I returned duplicates
in the get(Own)PropertyNames trap and they've been removed! How so?", etc.)

David

> * If proxy handlers are allowed to free-wheel and return whatever they
> like, this will no doubt break some invariants of client code. I don't
> think something like Proxy.safeCreate is a particularly good idea, since:
> a) it further increases the complexity of an already complex API
> b) it puts the responsibility for ensuring safety on the wrong party:
> if safety is required, it's not a good idea to rely on library authors
> to use Proxy.safeCreate instead of Proxy.create. The library author
> can always "forget" (unintentionally or intentionally).
>
> I believe Allen raised the idea at one of the last TC39 meetings that
> a safe subset could replace Proxy.create, Object.keys, etc. with safe
> variants that check for consistency. I recall that MarkM objected on
> the grounds that this approach could be prohibitively expensive for
> some checks, such as filtering out duplicates.
>
> Cheers,
> Tom
>
> 2011/3/16 David Bruant <bruant at enseirb-matmeca.fr
> <mailto:bruant at enseirb-matmeca.fr>>
>
>     Hi,
>
>     On the proxy proposal is an open issue. It starts with "How to
>     deal with inconsistent data returned by handler traps?" (actually,
>     the issue also applies to inputs since I can provide garbage as
>     Object.defineProperty arguments). First of all, I think that there
>     might be a false assumption in the question. It would be in the
>     word "inconsistent". Inconsistent with what? From what I
>     understand, the answer would be "with our current knowledge, use
>     and understanding of objects". But should proxy be consistent with
>     this?
>
>     The first sub-question is "what to do if the return value of
>     getOwnPropertyNames or keys contains duplicate property names:
>     silently filter them out, leave them, or throw?". So I have
>     started to wonder "why would Object.getOwnPropertyNames return
>     duplicates?". So I have thought of a case where objects, for the
>     same key would have not one, but several values. Long story short,
>     with Object.defineProperty, you add a value, with get/set, you
>     play with the last value and with delete, you delete the last value.
>     I have implemented it and invite you to run
>     http://davidbruant.github.com/PropStackObjects/ on Firefox4 and
>     look at the source code
>     https://github.com/DavidBruant/PropStackObjects/blob/gh-pages/index.html
>     With this "several values per property name", one could expect to
>     see as many duplicates of the same key than the number of values
>     of this key on the object after a Object.getOwnPropertyNames.
>     I have implemented the thing, but as you will notice on
>     Firebug/WebConsole, since there is some data massaging on the
>     output of the trap, duplicate keys disappear.
>
>     My point is that it might be too restrictive to consider proxies
>     as things "that behave like objects with some differencies". The
>     ability to have functions (arbitrary code) to define a behavior
>     potentially offers library authors the potential to consider
>     objects differently than we used to. In my example, I am breaking
>     the idea that a property name is bound to at most a unique value.
>     In my example, it's a stack. And through the handler code, I am
>     offering the guarantee that get and set only act on the last value.
>     The way I see it, proxies offer the possibility of a dialog
>     between library authors and library users and for this dialog,
>     there is no need to learn a new language. This dialog happens with
>     the "Object vocabulary" (with library author-defined semantics).
>     And in my opinion, it would be a mistake to constraint this dialog
>     to what we know for current objects.
>
>     While implementing this first example, I have realized that the
>     property descriptor was somewhat inappropriate, because I didn't
>     want, for instance, a non-configurable value that could "block"
>     the stack. Actually, besides the value, nothing really mattered to
>     me. And then I thought that through property descriptor, I could
>     carry more meaning than with the current attributes. Since the
>     property descriptor is an object (and that was a genius idea!) I
>     could add an 'index' property attribute in my descriptor to
>     explicitely tell where in the stack I want the property to be
>     added to. My property descriptors would look like
>     {value:"myValue", index:3}. Hence, second experiment :
>     http://davidbruant.github.com/PropStackObjects/index2.html
>     code:
>     https://github.com/DavidBruant/PropStackObjects/blob/gh-pages/index2.html
>
>     Unfortunately, currently, on FF4, the property descriptor is
>     rewritten, but with my comments on the code, you can see what
>     results I would expect. But the potential of having my
>     library-specific property descriptor format is here.
>
>     During these experiments, imposed data massaging has been
>     frustated, because I the dialog I was trying to instore between
>     the library code and the calling code was restricted by the
>     engine. It would be the same with throwing.
>     I know that what I am proposing is a break of the usual contract
>     between what objects are and what people object to be. But I do
>     not see why I, as a library writer couldn't decide to write
>     another contract with my library users, one where I would be
>     allowed to duplicate keys in Object.getOwnPropertyNames or one
>     where I decide of the format and semantics of a property
>     descriptor and so on.
>     To answer the concern of derived traps default behavior expecting
>     some format: if I'm planning on "creating a new contract", I would
>     override them and make sure I respect the invariant and properties
>     my library users expect in all circumstances.
>
>     I think that through proxies, with "uncontrolled trapping", it is
>     likely that we see new usages and new forms of objects (Array
>     could have emerged from that:
>     https://github.com/DavidBruant/ProxyArray). Some of these new
>     forms could even be included to ECMAScript one day, why not?
>
>     If data validation was expected anyway for security or debugging
>     purposes, maybe that another type of proxy could be invented in
>     which each trap call is controlled (input and output). Maybe that
>     this could be done through Proxy.safeCreate() or something like
>     that. It would return a "safe proxy". Validation/normalizing
>     methods could also be provided by Proxy in order to help
>     implementors validate their inputs.
>
>     Of course, all said here is to be discussed, so let's discuss.
>
>     David
>
>     _______________________________________________
>     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/20110318/288a5c13/attachment.html>


More information about the es-discuss mailing list