<div dir="ltr"><div dir="ltr"><div class="gmail_default" style="font-family:arial,helvetica,sans-serif;color:rgb(0,0,0)">another example, that may "normalize" it a bit more:<br><br>```</div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif;color:rgb(0,0,0)"><div style="font-family:Menlo,Monaco,"Courier New",monospace;font-size:12px;line-height:18px;white-space:pre"><div><span style="color:rgb(0,16,128)">async</span> { <span style="color:rgb(0,128,0)">// ... = returns a promise</span></div><div>    <span style="color:rgb(0,0,255)">const</span> <span style="color:rgb(0,16,128)">x1</span> = <span style="color:rgb(175,0,219)">await</span>|| ...</div><div>    <span style="color:rgb(0,0,255)">const</span> <span style="color:rgb(0,16,128)">x2</span> = <span style="color:rgb(175,0,219)">await</span> ... (<span style="color:rgb(0,16,128)">x1</span>)</div><div>    <span style="color:rgb(0,0,255)">const</span> <span style="color:rgb(0,16,128)">x3</span> = <span style="color:rgb(175,0,219)">await</span>|| ...</div><div>    <span style="color:rgb(0,0,255)">const</span> <span style="color:rgb(0,16,128)">x10</span> = <span style="color:rgb(175,0,219)">await</span> ... (<span style="color:rgb(0,16,128)">x2</span>, <span style="color:rgb(0,16,128)">x3</span>)</div><div>    </div><div>    <span style="color:rgb(0,0,255)">let</span> <span style="color:rgb(0,16,128)">x4</span>, <span style="color:rgb(0,16,128)">x5</span>, <span style="color:rgb(0,16,128)">x6</span></div><div>    </div><div>    <span style="color:rgb(0,16,128)">async</span> {</div><div>        <span style="color:rgb(0,16,128)">x4</span> = <span style="color:rgb(175,0,219)">await</span>|| ... (<span style="color:rgb(0,16,128)">x1</span>, <span style="color:rgb(0,16,128)">x2</span>)</div><div>        <span style="color:rgb(0,16,128)">x5</span> = <span style="color:rgb(175,0,219)">await</span>|| ... (<span style="color:rgb(0,16,128)">x2</span>, <span style="color:rgb(0,16,128)">x3</span>)</div><div>        <span style="color:rgb(0,16,128)">x6</span> = <span style="color:rgb(175,0,219)">await</span> ... (<span style="color:rgb(0,16,128)">x4</span>, <span style="color:rgb(0,16,128)">x5</span>, <span style="color:rgb(0,16,128)">x10</span>)</div><div>    }</div><br><div>    <span style="color:rgb(0,0,255)">let</span> <span style="color:rgb(0,16,128)">x7</span>, <span style="color:rgb(0,16,128)">x8</span>, <span style="color:rgb(0,16,128)">x9</span></div><br><div>    <span style="color:rgb(0,16,128)">async</span> {</div><div>        <span style="color:rgb(0,16,128)">x7</span> = <span style="color:rgb(175,0,219)">await</span>|| ... (<span style="color:rgb(0,16,128)">x4</span>, <span style="color:rgb(0,16,128)">x6</span>)</div><div>        <span style="color:rgb(0,16,128)">x8</span> = <span style="color:rgb(175,0,219)">await</span> ... (<span style="color:rgb(0,16,128)">x6</span>, <span style="color:rgb(0,16,128)">x7</span>)</div><div>        <span style="color:rgb(0,16,128)">x9</span> = <span style="color:rgb(175,0,219)">await</span>|| ... (<span style="color:rgb(0,16,128)">x5</span>, <span style="color:rgb(0,16,128)">x6</span>)</div><div>    }</div><br><div>    <span style="color:rgb(175,0,219)">await</span> ... (<span style="color:rgb(0,16,128)">x8</span>, <span style="color:rgb(0,16,128)">x9</span>)</div><div>}</div></div></div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif;color:rgb(0,0,0)">```</div></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Mon, Nov 25, 2019 at 3:19 PM manuelbarzi <<a href="mailto:manuelbarzi@gmail.com">manuelbarzi@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div class="gmail_default" style="font-family:arial,helvetica,sans-serif;color:rgb(0,0,0)">why not making it work with the addition of a new keyword suffix for parallel awaits (for example, `||`), grouping the mid blocks that require parallelism. playing with your example and going a bit further:</div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif;color:rgb(0,0,0)"><br></div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif;color:rgb(0,0,0)">```</div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif;color:rgb(0,0,0)"><span style="font-family:Arial,Helvetica,sans-serif;color:rgb(34,34,34)">async {</span></div><div><span class="gmail_default" style="font-family:arial,helvetica,sans-serif;color:rgb(0,0,0)">  const v0 = await|| </span>returnsAPromise();<span class="gmail_default" style="font-family:arial,helvetica,sans-serif;color:rgb(0,0,0)"> // to be grouped in parallel</span></div><div>  for (let i = 0; (i < 100000); i++) {<br></div><div>    doesSimpleFastSynchronousMath();</div><div>  }<br></div><div>  <span class="gmail_default" style="font-family:arial,helvetica,sans-serif;color:rgb(0,0,0)">const v1 = </span><span class="gmail_default" style="font-family:arial,helvetica,sans-serif;color:rgb(0,0,0)">await|| </span>returnsAnotherPromise();<span class="gmail_default" style="font-family:arial,helvetica,sans-serif;color:rgb(0,0,0)"> // to be grouped in parallel<br>  async {<br>      await returnsAnotherPromise1();<br>      const v2 = await|| returnsAnotherPromise2(); // to be grouped in parallel<br>      const v3 = await|| returnsAnotherPromise3(); // to be grouped in parallel<br>      await returnsAnotherPromise4(v2, v3);<br>      const v4 = await returnsAnotherPromise5();<br>  }<br>  await returnsAnotherPromiseX(v0, v1);</span></div><div>}</div><div>```<br></div></div></div></div></div></div></div></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Mon, Nov 25, 2019 at 2:06 PM Tom Boutell <<a href="mailto:tom@apostrophecms.com" target="_blank">tom@apostrophecms.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr">There is however a performance concern with your code that we should talk about.<div><br></div><div>If I write this:</div><div><br></div><div>await.all {</div><div>  returnsAPromise();</div><div>  for (let i = 0; (i < 100000); i++) {<br></div><div>    doesSimpleFastSynchronousMath();</div><div>  }<br></div><div>  returnsAnotherPromise();</div><div>}</div><div><br></div><div>Then Babel will have no choice but to compile this to:</div><div><br></div><div>{</div><div>  const promises = [];</div><div>  {</div><div>    const maybeThenable = returnsAPromise();</div><div>    if (maybeThenable && maybeThenable.then) {</div><div>      promises.push(maybeThenable);</div><div>    }</div><div>  }</div><div>  promises.push(returnsAPromise());</div><div>  for (let i = 0; (i < 100000); i++) {<br></div><div>    const maybeThenable = doesSimpleFastSynchronousMath();</div><div>    if (maybeThenable && maybeThenable.then) {</div><div>      promises.push(maybeThenable);</div><div>    }</div><div></div><div>  }<br></div><div><div>  const maybeThenable = returnsAnotherPromise();</div><div>  if (maybeThenable && maybeThenable.then) {</div><div>    promises.push(maybeThenable);</div><div>  }</div><div>}</div><div></div><div>await Promise.all(promises);<br></div><div><br></div><div>Which could have a significant performance impact on that synchronous inner loop.</div><div><br></div><div><br></div><div></div></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Mon, Nov 25, 2019 at 7:55 AM Tom Boutell <<a href="mailto:tom@apostrophecms.com" target="_blank">tom@apostrophecms.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div dir="ltr">Hey, you're absolutely right! It's OK because it just means things are more deterministic before the block exits. It doesn't impact any reasonable expectations *during* the block.<div><br></div><div>I am convinced that your syntax is useful and does not introduce any new confusion.</div><div><br></div><div>I wonder, then, if it is also possible to implement concurrency limits for this properly?</div><div><br></div><div>await.all({ concurrency: 5 }) {</div><div>  for (const item of items) {</div><div>    // returns promise</div><div>    item.process();</div><div>  }</div></div>}<div><br></div><div>This is more challenging because, in our transpilation, we can't just bottle up all the promises and call Promise.all at the end. It would be too late to manage how many are in process at once, bashing on various API limits (:</div><div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Sun, Nov 24, 2019 at 7:43 PM Naveen Chawla <<a href="mailto:naveen.chwl@gmail.com" target="_blank">naveen.chwl@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="auto"><div dir="ltr">Hi! It does not change the meaning of the ";" at all. As you may already know, omitting `await` already invokes multiple async function calls in parallel, in current JavaScript, so absolutely no change in that respect.<div><br></div><div>The only thing this `await.all` suggestion does, is ensure that all non-awaited async function calls are completed before proceeding beyond the end of the block.</div><div><br></div><div>i.e. it adds fairly straightforward and terse deterministic control to otherwise non-deterministic code, without requiring knowledge of destructuring or `Promise.all`.</div></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Sat, 23 Nov 2019 at 13:25, Tom Boutell <<a href="mailto:tom@apostrophecms.com" rel="noreferrer noreferrer" target="_blank">tom@apostrophecms.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr">This is very interesting, but this code:<br><br><div><div>await.all {</div><div>   x = getXAsync();</div><div>   y = getYAsync();</div><div>}</div><div><br></div><div>processXAndY(x, y);</div></div><div><br></div><div>Still carries within it the problem that if I'm looking at just the middle of the { ... } block — if "await.all" has scrolled offscreen — I'll be completely wrong about what ";" means. I think that's too much magic.</div><div><br></div><div>Also, in the case of the "for" loop, this doesn't address managing the level of concurrency. Although it could in theory with a syntax like await.all({ concurrency: 5 }), I'm not sure if it's practical to implement that for your general case.</div><div><br></div><div>Actually I'm curious about what the implementation would look like in general.  If it were babel compiling this, I guess it would have to wrap every statement not preceded by "await" with a check for whether it returns a thenable and add it to an array if it does. But with the concurrency feature it would also have to defer executing the code at all until the right time as otherwise we're still starting zillions of "processes" at once.</div><div><br></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Sat, Nov 23, 2019 at 5:08 AM Naveen Chawla <<a href="mailto:naveen.chwl@gmail.com" rel="noreferrer noreferrer" target="_blank">naveen.chwl@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr">However, if `await.all { ... }` were to mean "wait for all non-awaited async function calls made within this block to complete before proceeding", as I suggested earlier, I think that could satisfy determinism for "await" wherever it is used, and satisfy the original motivation:<div><br></div><div>```</div><div>await.all {</div><div>    for (const item of items) {</div><div>        doTheThingAsync(item);</div><div>    }</div><div>}</div><div>```</div><div><br></div><div>Notice I have omitted `await` inside the loop. Like current JavaScript, that causes parallel execution, so no change on that front, from a determinism perspective. So determinism is not hurt by `await.all`. Rather, it guarantees completion before going further.</div><div><br></div><div>In an earlier example (paraphrase-coded as I forgot the names):</div><div><br></div><div>```</div><div>let x, y;</div><div><br></div><div>await.all {</div><div>   x = getXAsync();</div><div>   y = getYAsync();</div><div>}</div><div><br></div><div>processXAndY(x, y);</div><div>```</div><div><br></div><div>I think the benefit of this syntax appears more stark with the looped (first) example, as current JavaScript requires building an array in the loop to subsequently pass to `Promise.all`, which I think is a little more difficult to conceptualize than the `await.all { ... }` way of doing it. The 2nd example is arguably better than current JavaScript too, particularly because the coder doesn't have to be very smart with destructuring in light of understanding the "Promise.all" return type, etc. In other words, less cognitive overhead, which I think is a net positive.</div><div></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Fri, 22 Nov 2019 at 13:44, Tom Boutell <<a href="mailto:tom@apostrophecms.com" rel="noreferrer noreferrer" target="_blank">tom@apostrophecms.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr">I am very sympathetic to pitches to allow more common cases for promise libraries to be written in an "awaitful" syntax without thinking explicitly about promises.<div><br></div><div>Howeever I think that changing the meaning of the semicolon in a particular context has too much potential for confusion. As others have said, parallel execution is different, and it should look and feel different. The most basic assumption a developer makes (consecutive lines of code run consecutively) is difficult to get away from; that's why we introduced "await" in the first place, to bring back the ability to write deterministic code with consecutive statements. Which sounds like a reasonable ask, when it's put that way. (:<div><br></div><div>I did propose this recently:</div><div><br></div><div>for (const item of items concurrency 5) {</div><div>  await  doTheThing(item);</div><div>}</div><div><br></div><div>However in this case I'm not talking about consecutive statements, I'm only talking about rules for simultaneously (in the sense of async, not threads) running more than one instance of the block. So I'm not proposing that we change the meaning of the semicolon(s) *within* the block in a way that could mean that if you're looking at half the code in the middle you would be likely to fundamentally misunderstand its operation.</div><div><br></div><div>I think that risk - that you can't tell what a semicolon means without reference to the outer context - is what makes your proposal a bridge too far for me.</div><div><br></div><div><br></div><div>-- <br><div dir="ltr"><div dir="ltr"><div><div dir="ltr"><div dir="ltr"><img src="https://docs.google.com/uc?export=download&id=1PuwzIzzd6LKIzLPd1vjM5IwpuaVFI9uK&revid=0ByBugVya1x6fTHRaM0NsZURPQktzVG41aFZMUEwzZWwvMHJnPQ" width="95" height="96"><br></div><div dir="ltr"><span style="color:rgb(0,0,0);font-family:Verdana;font-size:10.6667px;white-space:pre-wrap;background-color:transparent;font-weight:700;vertical-align:baseline"><span style="font-size:8pt">
THOMAS BOUTELL | CHIEF TECHNOLOGY OFFICER</span></span><span style="color:rgb(0,0,0);font-family:Verdana;font-size:8pt;white-space:pre-wrap;background-color:transparent;vertical-align:baseline"><br></span><span style="color:rgb(0,0,0);font-family:Verdana;font-size:8pt;white-space:pre-wrap;background-color:transparent;vertical-align:baseline">APOSTROPHECMS | </span><span style="color:rgb(17,85,204);font-family:Verdana;font-size:8pt;white-space:pre-wrap;background-color:transparent;vertical-align:baseline"><font color="#000000"><a href="http://apostrophecms.com/" style="color:rgb(17,85,204);font-family:Verdana;font-size:10.6667px;white-space:pre-wrap" rel="noreferrer noreferrer" target="_blank">apostrophecms.com</a> | he/him/his
</font></span></div></div></div></div></div></div></div></div>
_______________________________________________<br>
es-discuss mailing list<br>
<a href="mailto:es-discuss@mozilla.org" rel="noreferrer noreferrer" target="_blank">es-discuss@mozilla.org</a><br>
<a href="https://mail.mozilla.org/listinfo/es-discuss" rel="noreferrer noreferrer noreferrer" target="_blank">https://mail.mozilla.org/listinfo/es-discuss</a><br>
</blockquote></div>
</blockquote></div><br clear="all"><div><br></div>-- <br><div dir="ltr"><div dir="ltr"><div><div dir="ltr"><div dir="ltr"><img src="https://docs.google.com/uc?export=download&id=1PuwzIzzd6LKIzLPd1vjM5IwpuaVFI9uK&revid=0ByBugVya1x6fTHRaM0NsZURPQktzVG41aFZMUEwzZWwvMHJnPQ" width="95" height="96"><br></div><div dir="ltr"><span style="color:rgb(0,0,0);font-family:Verdana;font-size:10.6667px;white-space:pre-wrap;background-color:transparent;font-weight:700;vertical-align:baseline"><span style="font-size:8pt">
THOMAS BOUTELL | CHIEF TECHNOLOGY OFFICER</span></span><span style="color:rgb(0,0,0);font-family:Verdana;font-size:8pt;white-space:pre-wrap;background-color:transparent;vertical-align:baseline"><br></span><span style="color:rgb(0,0,0);font-family:Verdana;font-size:8pt;white-space:pre-wrap;background-color:transparent;vertical-align:baseline">APOSTROPHECMS | </span><span style="color:rgb(17,85,204);font-family:Verdana;font-size:8pt;white-space:pre-wrap;background-color:transparent;vertical-align:baseline"><font color="#000000"><a href="http://apostrophecms.com/" style="color:rgb(17,85,204);font-family:Verdana;font-size:10.6667px;white-space:pre-wrap" rel="noreferrer noreferrer" target="_blank">apostrophecms.com</a> | he/him/his
</font></span></div></div></div></div></div>
</blockquote></div>
</blockquote></div><br clear="all"><div><br></div>-- <br><div dir="ltr"><div dir="ltr"><div><div dir="ltr"><div dir="ltr"><img src="https://docs.google.com/uc?export=download&id=1PuwzIzzd6LKIzLPd1vjM5IwpuaVFI9uK&revid=0ByBugVya1x6fTHRaM0NsZURPQktzVG41aFZMUEwzZWwvMHJnPQ" width="95" height="96"><br></div><div dir="ltr"><span style="color:rgb(0,0,0);font-family:Verdana;font-size:10.6667px;white-space:pre-wrap;background-color:transparent;font-weight:700;vertical-align:baseline"><span style="font-size:8pt">
THOMAS BOUTELL | CHIEF TECHNOLOGY OFFICER</span></span><span style="color:rgb(0,0,0);font-family:Verdana;font-size:8pt;white-space:pre-wrap;background-color:transparent;vertical-align:baseline"><br></span><span style="color:rgb(0,0,0);font-family:Verdana;font-size:8pt;white-space:pre-wrap;background-color:transparent;vertical-align:baseline">APOSTROPHECMS | </span><span style="color:rgb(17,85,204);font-family:Verdana;font-size:8pt;white-space:pre-wrap;background-color:transparent;vertical-align:baseline"><font color="#000000"><a href="http://apostrophecms.com/" style="color:rgb(17,85,204);font-family:Verdana;font-size:10.6667px;white-space:pre-wrap" target="_blank">apostrophecms.com</a> | he/him/his
</font></span></div></div></div></div></div></div></div>
</blockquote></div><br clear="all"><div><br></div>-- <br><div dir="ltr"><div dir="ltr"><div><div dir="ltr"><div dir="ltr"><img src="https://docs.google.com/uc?export=download&id=1PuwzIzzd6LKIzLPd1vjM5IwpuaVFI9uK&revid=0ByBugVya1x6fTHRaM0NsZURPQktzVG41aFZMUEwzZWwvMHJnPQ" width="95" height="96"><br></div><div dir="ltr"><span style="color:rgb(0,0,0);font-family:Verdana;font-size:10.6667px;white-space:pre-wrap;background-color:transparent;font-weight:700;vertical-align:baseline"><span style="font-size:8pt">
THOMAS BOUTELL | CHIEF TECHNOLOGY OFFICER</span></span><span style="color:rgb(0,0,0);font-family:Verdana;font-size:8pt;white-space:pre-wrap;background-color:transparent;vertical-align:baseline"><br></span><span style="color:rgb(0,0,0);font-family:Verdana;font-size:8pt;white-space:pre-wrap;background-color:transparent;vertical-align:baseline">APOSTROPHECMS | </span><span style="color:rgb(17,85,204);font-family:Verdana;font-size:8pt;white-space:pre-wrap;background-color:transparent;vertical-align:baseline"><font color="#000000"><a href="http://apostrophecms.com/" style="color:rgb(17,85,204);font-family:Verdana;font-size:10.6667px;white-space:pre-wrap" target="_blank">apostrophecms.com</a> | he/him/his
</font></span></div></div></div></div></div>
_______________________________________________<br>
es-discuss mailing list<br>
<a href="mailto:es-discuss@mozilla.org" target="_blank">es-discuss@mozilla.org</a><br>
<a href="https://mail.mozilla.org/listinfo/es-discuss" rel="noreferrer" target="_blank">https://mail.mozilla.org/listinfo/es-discuss</a><br>
</blockquote></div>
</blockquote></div>