Oh, and just to be clear, there would still need to be an explanation for why you need to attach `async` or `await` to any function that contains a call to an asynchronous function. I assume that requirement exists for performance reasons --- I have suggested that requirement be dropped elsewhere, but understand that may not be practical.
On 4 December 2017 at 23:52, Steven Mascaro <[email protected]> wrote: > 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 <[email protected]> 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 <[email protected]> >> 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 >>> [email protected] >>> https://mail.mozilla.org/listinfo/es-discuss >>> >> >
_______________________________________________ es-discuss mailing list [email protected] https://mail.mozilla.org/listinfo/es-discuss

