Thanks Naveen, I agree, potentially in full. Let me address T.J. Crowder's objections out of order (2,3,1), as the response will be clearer that way.
2. As Naveen noted, this is a use case that I did (and very much intended to) handle in the proposal by having a keyword at the call site. Namely: `let promise = async remote.runInBackground();`. 3. I think the principle "prefer explicit to implicit" argues in *favour* of the proposal (and against the existing syntax). You gave the example: ```js let x = foo(); let y = bar(); ``` Imperative language conventions imply the second statement only executes after the first is fully complete. But if `foo` and `bar` are defined as async functions, the second statement likely starts executing before the *real* work being done in the first statement is complete. The proposed syntax restores the normal imperative conventions, and requires one to be explicit when code departs from those conventions. e.g.: ```js let p = async baz(); // We're explicit that this doesn't work like every other sync function, it just returns a promise! let x = foo(); // This could be an await function or an ordinary sync function. We don't need to care (outside of atomics,etc.) let y = bar(x); // Ditto ``` If you're really committed to being explicit, then we should require the coder to specify how they want *every* call to an async function to be handled. e.g.: ```js let p = async baz(); // Explicit let x = await foo(); // Explicit let y = await bar(x); // Explicit ``` But this seems needlessly verbose. 1. I'm not committed to keeping the `async` and `await` keywords. My original thoughts on this were much like Naveen's proposed keywords. I was initially using `awaitalways` for `await` in the function declaration and `trap` for `async` at the call site, but if we do want to use different keywords, I think I prefer `awaitauto` and `background`. (`awaitauto` rather than `asyncauto` because I think it's very important to be clear about what the default call behaviour becomes.) However, I later realised that the keyword reuse will only be confusing to someone who has only learned the existing (essentially incomplete) async/await syntax. Someone entirely *new* to the language may actually find the completed symmetry of the proposal *less* confusing. The explanation for a new JS developer might run as follows: === *Asynchronous Functions* An "asynchronous function" is any function that returns a `Promise`. `async` and `await` control how an asynchronous function is executed. Prefixing a call to an asynchronous function with `async` will cause it to be run in an asynchronous thread, and will return the `Promise`. Prefixing a function call with `await` will cause execution of the current function to be suspended until the asynchronous function has completed (successfully or otherwise), potentially returning a value computed by the function. Specifying how asynchronous functions should be called every time is cumbersome and error-prone, so you can specify the default approach to calling the function in the function declaration. Thus: ```js async function foo() {} ``` specifies that all calls to the function `foo` will use the `async` method by default and ```js await function bar() {} ``` specifies that all calls to the function `bar` will use the `await` method by default. In either case, you can override the default and force the call behaviour by prefixing the call with either `await` or `async`. === And I think this possibly makes things far clearer than any description I've yet seen, not because it was especially eloquent, but simply because the missing pieces have now been filled in. Nonetheless, I could be convinced otherwise, and I'd be more than willing to accept Naveen's suggestions for different keywords. Cheers, Steven On 4 December 2017 at 16:38, Naveen Chawla <naveen.c...@gmail.com> wrote: > The crux of your idea is: let any calls of an async function inside an > async function automatically await unless explicity instructed to run "in > the background". I like the idea. I just wouldn't use the words "await" and > "async" for it, because they are used as currently in C#. > > On the last disagreement by T.J Crowder: 1. it's an alternative (perhaps > with different words), not necessarily in conjunction with the existing > syntax. 2. The promise would be accessible via e.g. `const promise = > background > remote.runInBackground();` 3. If a presumption is made that in an async > function, other async function calls are automatically awaited unless > prefixed with `background`, I'm not sure about the value of having a "clear > indicator" of which function calls are sync and which are async - in normal > use I wouldn't care. I just want their results and if I want to make a > function async (by adding a server call, etc.), I can do so transparently > without breaking my code. I agree with the thrust of this proposal. > > The horse has bolted on `await` `async`, but maybe with different > keywords, e.g. `asyncauto` and `background`, I would definitely use this > new syntax instead of `await` `async` (which I use currently), for the > reasons stated in the original post. Bug minimization is a big factor in > the features I use, and should be THE driving factor in introducing new > features. > > The OP has stated this idea upon extensive real world use, and I > appreciate that. I would definitely support the introduction of e.g. > `asyncauto` and `background`, and would definitely use it immediately in > all cases instead of `async` `await` if introduced. > > On Sun, 3 Dec 2017 at 17:13 T.J. Crowder <tj.crow...@farsightsoftware.com> > wrote: > >> I understand the motivation, but I have to disagree with the proposal >> for multiple reasons: >> >> 1. It adds too much confusion to the existing syntax. >> >> 2. If the calling code needs to call one of these new-style `await` >> functions and access its promise (rather than `await`ing it), it >> doesn't have a way to do that; `async`/`await` doesn't have full >> coverage of all patterns (yet, possibly never), sometimes you still >> need to access the actual promise (for instance, to feed into >> `Promise.all` or `Promise.race`). (Obviously you could add something >> to make it possible to access the promise.) >> >> 3. Having a clear indicator in the source saying where the async >> boundaries are is useful for code correctness. With the new syntax, I >> have no idea of the temporal sequence of this code: >> >> ```js >> let x = foo(); >> let y = bar(); >> ``` >> >> ...without going and looking at the declarations of `foo` and `bar`. >> With current syntax, it's clear when there's an async break in the >> flow. I think the phrase is "prefer explicit to implicit" or something >> like that. >> >> -- T.J. Crowder >> _______________________________________________ >> es-discuss mailing list >> es-discuss@mozilla.org >> https://mail.mozilla.org/listinfo/es-discuss >> >
_______________________________________________ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss