[[Invoke]] and implicit method calls

Tom Van Cutsem tomvc.be at gmail.com
Thu Sep 12 05:32:11 PDT 2013

2013/9/11 Allen Wirfs-Brock <allen at wirfs-brock.com>

> I'm not sold.  Two internal methods means there must be two proxy traps
> that must always be implemented as a pair.  It would simply be wrong for a
> handler to implement the invoke trap and not also implement  the
> invokeConditional trap.  And inheriting from DelegatingHandler or
> ForwardHandler doesn't help because if either invoke or invokeConditional
> is over-ridden then then other also needs to be over-ridden.

The Proxy API is rife with such dependencies among traps. In fact, the
dependency already exists between "get" and "invoke".

That is why you and I came up with <

Assuming we have both "invoke" and "invokeConditional" traps, I would
assume "invokeConditional" to be implemented in terms of "get", e.g.
DelegatingHandler would implement it as:

invokeConditional: function(target, name, args, receiver = target) {
  var fun = this.get(target, name, receiver);
  if (!isCallablable(fun)) {
    return undefined; // or a distinguishing sentinel value
  return Reflect.apply(fun, receiver, args);

A handler extending DelegatingHandler would inherit appropriate versions of
"get", "invoke" and "invokeConditional" that will all be mutually

> [[InvokeFunction]] requires use of [[Get]] to access a method so it
> reintroduces the possibility that a handler might have to cons up a
> function. I suspect this is rare which is the conclusion we came to when
> [[Invoke]] was originally considered long ago.

It wouldn't be rare for virtual object abstractions: these can't return a
pre-existing method on their target object from their "get" trap, hence
will need to cons up a function.

> 3) For proxy trap invocations I maintain we are still better off with
> [[Get]] + [[Call]] to keep double-lifting as simple as possible.
> Sorry if I missed it: what complicates things if we use [[Invoke]] to
> support double-lifting?
> however proxy trap invocation should really be [[Invoke]] for semantics
> consistency.  It really is a method invocation and the meta-meta-level
> handler should be given the opportunity to apply any method invocation
> policy it may have. Either a conditional [[Invoke]] or
> [[Get]]+[[InvokeFunction]] would supply adequate semantics.

For double-lifting, the meta-handler is a virtual object that wants to
ignore its target. It doesn't want to re-bind the |this|-value.
Here's a gist containing the pattern: <

> Either some form of conditional [[Invoke]] or a [[InvokeFunction]] trap
> would still support double-lifting via a single trap.  In the case of
> conditional [[Invoke]], it is that trap that would be implemented at the
> the meta-meta-level. With [[InvokeFunction]] it is the [[Get]] trap that
> would be implemented.

Yes, conditional [[Invoke]] would also be sufficient (and would get rid of
the function allocation per intercepted operation).

If we'd have [[InvokeFunction]], the metaHandler still needs to implement
"get" and "invokeFunction". If it wouldn't override "invokeFunction", the
default would be wrong (assuming the default is, as for all missing traps,
to forward to the target).

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

More information about the es-discuss mailing list