It should be one of the main things bringing you to Rust, because it simplifies a lot of typical concurrency patterns.
When I started out, it felt icky and like some kind of infection that everything eventually had to be async, but that was because I didn't understand how to interact with async code. Using spawn, spawn_blocking, and futures::stream is 90% of my use case, and it makes it easy to set up "barriers" beyond which async doesn't need to spread.
I did a fair bit of Rust (only single-threaded, quite a few years ago) but it sounds like the dependency inversion principle is popping up again.
DIP, async/await, coloured-functions, io-monad. All cases where the business logic should go in one column (abstract/sync/blue/pure), and your machinery should go in the other column (concrete/async/red/io). Your logic will remain unit-testable that way, regardless of how big or small it gets.
Irritated newcomers will complain about not being able to call in the other direction. So what's a language-designer to do? Attract the largest possible user-base by not getting in the user's way - or filter out frustrated users and have fewer but better codebases out there?
I know where you're coming from. But for me it's one of the main reasons I use Rust, since it clicked for me after the initial hurdles. Contrary to the average opinion on this, I like the syntax and don't mind so much about function colouring.
Especially when using tokio I feel like my solutions work out pretty well. I also very much appreciate how they create async equivalent functions for pretty much any std function worth using. Maybe this creates a divide, but my concurrent programs feel easy to code and the performance is pretty good.
My only semi-issues are probably stuff like task cancellation, however I attribute that to skill issues on my end, rather than tokio or the way async/await is implemented in Rust.
It has and it's both pretty mature and extensively used. Some users have philosophical reasons against using async/await at all, so I believe that's why the user said that... The other option being the user doesn't like the way it is implemented, compared to other languages.
jvanderbot|9 months ago
When I started out, it felt icky and like some kind of infection that everything eventually had to be async, but that was because I didn't understand how to interact with async code. Using spawn, spawn_blocking, and futures::stream is 90% of my use case, and it makes it easy to set up "barriers" beyond which async doesn't need to spread.
mrkeen|9 months ago
DIP, async/await, coloured-functions, io-monad. All cases where the business logic should go in one column (abstract/sync/blue/pure), and your machinery should go in the other column (concrete/async/red/io). Your logic will remain unit-testable that way, regardless of how big or small it gets.
Irritated newcomers will complain about not being able to call in the other direction. So what's a language-designer to do? Attract the largest possible user-base by not getting in the user's way - or filter out frustrated users and have fewer but better codebases out there?
vascocosta|9 months ago
Especially when using tokio I feel like my solutions work out pretty well. I also very much appreciate how they create async equivalent functions for pretty much any std function worth using. Maybe this creates a divide, but my concurrent programs feel easy to code and the performance is pretty good.
My only semi-issues are probably stuff like task cancellation, however I attribute that to skill issues on my end, rather than tokio or the way async/await is implemented in Rust.
pjc50|9 months ago
vascocosta|9 months ago