It’s proliferation puzzles me: c#, python, node, rust and no doubt others. Yet it seems like a poor abstraction.
1. The cognitive overhead. Whilst the example might be intended to show off power, that function signature is not at all easy to parse mentally. Even allowing for generics it’s still a lot more difficult to think of a function that returns a future that will return the result at some point (as opposed to a function that returns a result synchronously).
2. It’s declared at the call site - not by the caller. As the writer of a function, how am I supposed to know whether the majority of callers will get sufficient benefit to offset the increased cognitive overhead? It can also have viral tendencies: a function that calls an async function is async itself, and so on. (Not sure if that’s mandatory in all language implementations). I’ve seen more than one code base where async was like a virulent rash.
Personally I find Actor model concurrency so much easier to deal with (e.g. Erlang). The rules seem significantly more straightforward and easier to deal with mentally.
Data flow concurrency (e.g. FRP) also seems much easier to reason about.
Async/await by comparison seems like a poor substitute. So I’m puzzled but intrigued by its growing popularity.
I can imagine it’s easier to implement in the language (compiler/runtime), which might be key for rust. I can also see that it’s an incremental step for procedural languages. But then surely it’s a wise investment to build good abstractions in the language - even if it’s (a lot) harder - rather than burden the programmer with more complexity?
What am I missing?