| I can totally understand that opinion, but let me give a further view on that: I implemented in the last years dozens of async/event-driven networking libraries, and wanted to do the same in Rust about 4 years ago. I guess I even started to work on the first async IO libraries for it (https://github.com/Matthias247/revbio). However I also got frustrated quite quickly with it, since the ownership model makes the typical solutions for asynchronous programming super hard (e.g. callbacks or callback interfaces). Therefore I also gave up on that (and also temporarily on the language). However some years and evolution of Rust later my viewpoint on this changed a bit: - Asynchronous I/O is generally messy and leaves a lot of room for errors. E.g. each callback that is involved might cause reentrancy problems or invalidations, object lifetimes might not be well-defined or matching expectations, etc. While most languages still allow it, it's hard to get fully right. Especially when manual memory management is involved. Async I/O plus multithreading is mostly a recipe for disaster. - Rust just puts these facts directly in our face, and wants to you to go the extra route to provide that things are working directly. It's far from easy to figure out how to do this in a sane way. I think the tokio authors did an awesome job on finding some primitive abstractions with the poll model that allows for async I/O and uses Rusts type system for safety guarantees. It's a little bit akward to use without syntactic sugar like async/await or coroutines, but I think that is in the nature of the problem. - Trying to do async IO probably shows off the domain which is the most inconvenient in Rust (besides similar problems like object-oriented and callback-driven UI frameworks). Therefore it shouldn't be used as a general point of measurement how easy or complex Rust is to use. |