I’m not sure I fully grok the use cases for FutureResolver#accept and having  
Future<Future<value>>. Having to call an Unwrap extension method on a 
Task<Task<T>> in .NET is an unfortunate necessity. Also, since Future#then 
implicitly resolves a future it is difficult to return a Future<Future<value>> 
from a then.

In every case where I've used something like a Future it has always seemed more 
convenient to have it implicitly unwrap.

For native Futures, I don’t think it makes sense to try and unwrap just any 
object with a callable “then”. Its a necessity today for Promise libraries in 
ES5 as there’s no ideal way to brand an object as a Future.

This is what seems to make sense to me from a practical standpoint when using 
native Futures:


  *   If you resolve a Future (A) with a Future (B), the result of Future (A) 
should be B.
  *   This implicit unwrap should only work out of the box for Future 
subclasses or branded Futures.
  *   To coerce a “thenable” should be an explicit opt-in (e.g. Q(), or 
Future.of).
  *   There should be a well-defined mechanism for chaining futures from 
subclasses to preserve capabilities (ProgressFuture, etc.). One option might be 
a FutureFactory, another is to have subclasses override the .then method.
  *   An alternative to FutureResolver#accept that would allow for an explicit 
Future for a Future, might be to box the future, either explicitly (e.g. 
resolver.resolve({ future: f })) or with something like a Future.box() that 
encapsulates the future. In this way, if you need a future for a future you can 
support it on both FutureResolver and “then”.


A Future for a Future seems like a corner case compared to the broader 
simplicity of an implicit unwrap.

If we had Future.box() instead of FutureResolver#accept, we might be able to do 
things like:

function someFutureFutureV() {
  return new Future(function (resolver) {
    var F = someFutureV();
    var Fboxed = Future.box(F); // some special instance with a .value property?
    // F === Fboxed.value;
    resolver.resolve(Fboxed); // i.e. resolver.resolve(Future.box(F)) instead 
of resolver.accept(F)
  })
}

someFutureFutureV().then(function (F) {
  // “then” unboxes Fboxed, just as it might have unwrapped F were it not boxed.
  // ...
  return Future.box(F); // another Fboxed
}).then(function (F) {
  // F is again preserved, this time from a call to then
  // ...
  return F; // no boxing this time
}).then(function (V) {
  // F is now unwrapped to V
});

While slightly more complicated for the FutureFuture case, the expectations are 
simpler for the broader usage scenarios, and the API surface is simpler (no 
FutureResolver#accept) for the most common use cases. If you really do intend 
to have a FutureFuture, Future.box would let you have a single way to opt in 
for both FutureResolver#resolve as well as Future#then.

Ron


Sent from Windows Mail

From: Tab Atkins Jr.
Sent: ‎Thursday‎, ‎April‎ ‎25‎, ‎2013 ‎8‎:‎38‎ ‎PM
To: Mark S. Miller
Cc: Mark Miller, es-discuss

On Thu, Apr 25, 2013 at 6:49 PM, Mark S. Miller <[email protected]> wrote:
> What is the semantics of Future.resolve?

Creates an already-accepted future using the "resolve" algorithm,
which is the same magic that happens to the return value of a .then()
callback (if it's a future, it adopts the state; otherwise, it accepts
with the value).

In other words, "If this is a future, use it; otherwise, make me a
future for it".

~TJ
_______________________________________________
es-discuss mailing list
[email protected]
https://mail.mozilla.org/listinfo/es-discuss

_______________________________________________
es-discuss mailing list
[email protected]
https://mail.mozilla.org/listinfo/es-discuss

Reply via email to