When the only tool you have is subclassing, all extensions look like....

C. Scott Ananian ecmascript at cscott.net
Tue Jun 9 18:20:31 UTC 2015


On Tue, Jun 9, 2015 at 1:43 PM, Mark S. Miller <erights at google.com> wrote:

> On Tue, Jun 9, 2015 at 10:38 AM, C. Scott Ananian <ecmascript at cscott.net>
> wrote:
>
>> I think that Promise pipelining works just fine -- you just have to
>> implement it inside Promise#get, Promise#put, etc.
>> ```
>> // This is already in prfun
>> Promise.get = function(fieldname) { return this.then(function(o) { return
>> o[fieldname]; }); };
>> // This comes with your RPC mechanism
>> class RemoteObjectPromise extends Promise {
>>   this(args...) {
>>     let res, rej;
>>
>     if (typeof(args[0]) !== 'string') throw new TypeError("Not a remote
>> reference!");
>>
>     super((a,b)=>{res=a;rej=b;});
>>     this.handle = gensym();
>>     // first argument to rpcCall is "destination" of the operation
>>     rpcCall(this.handle, ...args).then( v => res(v), e => rej(v) );
>>   },
>>
>   get(fieldname) {
>>
>    // note that this.handle is a name for the remote object, it is not a
>> resolved value.
>>    // as such, this method doesn't have to wait until the remote object
>> corresponding to
>>    // this.handle is resolved
>>    return new RemoteObjectPromise('GET', this.handle, fieldname);
>>
>   }
>>
> }
>> ```
>>
> What about the interaction between q and r in .then, that I mentioned in
> my previous email? That's the reason I changed my mind and now think we
> need an extension mechanism besides subclassing in order to make pipelining
> work. Note: it needs to work even if p is a plain promise. It is only q
> that knows that the scenario is special.
>

Oh, right, I forgot:
```
RemoteObjectPromise[Symbol.species] = Promise;
```

That takes care of `then()`...

And provides another nice use case for species.

What would you expect `RemoteObjectPromise.all()` to do in this case?

Probably `RemoteObjectPromise.prototype.all()` makes more sense -- if you
have a remote reference to a (promised) array, you can pipeline the wait
for all the elements in the array, without having to do all the waits on
the client side.

But in this case `RemoteObjectPromise.prototype.all()` is probably
special-cased (and ignores species):
```
RemoteObjectPromise.prototype.all = function() {
  return new RemoteObjectPromise('ALL', this.handle);
};
// And this is what I claim that `Promise.all` should also be:
RemoteObjectPromise.all = function(x) { return this.resolve(x).all(); };
```

Note that, given the definition above (I've tweaked it slightly),
`RemoteObjectPromise.resolve(x)` throws TypeError if `x` is not already a
remote object reference.  You could tweak it to perform a migration or some
such if you preferred.
  --scott
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20150609/72d0808a/attachment.html>


More information about the es-discuss mailing list