9 ms·
I find all the async stuff in Rust incredibly ugly, cumbersome, and its one of the biggest reasons I prefer C++, still. C++ lets me just write single- or multit
by lionkor 3y ago
I find all the async stuff in Rust incredibly ugly, cumbersome, and its one of the biggest reasons I prefer C++, still. C++ lets me just write single- or multithreaded code, because none of the dependencies force their `async` stuff on me. Yeah, its up to me to ensure things are synchronized, but I'd rather do that than try to figure out how to get some dependency that isnt meant to use async to work in some async move closure.
- zokier 3y agoYour dependencies are what you choose them to be, you are not forced to use async libraries if you don't want to.
- klabb3 3y agoTechnically true, but in practice you’re constrained by whatever is provided by the ecosystem. And the truth is that many Rust projects were forced to choose async or sync, so these are often disjoint and fragmented. Even within async, crate authors need to pick and choose which async ecosystem to support, due to lack of support in std for spawning tasks and running simple IO, which most projects need. This is slightly alleviated by the Tokio hegemony, but that itself is a deferred migration minefield for Rust to handle.
- zokier 3y agoLibraries don't just sprout out from nothingness, someone has written those. And if there isn't a library that suits you, that someone can be you then. Key observation is that the ecosystem is only additive, it doesn't deny you of anything.
- cmrdporcupine 3y agoThis is true to an extant, except it's also a cultural problem: it spreads across crates, and soon you've got tokio spread everywhere. But it's also a concern for me that a language feature was added that requires runtime framework support to function. This is bad separation of concerns. It (async) is viral syntactic sugar that doesn't need to exist; asynchronous programming has been done for decades without it.
- sanxiyn 3y agoEh, in that case, you can also just write single or multithreaded Rust code, entirely ignoring async Rust. I do. And multithreaded Rust is much more pleasant experience than multithreaded C++. Which dependency is forcing async Rust on you? Alternatives are usually available.
- borrow 3y agoPostgres (which is a wrapper around tokio-postgres, and as a result drags the whole tokio bloated dependency graph). I would love to have a purely sync alternative to that.
- deleted 3y ago[deleted]
- almindor 3y agoI am so glad someone said this. This also shows nicely how async is wrong, not just that it's viral, but it's bad design because it forces code duplication. Middleware/library writers that touch on anything that could be async (db, SPI, network etc.) will now have to write two versions of their API and duplicate most code.
- rklaehn 3y agoI can see where you are coming from. But you can do most things purely in sync rust. There are sync rust multithreading libs like rayon that are a joy to use, and there are even blocking versions of popular http libraries like reqwest: https://docs.rs/reqwest/latest/reqwest/blocking/index.html https://docs.rs/reqwest/latest/reqwest/blocking/index.html They are usually doing some ugly stuff internally to make this work, but as a pure library user you don't have to care. If you want to write something small that e.g. pulls some data via http, performs some computation, then pushes the result, it is totally possible to do this fully in sync rust. And if you are writing a highly concurrent web server, looking into async might not be the worst idea.
- eptcyka 3y agoHaving written a lot of async and sync rust, and having both components interact with one another, calling async stuff from a sync context isn't even that ugly these days. But maybe it's stockholm syndrome.
- rklaehn 3y agoIt's OK but not great. Ideally library authors should provide a sync facade so people don't have to deal with this, like reqwest does.
- vacuity 3y agoIdeal for library users but not for library authors...
- masklinn 3y agoThe implementation is really not complicated, though it’s hardly great if you expect it to be performant: reqwest just creates a tokio runtime, schedules the task on it, waits for completion, then tears it down. It’s repetitive but it’s simple.
- yencabulator 3y ago
- littlestymaar 3y ago> but I'd rather do that than try to figure out how to get some dependency that isnt meant to use async to work in some async move closure tokio::spawn_blocking[1], see it's not that hard. But sure to use another language you must learn it, an it requires a bit if effort… [1] assuming you want to use tokio like post people do, but other executors should have the same kind of functions to do that as well if need be.
- rklaehn 3y agoIt's not always that simple. What if your sync lib has some callbacks, and you want to do something in the callbacks that requires async. You could argue that this mismatch exists even with rust itself, where you have Drop, which is sync, and you might have to do something in your drop that requires async, like closing a network connection. You have to pass in some runtime handle that you can use to spawn a task to do what you have to do. This is definitely not simple and beginner friendly. Or even worse - say goodbye to RAII and tell people that they have to explicitly call an async shutdown fn.
- anderskaseorg 3y agoWithin your sync callback spawned via spawn_blocking, you can run async code with Handle::current().block_on(…): https://docs.rs/tokio/latest/tokio/runtime/struct.Handle.html#method.block_on https://docs.rs/tokio/latest/tokio/runtime/struct.Handle.htm....
- rklaehn 3y agoWhich panics if you don't call it in the right context. So now you have code which can only be used under certain circumstances and with one particular async runtime. Since when has it become acceptable in rust to have fns that just panic depending on the state of some thread local? That is one thing I really dislike about tokio. The thread local runtime is convenience over correctness, which is antithetical to what rust usually favours.
- cmrdporcupine 3y ago
- cmrdporcupine 3y agoI find the async stuff obnoxious, too, and I avoid it. Helps that I don't work in the web space. But in general the dependency story with Rust is better than with C++. I don't miss the integration story with C++; just bringing in a dep in the first place is a roll of the dice on whether it's going to work with your build system. And then whether it brings with it some other lifestyle assumptions (exceptions, some third party deps you don't want or can't link to, work with your compiler or not, etc.) Honestly, I work in systems & embedded stuff, and it's not hard to avoid async in Rust. It's only once you start poking at web-adjacent stuff that you run into the wall, and then when you do you find yourself covered in the taint of people who brought their NodeJS Stockholm Syndrome over to Rust, but that's another rant...
- pjmlp 3y agoOr just stick with cmake + vcpkg/conan, and enjoy the existing ecosystem of C++ libraries. Nowadays it is impensable to do a Java project without Maven/Gradle, yet it took about 10 years for Ant to be relevant (counting from 1996), and couple more for Maven, and yet another few for Gradle. Similarly with NuGET and MSBuild evolution. Yet they were eventually adopted, same is happening with vcpkg/conan.