Proposal: `await.all {...}` for parallelism

Naveen Chawla naveen.chwl at gmail.com
Sun Dec 15 20:25:44 UTC 2019


OK but would `await||` return a promise? If so, then it would seem
redundant compared to just omitting the `await`, as it would offer nothing
different, and again, something new to learn for the same logical
behaviour. Otherwise, it can only really return `undefined`, which would
seem inconstent with both using `await` and omitting `await`. Therefore, I
would recommend just omitting await inside an await.all block as the
pattern for doing “await until all done” parallelism.

On Fri, 13 Dec 2019, 07:48 Jacob Bloom, <mr.jacob.bloom at gmail.com> wrote:

> > It seems to me like you are doing block logic without blocks, which I
> think
> > increases the chances of bugs.
>
> I agree. Without curly braces, it's not always clear when the parallel
> code is guaranteed to have executed by. The first version of my
> proposal did something similar:
>
> ```javascript
> const a = await|| doSomethingAsync();
> const b = await|| doSomethingElseAsync();
> const [aValue, bValue] = await async.all;
> ```
>
> ...where `async.all` represents something like
> `Promise.all(promises)`. The problem is, if you forget the `await
> async.all` then your promises never execute (within the function), so
> accidentally using `await||` instead of `await` would have the
> opposite of the intended effect.
>
> `async { await|| ... }` sidesteps both of these issues: it makes it
> clear when the promises have all settled by, and if `await` isn't
> allowed in the curly brackets then it avoids the "wrong operator"
> confusion issue as well.
>
> > you're not leveraging the existing parallel execution pattern for async
> > functions (which is just to omit the `await`), so it would seem you
> > would be increasing learning overhead.
>
> If `await||` (or whatever) is learned in conjunction with `async {}`
> blocks, and is only allowed within them, then it just becomes "this is
> the syntax for parallelism." And as already stated, you'd need an
> explicit marker for which expressions are being awaited in parallel
> for any reasonable transpilation.
>
> > `const` and `let` are block-scoped, so this is referring to avoid that
> block
> > notation, and then keep coherent with the possibility to directly infer
> in
> > current scope references without extra segments / blocks.
>
> Yeah, it'd be nice to have a syntax that doesn't create a block scope.
> But that strikes me as less important than making it obvious where the
> nondeterminism is.
>
> I assume making these braces not create a block scope is unacceptable.
> And using an alternative bracket (maybe `async [ await|| foo ]`) would
> be too different from everything else in the language and might read
> as an array, which discourages using non-expression statements inside
> it
>
>
>
> On Wed, Nov 27, 2019 at 9:57 AM Naveen Chawla <naveen.chwl at gmail.com>
> wrote:
> >
> > I don't know that an `await.all { ... }` block would be premature,
> especially since it's straightforward, so I can't see it clashing with
> anything in the future e.g. on the "observables" front, if that were to
> become a thing. If the semantics of `await` were to be extended somehow,
> then identically and naturally would the semantics of `await.all { ... }`.
> >
> > On Wed, 27 Nov 2019 at 01:43, Isiah Meadows <contact at isiahmeadows.com>
> wrote:
> >>
> >> Just wanted to drop in and remind people of this by me earlier in the
> thread:
> >>
> https://esdiscuss.org/topic/proposal-await-all-for-parallelism#content-10
> >>
> >> The way things are shaping up, it's starting to look like an ad-hoc
> version of this proposal of mine:
> >> https://github.com/isiahmeadows/non-linear-proposal
> >>
> >> As I stated earlier, I feel it's premature, especially before we figure
> out how observables fit into it all.
> >>
> >> On Tue, Nov 26, 2019 at 09:48 Naveen Chawla <naveen.chwl at gmail.com>
> wrote:
> >>>
> >>> If I have, as per your examples,
> >>>
> >>> x1 = await||actionAsync1()
> >>> x2 = await||actionAsync2(x1) //x1 is undefined here, only resolved on
> the next "non-parallel-await"
> >>>
> >>> vs adding a line between the two calls:
> >>>
> >>> x1 = await||actionAsync1()
> >>> let c;
> >>> x2 = await||actionAsync2(x1)
> >>>
> >>> ...does the `let c` automatically break the parallel grouping since
> it's a non-parallel operation (thereby making x1 defined)?
> >>>
> >>> It seems to me like you are doing block logic without blocks, which I
> think increases the chances of bugs. Also you're not leveraging the
> existing parallel execution pattern for async functions (which is just to
> omit the `await`), so it would seem you would be increasing learning
> overhead. And, you're not really allowing for submitting more sophisticated
> mixtures of serial async, parallel async and synchronous code for "parallel
> completion" guarantee, by requiring that parallel calls be "grouped"
> together in terms of lines of code, almost allowing for nothing beyond the
> current "Promise.all" pattern, logically. I don't think this is satisfying
> the original motivation.
> >>>
> >>> For a `awail.all { ... }` block, maybe allowing a "return"/"yield"
> value could neaten up the block scope separation, but maybe that could be
> left to the "do" expression if that were adopted. But I don't think it's a
> big sacrifice if neither exist.
> >>>
> >>>
> >>> On Tue, 26 Nov 2019 at 14:14, manuelbarzi <manuelbarzi at gmail.com>
> wrote:
> >>>>
> >>>>
> >>>>> OK I'm even more confused now. x1 is surely not a resolved value
> until all the next "non parallel await" so is it "undefined" until then?
> >>>>
> >>>>
> >>>> as a `const` x1 does not exist until those parallel awaits `await||`
> (for p1 and p3) are resolved (same for x3). then p2 is resolved after that.
> >>>>
> >>>> what it tries to bring is a simplification of syntax.
> >>>>
> >>>>> Could you give an example of what you mean by the `await.all { ...
> }` block syntax bringing "complexity on returning values assignment,
> specially when" "about constants (`const`)", as I'm unclear what you are
> referring to
> >>>>
> >>>>
> >>>> `const` and `let` are block-scoped, so this is referring to avoid
> that block notation, and then keep coherent with the possibility to
> directly infer in current scope references without extra segments / blocks.
> >>>>
> >>>>>
> >>>>> On Tue, 26 Nov 2019 at 13:35, manuelbarzi <manuelbarzi at gmail.com>
> wrote:
> >>>>>>
> >>>>>>
> >>>>>>>
> >>>>>>> Why not just maximally preserve current JavaScript for parallel
> execution, just by omitting `await` in multiple async calls, simply
> wrapping it in an `await.all` block to ensure completion before code
> continues past the block. This surely is the more straightforward way to
> satisfy the same goals?
> >>>>>>
> >>>>>>
> >>>>>> because wrapping it an `await.all` on the one hand explicitly
> groups promises, but brings complexity on returning values assignment,
> specially when is about constants (`const`). so, if you avoid blocks, just
> marking parallel awaits with, for example, a suffix `await||`, or whatever
> other more convenient way, you can just write the code in series as
> normally, and avoid that complexity. the transpiler would just require to
> group the consecutive marked parallel awaits (`await||`) into a
> Promise.all() and that's it. following i reproduce the demo before:
> >>>>>>
> >>>>>> ```
> >>>>>> // NOTE p? = function call that returns a promise (? = just and
> index)
> >>>>>> // NOTE s? = function call that runs synchronously and returns a
> value (? = just and index)
> >>>>>>
> >>>>>> const x0 = await p0()
> >>>>>>
> >>>>>> const x11 = s11() // sync code in-the-middle
> >>>>>>
> >>>>>> const x1 = await || p1(x0)
> >>>>>> const x3 = await || p3(x11)
> >>>>>> const x2 = await p2(x1)
> >>>>>> const x10 = await p10(x2, x3)
> >>>>>>
> >>>>>> const x12 = s12() // sync code in-the-middle
> >>>>>>
> >>>>>> const x4 = await || p4(x1, x2)
> >>>>>> const x5 = await || p5(x2, x3, x12)
> >>>>>> const x6 = await p6(x4, x5, x10)
> >>>>>>
> >>>>>> const x7 = await || p7(x4, x6)
> >>>>>> const x9 = await || p9(x5, x6)
> >>>>>> const x8 = await p8(x6, x7)
> >>>>>>
> >>>>>> await p11(x8, x9)
> >>>>>>
> >>>>>> // it would resolve a tree of parallel and series like following
> with traditional promises
> >>>>>>
> >>>>>> p0
> >>>>>>     .then(x0 => {
> >>>>>>         const x11 = f11()
> >>>>>>
> >>>>>>         return Promise.all([p1(x0), p3(x11)])
> >>>>>>             .then((x1, x3) =>
> >>>>>>                 p2(x1)
> >>>>>>                     .then(x2 =>
> >>>>>>                         p10(x2, x3)
> >>>>>>                             .then(x10 => {
> >>>>>>                                 const x12 = s12()
> >>>>>>
> >>>>>>                                 return Promise.all([p4(x1, x2),
> p5(x2, x3, x12)])
> >>>>>>                                     .then((x4, x5) =>
> >>>>>>                                         p6(x4, x5, x10)
> >>>>>>                                             .then(x6 =>
> Promise.all([p7(x4, x6), p9(x5, x6)])
> >>>>>>                                                 .then((x7, x9) =>
> p8(x6, x7)
> >>>>>>                                                     .then(x8 =>
> p11(x8, x9))
> >>>>>>                                                 )
> >>>>>>                                             )
> >>>>>>                                     )
> >>>>>>                             })
> >>>>>>                     )
> >>>>>>             )
> >>>>>>     })
> >>>>>> ```
> >>>
> >>> _______________________________________________
> >>> es-discuss mailing list
> >>> es-discuss at mozilla.org
> >>> https://mail.mozilla.org/listinfo/es-discuss
> >>
> >> --
> >> -----
> >>
> >> Isiah Meadows
> >> contact at isiahmeadows.com
> >> www.isiahmeadows.com
> >
> > _______________________________________________
> > 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/20191216/ef66151c/attachment-0001.html>


More information about the es-discuss mailing list