David Bruant (2013-07-30T19:40:30.000Z)
Le 30/07/2013 18:57, Allen Wirfs-Brock a écrit :
> So far in ES<=6 dealing with such private data slots is something that 
> could be treated in a relatively ad hoc manner within the ES spec. and 
> by implementations.  But in ES7 we really want and need user definable 
> per instance private data. The issues we are encountering here are a 
> precursor of the issue we will see down the line and what we do now 
> may constrain what we can do later.
I could not agree more. Should proxies be deferred waiting for private 
data, then?
Or, maybe they can be put in quarantaine in some way. For instance, 
making the constructor throw if the target isn't a regular object. 
That's for the time being until the "private state" (whether "private 
internal slots" or user data) is sorted out. A max-min sort of proxy, I 
guess.

>
> ...
>>
>>
>>     For a broader discussion of the use of [[Class]] in ES5 see
>>     https://docs.google.com/document/d/1sSUtri6joyOOh23nVDfMbs1wDS7iDMDUFVVeHeRdSIw/edit?hl=en&authkey=CI-FopgC&pli=1
>>
>>
>> Cases are annoyingly numerous, but finite. A test suite can go a long 
>> way. I heard the test suite is moving to Github :-) Only missing is 
>> an extensive doc of the test framework.
>
> Tests are normative and you can't write a valid test suite in the 
> absence of an accurate specification.
I was answering to your concern about built-in implementations and 
memory safety hazard. If a test suite contains a good share of tests to 
exercise how built-ins react when passed proxies as arguments (including 
'this'), this would provide some level of confidence that the 
implementations aren't too memory unsafe.
What the tests exactly returns will of course have to be determine by an 
accurate spec, no doubt here.
I was thinking of tests as a coverage method here, not as a conformance 
tool.


>>>     So self-hosted code can distinguish an actual array from a
>>>     proxy, that's not an issue.
>>>     Non-privileged code being able to distinguish an array and a
>>>     proxy for an array is more worrisome.
>>
>>     I go the other way, in general there should be nothing special
>>     about  "self-hosting code".  Perhaps the phrase is even
>>     misleading. What I'm really saying that there should be no
>>     particular reason that anything other than the most primitive
>>     elements of the the ES built-ins can't be expressed in ES code.
>>
>>     A proxy with an Array as its target is not an Array.  Whether
>>     such an object is substitutable for an Array instance is high
>>     dependent on the details of its handler and other aspects of its
>>     implementation.   Also please see
>>     http://wiki.ecmascript.org/doku.php?id=harmony:virtual_object_api which
>>     address related issues.
>>
>> This is not enough.
>> this-binding ("proxy.getMonth()" when the target is a Date) is only 
>> half of the story. The other half remains unadressed 
>> ("Date.prototype.getMonth.call(proxy)"). Exotic objects aren't always 
>> used as "this" value. This is exactly Tom's feedback actually.
>> We need the same solution for both cases (this and non-this usage of 
>> methods).
>
> I also raised this objection and it is what led to the recent update 
> to the virtual object API referenced above.  What that change does is 
> make it easier for ES programmer to create proxies that behave in this 
> manner.
>
> But, in the end we could not come up with a solution for the 
> Date.prototype.getMonth.call(proxy) issue.  The [[Invoke]] MOP 
> operation/trap was added to minimize the actual occurrence of this 
> scenario.  You can't use 'call' to force a built-in to operate upon 
> the wrong kind of object.
The introduction of [[invoke]] in this particular context might be an 
instance of "may constrain what we can do later". Specifically, it may 
collide and feel duplicate if a more generic solution is found for 
Date.prototype.getMonth.call(proxy); a more "useful" example of which is 
Set.call(proxy).


>
>>
>>>>>     The (granted implicit) model of "a proxy for exotic object X
>>>>>     is seen by all algorithms as an exotic object X" feels simpler
>>>>>     even if it means that a proxy might not act as an internal
>>>>>     algorithm expects.
>>>>     memory safety hazard.  Every place that checks for "is O an
>>>>     exotic X object" would have to have a subsequent "is O a Proxy
>>>>     whose target is an exotic X" and take different code paths.  If
>>>>     you screw it up, you may have memory safety issues.
>>>     That's an implementation hazard; not sure what your point is here.
>>
>>     The major of such test in the spec. are abstracting over such
>>     implementation hazards.  That's why they are there.
>>
>> Let's let implementors deal with implementation issues. Let's just 
>> make sure the spec isn't impossible or too high barrier to implement. 
>> A test suite will do the rest. Let's care only for tests that make 
>> sense when authoring.
>> Implementors are free to dive in here to say I'm wrong and why.
>
> ES spec. largely exists to constrain how implementors deal with such 
> issue in order to guarantee that different implementations have 
> observably identical behavior.
How did the discussion shift from "memory safety issue" to "observably 
identical behavior"?
In any case, I agree with you.

> I think you are glossing over real issues that require real design 
> thinking and which probably can't be addressed until ES7.
I think I understand the real issues :-) I don't have a idea to solve 
them and even less an idea TC39 would agree on, but I understand them.
I feel that the [[invoke]] proposal is an attempt to get the maximum out 
of proxies without addressing them and I wonder whether it would be 
better to wait.

> I complete disagree WRT tests. Tests written without reference to some 
> normative specification are just a reflection of how their developer 
> thinks the system should work.
Again, I thought of tests as a coverage tool more than a conformance one 
(though obviously, testing conformance along the way is obviously a nice 
property, but has to wait for an actual spec)


>
>> ...
>>
>>>     Something has to be given up. And giving up on
>>>     indistinguishability would defeat the purpose of proxies (and
>>>     the expectation as feedback on Tom's library suggests).
>>
>>     You suggestion is?  My point is ES internal branding, whether you
>>     call it "check for exotic XXX object", "check for the[[XXX]]
>>     internal data property" or check if [[Class]] == "Array" h does
>>     not work with the Direct Proxy default handler semantics.
>>
>> Is there a handler semantics with which it can fully work? That's all 
>> is needed.
>
> The ForwardingHandler semantics is close to what you want.
The part I'm being insistent on is the delta between what this handler 
enables and what it does not.
The use of 'this' has been special-cased. I understand the biais that 
leads to this decision, but I don't think it's a good rationale.
I think it's an equivalent biais than the one of the original Proxy 
design where the [[prototype]] was passed to the proxy.create function 
as if the [[Prototype]] internal property was that special in the MOP.
'this' is the 0th argument of functions (and .call shifts the order 
making this statement false in absolute terms), there is no good reason 
to give it a special treatment.

> But it still doesn't work the way you would like for direct "call" 
> invocation or for things like Array.isArray.  The base issue for 
> either of these is that they don't indirect through the proxy handler 
> and hence the handler doesn't have an opportunity to replace the proxy 
> reference with the target reference.
Wouldn't replacing the proxy reference for the target reference be 
violating stratification?
Per exotic type traps would solve the issue generically, I think.


> Do you have new use cases, that motivate the design of an enhanced 
> Array.isArray?
I cited membrane transparency a couple of times. Tom seems to agree. 
Others have opinions?

>
> It would be quite easy to extend Array.isArray(obj) so that it 
> delegated back to obj with a @@areYouAnArray method such as we are 
> doing with @@isRegExp in certain places.  However, if we do that you 
> loose support for the original Array.isArray use case because any 
> object could decide to return true from Array.isArray.
> ...
If, for instance, you have an "areYouAnArray" trap that only works if 
the target is an Array (recursive definition with actual arrays as base 
case), then Array.isArray isn't spoofable by any object.
Mark and Tom once used a expression about direct proxies. Something like 
"invariant forwarding" or something like that, where the target imposes 
restrictions on the handler. This could be extended to exotic objects by 
adding per exotic type only traps.

>
>> This thread feedback brings new data and it seems that the current 
>> handler offering isn't enough (and I understand can't be).
>
> yup
Glad we agree here :-p

David
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20130730/ad83251b/attachment-0001.html>
domenic at domenicdenicola.com (2013-08-04T22:54:11.193Z)
Le 30/07/2013 18:57, Allen Wirfs-Brock a écrit :
> So far in ES<=6 dealing with such private data slots is something that 
> could be treated in a relatively ad hoc manner within the ES spec. and 
> by implementations.  But in ES7 we really want and need user definable 
> per instance private data. The issues we are encountering here are a 
> precursor of the issue we will see down the line and what we do now 
> may constrain what we can do later.

I could not agree more. Should proxies be deferred waiting for private 
data, then?
Or, maybe they can be put in quarantaine in some way. For instance, 
making the constructor throw if the target isn't a regular object. 
That's for the time being until the "private state" (whether "private 
internal slots" or user data) is sorted out. A max-min sort of proxy, I 
guess.

> Tests are normative and you can't write a valid test suite in the 
> absence of an accurate specification.

I was answering to your concern about built-in implementations and 
memory safety hazard. If a test suite contains a good share of tests to 
exercise how built-ins react when passed proxies as arguments (including 
'this'), this would provide some level of confidence that the 
implementations aren't too memory unsafe.
What the tests exactly returns will of course have to be determine by an 
accurate spec, no doubt here.
I was thinking of tests as a coverage method here, not as a conformance 
tool.


> I also raised this objection and it is what led to the recent update 
> to the virtual object API referenced above.  What that change does is 
> make it easier for ES programmer to create proxies that behave in this 
> manner.
>
> But, in the end we could not come up with a solution for the 
> Date.prototype.getMonth.call(proxy) issue.  The [[Invoke]] MOP 
> operation/trap was added to minimize the actual occurrence of this 
> scenario.  You can't use 'call' to force a built-in to operate upon 
> the wrong kind of object.

The introduction of [[invoke]] in this particular context might be an 
instance of "may constrain what we can do later". Specifically, it may 
collide and feel duplicate if a more generic solution is found for 
Date.prototype.getMonth.call(proxy); a more "useful" example of which is 
Set.call(proxy).


> ES spec. largely exists to constrain how implementors deal with such 
> issue in order to guarantee that different implementations have 
> observably identical behavior.

How did the discussion shift from "memory safety issue" to "observably 
identical behavior"?
In any case, I agree with you.

> I think you are glossing over real issues that require real design 
> thinking and which probably can't be addressed until ES7.

I think I understand the real issues :-) I don't have a idea to solve 
them and even less an idea TC39 would agree on, but I understand them.
I feel that the [[invoke]] proposal is an attempt to get the maximum out 
of proxies without addressing them and I wonder whether it would be 
better to wait.

> I complete disagree WRT tests. Tests written without reference to some 
> normative specification are just a reflection of how their developer 
> thinks the system should work.

Again, I thought of tests as a coverage tool more than a conformance one 
(though obviously, testing conformance along the way is obviously a nice 
property, but has to wait for an actual spec)

> The ForwardingHandler semantics is close to what you want.

The part I'm being insistent on is the delta between what this handler 
enables and what it does not.
The use of 'this' has been special-cased. I understand the biais that 
leads to this decision, but I don't think it's a good rationale.
I think it's an equivalent biais than the one of the original Proxy 
design where the [[prototype]] was passed to the proxy.create function 
as if the [[Prototype]] internal property was that special in the MOP.
'this' is the 0th argument of functions (and .call shifts the order 
making this statement false in absolute terms), there is no good reason 
to give it a special treatment.

> But it still doesn't work the way you would like for direct "call" 
> invocation or for things like Array.isArray.  The base issue for 
> either of these is that they don't indirect through the proxy handler 
> and hence the handler doesn't have an opportunity to replace the proxy 
> reference with the target reference.

Wouldn't replacing the proxy reference for the target reference be 
violating stratification?
Per exotic type traps would solve the issue generically, I think.


> Do you have new use cases, that motivate the design of an enhanced 
> Array.isArray?

I cited membrane transparency a couple of times. Tom seems to agree. 
Others have opinions?

> It would be quite easy to extend Array.isArray(obj) so that it 
> delegated back to obj with a @@areYouAnArray method such as we are 
> doing with @@isRegExp in certain places.  However, if we do that you 
> loose support for the original Array.isArray use case because any 
> object could decide to return true from Array.isArray.
> ...

If, for instance, you have an "areYouAnArray" trap that only works if 
the target is an Array (recursive definition with actual arrays as base 
case), then Array.isArray isn't spoofable by any object.
Mark and Tom once used a expression about direct proxies. Something like 
"invariant forwarding" or something like that, where the target imposes 
restrictions on the handler. This could be extended to exotic objects by 
adding per exotic type only traps.

>> This thread feedback brings new data and it seems that the current 
>> handler offering isn't enough (and I understand can't be).
>
> yup

Glad we agree here :-p