Promise/Future: asynchrony in 'then'
claus.reinke at talk21.com
Fri May 3 01:53:38 PDT 2013
>>> Promise.of(value).then(cb) = cb(value)
>>> promise.then(Promise.of) = promise
>> My interpretation of these laws for promises is that attaching a callback to
>> a resolved promise should execute that callback synchronously (though the
>> callback itself may create an asynchronous promise, introducing its own
> It's not that the callback "may" create an async promise: it *must*
> create an async promise, if you want to reason about it in terms of
> the monad laws. The cb must have the signature "a -> Mb", where M in
> this case is Promise. If cb returns a non-promise value, then you're
> not following the monad laws, and you can't reason about monadic
We need cb :: a -> Promise<b> in order to avoid the non-monadic
overloads of 'then' in current promise specs but I was referring to
the choice of such a callback returning a resolved-now promise
(Promise.of) or a resolve-later promise (via some asynchronous
operation like nextTick, ajax, ...).
> Assuming it does follow the monad laws properly, then the return
> value of cb is *always* accessible in the next tick only, regardless of
> whether it runs synchronously or not.
That part I wouldn't be so sure about: in all monads, the .of equivalent
is effect-free (in an IO monad, it does no IO; in a non-determinism
monad, it is deterministic; in a failure/exception monad, it does not
fail; in a count-steps monad, it doesn't count).
If you look at those identity laws at the top again, you'll see that
Promise.of cannot introduce a delay for these laws to work out
(otherwise, the left- and right-hand sides would have different
numbers of ticks/turns).
Almost all monads have other monad constructors that do have
effects (do IO, add non-determinism, throw an exception, ...). It is
just that the monad laws are about the effect-free part only.
At least that is my current reading of the situation;-)
More information about the es-discuss