On Jan 20, 2013, at 2:27 PM, Brendan Eich wrote:

> Skipping contentious stuff (some of which, e.g. "classes as sugar", I agree 
> with -- and so does TC39) to get to this paragraph:
> 
> Allen Wirfs-Brock wrote:
>> The [[Get]] and [[Set]]  (and probably some others) internal methods of a 
>> proxy never call the corresponding trap when the property key is a private 
>> Symbol.  Instead, they trace the [[Target]] chain of the proxy until a 
>> non-proxy object is reached (call this the "ultimate target").  It then 
>> invokes the ultimate target's [[Gett]]/[[Set]] using that same private 
>> Symbol key.  The result of that operation is then returned as the value of 
>> the original [[Get]]/[[Set]].
>> 
>> The "private" state access is applied to the correct object and there is no 
>> exposure of the private symbol!
> 
> If I want to proxy for a date instance I might rather have @@DateValue 
> available and passed as a name to get and set traps, so I can keep my own 
> time number, and not have to delegate to a Date prototype that has the right 
> milliseconds since the Epoch.

For the above I'm thinking of situations where an external party (a membrane?) 
is wrapping an object that wasn't specifically designed to be proxied.  That 
presumably is the use case that people are primarily concerned about in the 
recent discussions.   As far as I can tell, without special accommodations for 
all the built-ins' internal state they just don't work if proxied  in that 
manner because the "wrong" this value is passed to all of the methods. Same as 
for previous proposal for censoring private symbols. 

I actually don't see why you would ever need to use a Proxy to implement a ES 
compatible data abstraction.  There is nothing about that abstractions (unlike 
Array, for example) that requires changing the MOP level behavior manifested by 
its instances.

Mostly what we are dealing with, WRT Date, is balancing legacy compatibility 
issues with subclassability issues.  The legacy spec for all the Date prototype 
methods says they throw if they are applied to a this value that does not have 
the internal state of a Date instance.  Among other things, this allows 
implementations to use custom c structs for Date instances and implement access 
to the timeValue as a impl level brand check followed by a direct slot access.  
The ES6 specification of these methods is intentionally vague (the timeValue is 
in the [[DaveValue]] "internal data property" (which could be implemented using 
a private Symbol keyed property) rather than explicitly specified as a private 
Symbol keyed property.  This (along with the @@create method) allows subclass 
to have the same private state layout as the superclass and allows it to be 
recognized by the methods.

Because of this design, the Date prototype methods are only usable on objects 
that are allocated using Date.@@create (subclasses achieve this via class-side 
inheritance).  It would arguably be a better OO design to have all those 
methods access the timeValue via a specified @@DateValue method call.  Then 
they could be install on any object that supplies (possibly via inheritance) 
such a method.  But that design seems to make it harder to use an optimization 
object struct and possibly to perfectly duplicate the legacy failure behavior.

> 
> Perhaps you're in favor of that in addition? But if so, how would one proxy 
> such that the @@DateValue symbol was the name parameter to get and set traps?

I'm not sure if you are getting at something other than what I've described 
above.  If a @@DateValue private symbol is actually used as the implementation 
of [[DateValue]] then actuality that would happen. 

Were you thinking about something different?

Allen



_______________________________________________
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss

Reply via email to