[[Invoke]] and implicit method calls

Brendan Eich brendan at mozilla.com
Mon Sep 23 15:50:42 PDT 2013

> Allen Wirfs-Brock <mailto:allen at wirfs-brock.com>
> September 23, 2013 3:06 PM
> It's a matter of internal vs external consistency. The implementor of 
> a Proxy handler needs to internally consistently implement the 'get', 
> 'set', 'has', 'invoke', etc. traps in order to manifest an object that 
> exhibits the normally expected object semantics. But there is no fool 
> proof (I contend) way for the proxy implementor to achieve 'invoke' 
> consistency with 'get+F.p.call

Now it depends on what you mean by "fool proof".
> JS programmer have been trained that:
> obj.m(args)
> is equivalent to:
> let f = obj.m;
> f.call(obj, args)
> Sometimes they place additional code between the property access and 
> the call. That code might make the call conditional. It might memorize 
> f and obj in order to defer the call to an arbitrary point in the future.
> Prior to proxies this was always valid because the semantics of both, 
> at the MOP level were: f = obj.[[Get]]("m"); f.[[Call]](obj,args). But 
> with proxies and [[Invoke]], this equivalent is no longer the case.

Vacuously true, and why we resisted invoke.

> And with the current definition of F.p.call/apply there is nothing 
> that the client code can do to reestablish the consistency.

To use either F.p.call or .apply, you must do obj.[[Get]]("m"). For 
function objects, [[Call]] is well-specified and what F.p.{c,a} use.

For proxies, we need something akin to [[Call]]. Is that the point of 

> This can be fixed, if obj.m(args) has the semantics of 
> [[Get]]+[[InvokeFunction]] and F.p.call/apply also uses 
> [[InvokeFunction]] (noting that is the vast majority of cases 
> [[InvokeFunction]] is exactly the same as [[Call]].

Ok, but then Tom asked whether function objects targeted by direct 
proxies having their [[Call]] overridden was a problem?

> The JS programmers expected equivalence is maintained yet transparent 
> proxies still have an opportunity to do forward of this values.
> BTW, it also restore left to right evaluation of the call operator 
> which regressed when the call operator was implemented using [[Invoke]].

If you can rename [[InvokeFunction]] to [[Invoke]] so my head stops 
exploding, I think we have a deal. But need Tom on board.


More information about the es-discuss mailing list