[[Invoke]] and implicit method calls
allen at wirfs-brock.com
Tue Sep 10 11:35:41 PDT 2013
On Sep 10, 2013, at 10:45 AM, Jason Orendorff wrote:
> On Tue, Sep 10, 2013 at 11:11 AM, Allen Wirfs-Brock
> <allen at wirfs-brock.com> wrote:
>> Having to create a new bound function on every method call seems too expensive.
> Only for proxy method calls, and it's easily optimized away in the
> default case (i.e. there is no .getMethod handler method).
> (As an aside, exchanges like the above have gotten so frequent they
> are beginning to feel a bit pro forma. I don't mean to sweep all
> performance concerns into one pile here.)
>> But what about:
>> 6. Let method = O.[[Get]](P).
>> 7. ReturnIfAbrupt(method).
>> 8. If IsCallable(method) is false, throw a TypeError.
>> 9. Return O.[[InvokeFunction]](method,O, args).
>> Using [[InvokeFunction]] the Proxy still mediates the [[Call]] to method but it is assume the [[Get]] step has already been performed and has produced method.
> This is appealing. There are a few things [[GetMethod]] can do that
> this can't: [[InvokeFunction]] can't be used to make a proxy that
> mimics the behavior of __noSuchMethod__, for example. I don't think it
> can mimic ActionScript 3 Proxy.callMethod either.
Well, we didn't have those capabilities before we added [[Invoke]] and neither were primary use cases that motivated [[Invoke]].
> If [[InvokeFunction]] is deemed powerful enough, I'm all for it.
I was thinking we might only need to have [[InvokeFunction]] but if we had both it and [[Invoke]] then then we'd only have we'd only those those capability in situations that required a conditional invoke. However, that would still create an anomalous edge case, for example toJSON not triggering a __noSuchMethod__ emulator. Should it?
I'm beginning to like a conditional option on [[Invoke]].
Consider: [[Invoke]](P, ArgumentsList, Receiver, conditional=false)
If conditional is false, it works just like the current [[Invoke]] spec.
If conditional is true and the [[Get]] value is not callable (this includes undefined for a missing property) result is: [false, [[Get]] result].
if conditional is true and the [[Get]] value is callable, result is [true, value returned from [[Call]]
The conditional form would only be used in odd cases like the toJSON call.
ES code can accomplish the same thing via Reflect.invoke with true as the 4th argument.
More information about the es-discuss