evaluation order and the [[Invoke]] MOP operation

Allen Wirfs-Brock allen at wirfs-brock.com
Mon Aug 19 10:44:58 PDT 2013


On Aug 19, 2013, at 9:39 AM, Brandon Benvie wrote:

> On 8/19/2013 9:33 AM, Allen Wirfs-Brock wrote:
>> thisObj.[[Invoke]](propertyKey, function, argumentList)
> 
> This could allow [[Invoke]] to trap `call` and `apply`, if propertyKey was allowed to be undefined.

I don't really want to get us off the topic WRT to the breaking change issue.  But, WRT call/apply here is a couple fragments from a private exchange between TomVC and me:


> On Jul 30, 2013, at 9:57 AM, Allen Wirfs-Brock wrote:
> 
>> 
>> On Jul 30, 2013, at 1:25 AM, David Bruant wrote:
>>> ...
>>> 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. 
>>> ...
> 
>>> 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.  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.  
> 
> I wonder if we could respecify F.p.call/apply in a manner that would make David's getMonth.call use case work (at least some of the time).
> 
> [[Invoke]](P, ArgumentsList, Receiver) is current specified such that P must be a property key.  What if we modify that so that P can be either a property key or a callable and that when a callable is passed the [[Get]] steps are skipped and P itself is used as the method.
> 
> Then call/apply could be respecified in terms of [[Invoke]] and ForwardingHandler could do the appropriate handler substitution. 
> 
> Of course, this is only an asymptotically better solution, as it only improves the handler of Proxy objects in the this position.  It wouldn't, may itself, fix Array.isArray.
> 

Tom's thought were:

> On Jul 31, 2013, at 3:58 AM, Tom Van Cutsem wrote:
> 
>> While clever, I don't think this will fly, for the reason that many programmers use the explicit `call` syntax particularly so that they can *guarantee* that the method to be invoked is the built-in that they previously stashed away somewhere.
>> 
>> If now `F.p.call` is going to delegate the decision of what code is to be executed to the thisArg, that destroys the pattern.
>> 
>> I know Mark's SES is full of preamble code where he first obtains references to the actual built-ins, then invokes those built-ins using `call` to make sure he will be executing only the original built-in code, nothing else.

These two ideas for [[Invoke]] could be combined (pass both 'f' and 'p' and have call/apply use [[Invoke]]) but it still does't address Tom's concern.

Allen
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20130819/b75921ef/attachment.html>


More information about the es-discuss mailing list