instanceof trap - Useful to implement promises through proxies

# Sebastian Markbåge (15 years ago)

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

# Tom Van Cutsem (15 years ago)

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>

# Sebastian Markbåge (15 years ago)

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

# Tom Van Cutsem (15 years ago)

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>