Is Explicit Concurrency in Rust worth it?

I’m not sure if this is a better place to post or on the other Rust thread, but I’ve been diving into Trio, loving it, and resurrecting some old conversations I had about Rust concurrency over on the RFCs repo a long time ago. The discussion is here, somewhere in the middle of the thread, but I don’t necessarily think its a terribly interesting read.

What came of that conversation was the suggestion, which seemed roughly reasonable at the time and even now, that in a language like Rust, with its emphasis on memory safety and ownership, that while same-thread concurrency is valuable, that splitting the world into colored functions may not be the right way to do it for Rust, though I do not think I had, or have, a solid answer on what I think would be best, all things considered.

Trio has some absolutely awesome primitives, especially nurseries and the like, that would be awesome for Rust, and I’m having a blast learning about Trio, reading through this forum, and following discussions on these design decisions.

What I’m wondering is, especially given the attention paid to ownership and thread-safety in Rust, is there significant extra value that explicit async and await give in that context, especially given the overhead of splitting the world of functions? The cost of splitting the world of functions seems like an absolutely huge cost, and I’m having trouble identifying where it would be a huge help to dealing with things over using implicit concurrency with green threads, given how much care has been taken to make multithreading as safe as possible in Rust.

In Python multithreading is a huge, difficult issue, and using explicit async/await really helps make that more manageable. Are there significant enough issues that, even with the excellent ownership system of Rust, are still present to warrant such a split of the world?

There is thread in this forum where some people, including @njs, talk about the rust approach to concurrency.
I think it really worth to take a look:

1 Like

Thanks, that’s exactly what I needed, and I feel silly now. Because I’d already read that, and had totally understood the parts of it talking about how bending the language of async to the Future machinery was the wrong direction, born out of history rather than necessity. But I had missed the implications of explicit await. Linking right to the money comment was exactly the pointer I needed. Thank you.

What I’m finding really interesting about that discussion is that he concluded that explicit await was unneeded in Rust, but that explicit async was good to explicitly mark functions as coroutines. It doesn’t actually avoid the colored functions problem, which was a big part of me wondering if the explicit async/await syntax is important in Rust.

I think that I’m grokking the reasons why, perhaps especially for Rust with its consistent effort to behave predictably with performance, that keeping the difference between coroutines and regular functions is appropriate. It all makes me feel like, in the end, that most IO would be done by coroutines.

Not for Rust, but I could even imagine such a language that preferred to consistently have the overhead of creating everything as coroutines, which might be the better way to solve the colored functions problem. That could be interesting. And it would make sense that in low-level languages, that the distinction would be important enough that it would never be eliminated.

Right, this is exactly what Go does :-). With the tradeoff being that it means Go’s stack management is totally different from most existing languages like C/C++, and that makes it much more complicated and higher-overhead to call between Go and other languages.

Oh that makes a lot of sense, and a significant downside. Pretty cool though. But of course it still has that harmful go statement… :grinning: