Feedback on the Relationship strawman

David Bruant bruant.d at gmail.com
Thu Apr 11 03:59:40 PDT 2013


Le 11/04/2013 10:39, Tom Van Cutsem a écrit :
> 2013/4/11 David Bruant <bruant.d at gmail.com <mailto:bruant.d at gmail.com>>
>
>     In the [[GetRelationship]] algorithm, if r.[[Get]](@geti) is
>     undefined, then return x.[[Get]](r) but what is this supposed to
>     do if r is an object?
>     x[r] would coerce r to a String before passing it to [[Get]], but
>     here the object is passed directly without coercion. I feel this
>     question is answered step 5.I of interaction with proxies which
>     talks about stringification.
>     I wonder if implicit stringification is necessary. I'm afraid most
>     of the time, it'll mean "[Object object]" will be passed as key
>     and result in an unexpected behavior (collision of keys, etc.)
>
>
> Yes, but this is also the behavior we have today, right? Nothing new 
> under the sun. I even wonder whether we can change this, wouldn't it 
> be backwards-incompatible?
I'm only interested in the semantics of the new syntax, so 
backward-compat isn't a concern.
o1 at o2 coercing o2 to a string when it's an object would be consistent 
with what we have today, but I don't believe today's o1[o2] behavior is 
desirable. Maybe I'm wrong. Does anyone have examples of code making 
good use of the implicit o2.toString() for o1[o2]?

I feel that either .toString returns a constant string in which case a 
string would be more appropriate or the string used as key is generated 
dynamically in which case, this is more of a Map use case than an object 
use case.

Also, the consistency wouldn't be perfect. Currently o1[o2] coerces o2 
into a string unconditionally while o1 at o2 would if o2 is 
run-time-conditionnally lacking @geti (same for @seti).
In terms of use, we'll see what people answer to the above question, but 
in o[x], x is rarely expected to be an object, while in o at x, x is 
expected to be an object (hopefully with @geti/@seti).

>     Are there default @geti/@seti for Object.prototype?
>
>
> Not sure if this is necessary: what would these default 
> implementations do?
The same thing that private symbols would do.

> Probably just stringify their |this| value and use that as a string 
> index. That's no different from the current fallback semantics if 
> @geti/@seti are undefined.
I think I better understand the mismatch between what I understood and 
your intention.
I expected relationship and the @ syntax to substitute to private 
symbols while it seems you "only" wanted to provide the basic mechanism 
that people can build on top of.
Take the following example:
     var o = {}, r = {}, r2 = {};

     o at r = 12;
     console.log(o at r); // 12
     console.log(o at r2); // ?

With the strawman as it is and string coercion, the second console.log 
would log 12 giving the false impression that o and r2 "have a 
relationship" or "are in a relationship" (is my wording confusing? :-s). 
I don't believe this is a good default.
A sensible Object.prototype default @geti/@seti would pretty much turn 
any object inheriting from Object.prototype into a private field and 
o at r2 would be undefined (since no value has been previously added). Of 
course, that's just a default. People could re-configure or shadow, etc.
I feel it is a more useful default. It provides something very close to 
what people expect from private symbols which this strawman is aiming at 
replacing.

Regardless of the default Object.prototype implementation, I think the 
current default with null-[[Prototype]]'d objects isn't good either. The 
string coercion will lead to the exact same confusion I noted above with 
o at r/o at r2.

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


More information about the es-discuss mailing list