The nuances in this case went well beyond what I was expecting - it's actually
more than just syntax, this heavily crosses over into semantics. It's been a very impressive process, and I was surprised at the power of the solution they landed on.
- Rust has to find a syntax that can work with different underlying libraries (Rust can compile to lots of different targets, some will have capability to accommodate larger libraries than others)
- The abstraction can't incur undue overhead (callback-based solutions may cause allocations that are hard to keep under control and will split the language if it spreads too much)
- The syntax should be pleasant to write for at least the majority of people (modeling your entire application as a state machine around async computation is pretty unpleasant)
- The compiler has to be able to give helpful error messages (this was a problem early on I think)
- Language authors had to think about how the borrow checker would work across async points, and whether to invest in changing the language to make that possible.
- and so on and so on
I really loved this talk by Without Boats (the author of the friendly article) going over all this stuff, really gave me a good sense of what they were up against https://www.youtube.com/watch?v=skos4B5x7qE