4 ms·
I like your idea, but I don't see how it could work in an untyped language. Consider: function foo() { return 1; } function bar() { return fetch('http:
by laughinghan 7y ago
I like your idea, but I don't see how it could work in an untyped language. Consider:
function foo() { return 1; }
function bar() { return fetch('http://example.com'); } // implicitly async
function qux() {
const fn = Math.random() > 1/2 ? foo : bar;
fn();
return 1;
}
Is qux() synchronous?
- anonytrary 7y agoThe function is both synchronous and asynchronous until it is called by the caller. This is called Shannon's Cat. Jokes aside, I'd like to add that just because a function returns a promise doesn't mean the caller will always want to wait for it to resolve. I think of `await` as a simple modifier that casts the return value from a `Promise<T>` into `T`. By getting rid of the modifier, we can no longer assume that the caller wants to implicitly wait.
- mstade 7y agoYou're right of course, and I have zero data to back this up other than anecdotes from my own experience, but still I posit the most common case is that the caller wants to await the return value, not run the function asynchronously. This is why I think it'd make more sense to flip the semantics so you'd have implicit await, and have to explicitly mark the things you want to run asynchronously.
- anonytrary 7y agoI think there might be some confusion here. `foo()` will run asynchronously regardless of whether or not `await` is specified. I agree that in most cases, you will want to unbox the Promise. It is still very common to pass Promises around as values.
- eyelidlessness 7y agoImplicit await would be a nightmare. You could never tell looking at a given block of code whether it yields to the event loop or not, introducing invisible concurrency problems. Even static types wouldn't solve this without looking at every value and function return type.
- mstade 7y agoWould love to learn what concurrency issues you'd see with implicit await, that you presumably wouldn't see otherwise. You're probably right, I just can't think of any examples.
- mstade 7y agoThe point isn't so much whether qux() is async or not, it's whether the caller wants it to execute before subsequent statements or not. In the current state of the world: const a = await qux() const b = qux() const c = await qux() const d = (await b) + 5 But if I had my little way: const a = qux() const b = async qux() const c = qux() const d = b + 5 The weird one is `d` of course, why would it implicitly await there? Because `+` tries to get the value of `b` in order to add `5`. How the runtime would optimize this scenario I don't know, it could probably statically determine that qux() may be async and therefore determine it would have to implicitly await its return value even if it's just the number. Obviously this is a contrived scenario, but I'd rather pay a small runtime cost, than pay the cognitive overhead of remembering to await things everywhere. Like most people, I forget things...
- laughinghan 7y agoI think you missed my point. I understood how you inverted explicit and implicit, you saw me explain that to someone else who asked about Promise.all(). What I'm asking you is, how does anyone, be it the programmer, compiler, or runtime, know whether to block on qux() or not, given that it sometimes synchronously returns 1? Are you saying that in your proposal, it would become part of the calling convention that any time any function at all returns (and no 'async' keyword was used), the callee would check if a Promise was returned and if so, return a continuation promise? That is no small runtime cost. In an untyped language like JS, the cases where static analysis could determine whether a function returns a Promise or not are vanishingly few, probably about the same as the cases where a function can be inlined. Remember, anyone at any point can overwrite Array.prototype.push to be anything they want, including a function that returns a Promise. Any function that takes and calls a callback might be calling an async function. Any math or string operation could be calling .valueOf() or .toString(), which might be async.