Direct proxies update

Tom Van Cutsem at
Tue Nov 29 09:40:17 PST 2011

2011/11/29 David Bruant <bruant.d at>

>  Promises sounds promising, but I'm not sure it will entirely fill the
> gap. If we're trying to write a function f which works both with local and
> remote objects, we end up with this:
> -----
> function f(o){
>     var a = o.bla;
>     // In the synchronous case, a is the value.
>     // if o is a localFarReferenceMaker, a is a promise.
>     // In order to continue for both cases, one would have to do something
> like:
>     if(isPromise(a)){
>          a.when(function(res){
>              // do something with the value in res
>          });
>     }
>     else{
>          // do the exact same thing with the value in a
>     }
> }
> -----

No, it need not be this complicated. Using the strawman Q API (<>):

function f(o) {
  var a = o.bla;
  Q(a).when(function(res) {
    // do something with the value in res

Q(x) is a no-op if x is already a promise. If x is a local value, Q(x)
turns it into a local promise for that value.
The general rule here is: if your code needs to handle both local and
remote values, deal with the remote/async case only. The local case should
be a subset of the remote case.

> <snip>
> And we get to some canonical case where I don't know how to uniformize
> "a.when(g)" and "g(a)". Maybe something with generators? Maybe a new form a
> function?

Generators can help in avoiding inversion of control. That's dealt with by
the Q.async part of the concurrency strawman <>.

> Maybe the goal of trying to have a function which works with both local
> and remote values is vain (in general or in JavaScript in particular)?

Not if one is careful to design the remote API such that it also operates
sensibly on local values.

> 2) When layering remote objects over a restful API, ideally you want
> obj[name] to perform an HTTP GET and,b,c) to perform an HTTP
> POST. Proxies cannot distinguish property access from method invocation
> (which is just get+apply), so they currently can't perform the above
> mapping.
> Hence the "bang" ("!") syntax, I guess.
> I think proxies can distinguish, but at some cost:
> "" returns a function proxy with a promise as target (no big deal
> :-p ). This sends neither GET nor POST but waits for the end of the "event
> loop turn". If the proxy function has been called send a POST (as many
> times as the function proxy has been called with respective arguments each
> time). If the event loop turn is over and the function has not been called,
> then perform a GET and the (function proxy) promise stops being callable.
> The point is that at the end of the "event loop turn", you know what the
> intention of the author is but you haven't started fulfilling promises, so
> it may be worth waiting to know whether to do a GET or a POST.
> It comes with the cost of waiting for the end of "event loop turn" which
> may never come... but promises won't be fulfilled anyway if it doesn't
> come, so whether you did a GET, a POST or nothing changes from a network
> perspective, but does not from a JavaScript program perspective.
> And since the idea is fresh, I may be ignoring some program correctness
> cost.

This replaces the need for a primitive to distinguish "get" from "invoke"
with the need for a primitive to execute code at the end of the current
event loop turn. Also, they are not equivalent: |var f = o.x; f();| would
perform an HTTP GET "x" under the original semantics, and an HTTP POST "x"
given your proposal.

Anyhow, the discussion about proxies being able to distinguish GET from
POST is moot in light of the concurrency strawman, since it proposes not to
overload "." for remote access, instead introducing distinct Q.get/
operations (or "!" syntactic sugar).

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <>

More information about the es-discuss mailing list