monadic extension to do-notation

Mat At Bread bread at mailed.me.uk
Sun Feb 7 18:19:31 UTC 2016


The conflation of assignment and awaiting is a bad idea. It leads to lots 
of unnecessary temporary variables and makes anything but the simplest 
expression involving more than one await/promise very ugly - akin to the 
original syntax you're trying to avoid with inner variable declarations and 
<- operations.

A very similar syntax was used by nodent until v1 when it was replaced with 
async and await.

I'd be much more interested in a VM extension that performed auto 
boxing/unboxing on Promises, achieving a similar result without the need 
for additional syntactic constructions


> ----------
> monadic extension to do-notation
> From: Raphael Mu <encryptedredux at gmail.com>
> Date: 7 Feb, 17:07
> To: es-discuss at mozilla.org
>
> 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 (
> http://wiki.ecmascript.org/doku.php?id=strawman:do_expressions), 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)
> ```javascript
> let finalPromise = do {
>     let a <- promiseA;
>     let b <- promiseB;
>     let c = f(a, b);
>     g(a, b, c)
> }
> ```
>
> (desugared to async/await)
> ```javascript
> let finalPromise = (async () => {
>     let a = await promiseA;
>     let b = await promiseB;
>     let c = f(a, b);
>     return g(a, b, c);
> })();
> ```
>
> (desugared to ES6)
> ```javascript
> 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
> collision:
>
> 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 (
> https://mail.mozilla.org/pipermail/es-discuss/2012-March/021624.html).
>
> This is an earlier draft of this proposal:
> https://github.com/edge/es-monadic
>
>
>
> ----------
> Re: monadic extension to do-notation
> From: Rick Waldron <waldron.rick at gmail.com>
> Date: 7 Feb, 17:19
> To: Raphael Mu <encryptedredux at gmail.com>, es-discuss at mozilla.org
>
> What does this do?
>
>
> let finalPromise = do {
> let a;
> a <- b;
> }
>
>
> Currently, that's an expression that means "a less than negated b"
>
> Rick
>
> On Sun, Feb 7, 2016 at 12:07 PM Raphael Mu <encryptedredux at gmail.com> wrote:
>
>> 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 (
>> http://wiki.ecmascript.org/doku.php?id=strawman:do_expressions), 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)
>> ```javascript
>> let finalPromise = do {
>>     let a <- promiseA;
>>     let b <- promiseB;
>>     let c = f(a, b);
>>     g(a, b, c)
>> }
>> ```
>>
>> (desugared to async/await)
>> ```javascript
>> let finalPromise = (async () => {
>>     let a = await promiseA;
>>     let b = await promiseB;
>>     let c = f(a, b);
>>     return g(a, b, c);
>> })();
>> ```
>>
>> (desugared to ES6)
>> ```javascript
>> 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
>> collision:
>>
>> 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 (
>> https://mail.mozilla.org/pipermail/es-discuss/2012-March/021624.html).
>>
>> This is an earlier draft of this proposal:
>> https://github.com/edge/es-monadic
>> _______________________________________________
>> es-discuss mailing list
>> es-discuss at mozilla.org
>> https://mail.mozilla.org/listinfo/es-discuss
>>
>
>
>
> ----------
> Re: monadic extension to do-notation
> From: Kevin Smith <zenparsing at gmail.com>
> Date: 7 Feb, 17:35
> To: Rick Waldron <waldron.rick at gmail.com>, Raphael Mu 
> <encryptedredux at gmail.com>, es-discuss at mozilla.org
>
> Why not just use await within `async do`?
>
> On 12:19PM, Sun, Feb 7, 2016 Rick Waldron <waldron.rick at gmail.com> wrote:
>
>> What does this do?
>>
>>
>> let finalPromise = do {
>> let a;
>> a <- b;
>> }
>>
>>
>> Currently, that's an expression that means "a less than negated b"
>>
>> Rick
>>
>> On Sun, Feb 7, 2016 at 12:07 PM Raphael Mu <encryptedredux at gmail.com>
>> wrote:
>>
>>> 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 (
>>> http://wiki.ecmascript.org/doku.php?id=strawman:do_expressions), 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)
>>> ```javascript
>>> let finalPromise = do {
>>>     let a <- promiseA;
>>>     let b <- promiseB;
>>>     let c = f(a, b);
>>>     g(a, b, c)
>>> }
>>> ```
>>>
>>> (desugared to async/await)
>>> ```javascript
>>> let finalPromise = (async () => {
>>>     let a = await promiseA;
>>>     let b = await promiseB;
>>>     let c = f(a, b);
>>>     return g(a, b, c);
>>> })();
>>> ```
>>>
>>> (desugared to ES6)
>>> ```javascript
>>> 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
>>> collision:
>>>
>>> 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 (
>>> https://mail.mozilla.org/pipermail/es-discuss/2012-March/021624.html).
>>>
>>> This is an earlier draft of this proposal:
>>> https://github.com/edge/es-monadic
>>> _______________________________________________
>>> es-discuss mailing list
>>> es-discuss at mozilla.org
>>> https://mail.mozilla.org/listinfo/es-discuss
>>>
>> _______________________________________________
>> es-discuss mailing list
>> es-discuss at mozilla.org
>> https://mail.mozilla.org/listinfo/es-discuss
>>
>
>
>
> ----------
> _______________________________________________
> es-discuss mailing list
> es-discuss at mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20160207/db16defd/attachment-0001.html>


More information about the es-discuss mailing list