It's sad that we still have to make async I/O explicit in the code to obtain some efficient concurrency in 2020. Async/await is a huge improvement over callback hell, but this doesn't fix everything. The "function color" problem still exists [1], and seems to be more than binary in rust. This quote from the article is incredibly sad: "each async library, comes its own ecosystem of libraries, which only work with that…
Having to write async versions of the sync APIs doesn't need to be the case: https://docs.rs/smol/0.1.18/smol/ lets you use blocking APIs in async contexts without blocking (by dispatching them to different threads). What the ecosystem is seeing is a few different projects trying things out in different ways to explore the design space. This is not necessarily a bad thing.
> Rust is ground breaking in some areas, but also completely lacks innovation in others.
Other than the borrow checker Rust is a very boring language for language designers. That is intentional :)
> But is it actually _necessary_ to resort to async I/O in Rust, given that the type system appears to make thread-based concurrency safe ?
async/await lets the compiler perform some extra inferences on how you're using your data, which makes writing an `async fn foo();` much easier than `fn foo() -> impl Future;` if you are dealing with borrowed data. Of course, the same underlying threading primitives are still available to use.