instanceof trap - Useful to implement promises through proxies
Could you clarify why trapping instanceof is required for promises? It seems
your use case can be addressed already using the current Proxy API: if FP
is a function proxy, then obj instanceof FP
will query FP
for its
prototype
property (as per the default algorithm) by calling the function
proxy's get
trap. Inside that get
trap, you could check whether the
prototype is unresolved or "far" and if so, throw an exception.
Cheers, Tom
2010/11/18 Sebastian Markbåge <sebastian at calyptus.eu>
The idea here is that it's "obj" that's the proxy/promise.
For example:
var pet = future();
var closure = function(){ return pet instanceof Cat; };
resolve(pet); // later
closure(); //?
I should've clarified that it's the [Prototype] of pet that needs to be delayed. Not prototype of Cat. It may be resolved to any number of different prototype chains depending on how the future/promise is resolved.
Sebastian
Ok, I see. So it's true that the current Proxy API doesn't support promises
that would throw on instanceof when unresolved and return a boolean when
resolved. The main reason is that we didn't want proxies to meddle with the
inheritance chain, in particular giving proxies the ability to implement
dynamic inheritance. While intercepting instanceof doesn't truly introduce
dynamic inheritance in the language, you could definitely create proxies
that are instanceof
prototypes from unrelated hierarchies, which could
spell trouble.
If the prototype or constructor function of the to-be-calculated value of a
promise is known to the promise creator, it is possible to make instanceof
work somewhat sensibly for promises:
var pet = promiseFor(Cat); // promise implementor can now write: Proxy.create(Cat.prototype, ...) ... // assume pet is still unresolved: pet instanceof Cat // true since the promise proxy already has the correct prototype
I said "somewhat sensibly" since this may or may not be the behavior you'd want for unresolved promises.
Note that even the proposed "instanceof trap" would not help if the
constructor function (Cat in the above example) is not in bed with the
promise abstraction, since obj instanceof F
would trap on F's handler, not
on obj's handler. If F is a promise-aware function proxy, it could then
check whether obj is an unresolved promise and throw. But it would require
user code to write at least:
Cat = PromiseAwareWrapperFor(function () { ... }); // declare that my instances can be promises
Cheers, Tom
2010/11/19 Sebastian Markbåge <sebastian at calyptus.eu>
I thought I'd make the case for the "instanceof trap" in strawman:proxy_extensions - beyond multiple inheritance. I'm sure this point has been made before at some point.
This is useful to implement various forms of promises using proxies. The prototype can be resolved at a later time perhaps after some IO or lazy operation. This should be able to fail if the promise is currently unresolved or "far".
It's the final piece missing to preserve "the invariants that keep the JS lucid dream".
I'm also curious to hear any objections to this proposal. I don't see the same issues as with mutable prototypes being applicable to proxies.
Sebastian Markbåge