monadic extension to do-notation

Raphael Mu encryptedredux at
Sun Feb 7 17:07:21 UTC 2016

The ES Promise is an instance of Monad, a property that implies a much more
concise and expressive syntax for using Promise, by exploiting its monadic
properties. I've seen a lot of people complain about Promises having too
clumsy a syntax, and likewise for async/await.

We now have the do-notation proposal (, and
monadic assignment would fit well into the syntax.

The extension would allow use of `<-` within a do-expression for binding
Promise values to variables, and the computation would behave most
similarly to the Either monad in Haskell (in the following code, if
promiseA or promiseB reject, the result of the entire expression would be a
rejected Promise).

(monadic extension)
let finalPromise = do {
    let a <- promiseA;
    let b <- promiseB;
    let c = f(a, b);
    g(a, b, c)

(desugared to async/await)
let finalPromise = (async () => {
    let a = await promiseA;
    let b = await promiseB;
    let c = f(a, b);
    return g(a, b, c);

(desugared to ES6)
let finalPromise = promiseA.then(a =>
    promiseB.then(b => {
        let c = f(a, b);
        return g(a, b, c);

The do-notation would apply Promise.resolve to the last expression (like
async and Promise#then), effectively returning another Promise. The current
proposal doesn't specify this behavior, but there are two ways about this

1. use an explicit version of do-notation, e.g. `async do { ... }` or `do*
{ ... }`
2. revise the do-notation proposal to always apply Promise.resolve to the
last expression

Both choices give us a new Promise literal for free: `do* { x }` (1) or `do
{ x }` (2) would be functionally equivalent to `Promise.resolve(x)`.

The idea was briefly mentioned several years ago, but didn't attract much
attention (

This is an earlier draft of this proposal:
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <>

More information about the es-discuss mailing list