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