A Challenge Problem for Promise Designers

Tab Atkins Jr. jackalmage at gmail.com
Fri Apr 26 13:39:30 PDT 2013


On Fri, Apr 26, 2013 at 6:36 AM, David Bruant <bruant.d at gmail.com> wrote:
> Le 26/04/2013 14:54, Kevin Smith a écrit :
>>
>> What exactly is the controversy here?
>>
>> I think we all agree with the semantics of "then" as specified in
>> Promises/A+.  (If not, then we have a really big problem!)
>>
>> If so, then the only real controversy is whether or not the API allows one
>> to create a promise whose eventual value is itself a promise.  Q does not:
>> it provides only "resolve" and "reject".  DOM Futures do by way of
>> "Future.accept".  As far as I know, there's nothing about Q's implementation
>> that would make such a function impossible, it just does not provide one.
>
> I believe at this point the question isn't so much "can I build a promise
> for a promise?", but rather "what should be the default Future semantics?"
> Namely:
>
>     Future.accept(5)
>         .then(function(x){
>             return Future.accept(x);
>         })
>         .then(function(y){
>             // is y a Future?
>         })
>
> I'm arguing in favor of y being guaranteed to be a non-Future value. It is
> my understanding others would want y to be a Future.
> That would be the controversy as I understand it.

No.  Future callbacks can return Futures, which then chain (the return
value of then adopts the state of the callback's return value).  This
is the big "monad" benefit that we keep talking about.

The only way to get y to be a future is to have the first function do
"return Future.accept(Future.accept(x));".  In other words, you have
to be pretty explicit about this.

The fact that Future callbacks can return either plain values *or*
Futures, and they act consistently with both (sending a plain value to
the next callback in the chain) is extremely powerful and usable, and
means that you basically *never* have to explicitly wrap a callback,
or even worry about the return value of functions.  As long as your
callback is simply returning the function's return value, it can be a
Future *or* a plain value, and it'll just *work* with you none the
wiser.

If other people on the "recursive flattening" side have the same
misunderstanding here that you're showing, no *wonder* we're all
arguing with each other so fiercely!  You're completely correct that
having Y be a Future would be *terrible*, and that's precisely why
Futures work the way they do already.

(For the uninitiated, the chaining behavior is part of the monad
contract.  If y was a Future, it would mean that Futures were only
functors (a weaker abstraction than monads).  Luckily, they're not.)

(By the way, apologies if any of this sounds insulting.  It's
unintentional!  I can't figure out a way to phrase "You're wrong, and
everyone else might be wrong in the same way" in an unambiguously
polite manner. ^_^)

~TJ


More information about the es-discuss mailing list