The nice thing about async/await is that it's just a wrapper around futures, which are themselves a composable wrapper around callbacks (semantically; the implementation can be more efficient, of course). So any language that can express function callbacks as first-class values can represent a future, and any language that can represent a future can interop with the async/await world. Which is why you can have JS code doing await on C# code doing await on C++ code in a Win10 UWP application, and it all works. And you can take existing libraries and frameworks that use explicit callbacks (often written in C), and wrap that into futures such that it's all usable with await.
I'd say the more important concern with c# is to be careful you're not accidentally calling a "really blocking" function from an async method, or you will lose scalability. The lesser issue is the mundane task of changing all your function signatures in the chain to async.
I too would use Go if it didn't regress in every single area for me, other than concurrency, and make me sad.
This is a spot-on. The only language I know that did this all right is Haskell, where most of your code doesn't need any thinking of async operations (either runtime gets you covered, or function takes a callback as a parameter, instead of any await magic), and when you need them -- you have `async` library that gets all you need.
Laziness is not Async.
You explicitly provide instructions which expressions get turned into async expressions in Haskell.
- either Haskell gives you API which is done "right", without any Async types. For example, `bracket` function
- or runtime gives you lightweight threads by default, so you can just `fork myComputation` and it'll run in a lightweight thread which "just works"
- or finally, in rare situations of interleaving different computations with complex dependencies, you just use the `async` library, which is not a special language construct but a library, which lets you "await" and all that
Async/await makes concurrency bubble up. This is a great article that explains this issue: http://journal.stuffwithstuff.com/2015/02/01/what-color-is-y...
It's also why I tried Golang. Once you use goroutines it's hard to go back, since the code is synchronous code.
(I use JavaScript with async/await in my day job)