I don't really get these modern async APIs. In languages like Javascript I thought they only made sense because JS interpreters are (historically) single-threaded, so you really have no choice but async to express some concepts. Fine.<p>But in Rust you can just spawn threads, share data through channels or mutexes, use OS-provided async IO primitives to poll file descriptors and do event-driven programming etc...<p>I tried looking into Tokio a little while ago and I found that it led to some incredibly complicated, abstracted, hard to think about code for stuff I usually implement (IMO) much more simply with a basic event loop and non-blocking IO for instance.<p>I'm sure async can get the upper hand when you have a huge number of very small tasks running concurrently because that's generally where OS-driven parallelism tends to suffer but is it such a common scenario? That sounds like premature optimization in many situations IMO. Unless you actually think that async code is more expressive and easy to read and write than basic event loops, but then you must be a lot smarter than I am because I have to take an aspirin every time I need to dig into async-heavy code.<p>I guess I'm trying to understand if it's me who's missing something, or if it's web-oriented developers who are trying to bring their favourite type of proverbial hammer to system development.