Advertisement
Advertisement
⚡ Community Insights
Discussion Sentiment
50% Positive
Analyzed from 966 words in the discussion.
Trending Topics
#async#https#function#await#performance#learn#threads#rust#coloring#lobste
Discussion Sentiment
Analyzed from 966 words in the discussion.
Trending Topics
Discussion (18 Comments)Read Original on HackerNews
Libraries like Tokio (mentioned in the article) have support for this built-in. Goroutines sidestep the issue completely. C# Tasks are batteries included in that regard. In fact function colors aren't an issue in most languages that have async/await. JavaScript is the odd one out, mostly due to being single-threaded. Can't really be made to work in a clean way in existing JS engines.
Java has this too.
I understand that some devs don’t want to learn async programming. It’s unintuitive and hard to learn.
On the other hand I feel like saying “go bloody learn async, it’s awesome and massively rewarding”.
Funny, because it was supposed to be more intuitive than handling concurrency manually.
If you come from callbacks it is (almost) purely an upgrade, from threads is it more mixed.
I find it interesting how in software, I repeatedly hear people saying "I should not have to learn, it should all be intuitive". In every other field, it is a given that experts are experts because they learned first.
Other fields don't have the same ability to produce unlimited incidental complexity, and therefore not the same need to rein it in. But I don't think there's any field which (as a whole) doesn't value simplicity.
After you’ve learned the paradigm and bedded it down with practice.
But concurrency is hard and there's so much you syntax can do about it.
It forces programmers to learn completely different ways of doing things, makes the code harder to understand and reason about, purely in order to get better performance.
Which is exactly the wrong thing for language designers to do. Their goal should be to find better ways to get those performance gains.
And the designers of Go and Java did just that.
Technically, promises/futures already did that in all of the mentioned languages. Async/await helped make it more user friendly, but the complexity was already there long before async/await arrived
>Zig went further: it removed its compiler-level async/await entirely and rebuilt around an Io interface parameter that i/o operations accept. [...] Though some argue that the Io parameter itself is a form of coloring.
>Language designers who studied the async/await experience in other ecosystems concluded that the costs of function coloring outweigh the benefits and chose different paths.
Green threads with a heavier runtime isn't the "right" lesson. Instead, it's a fundamental tradeoff of no-function-colors-ergonomics vs maximum performance. Some simply don't want to pay the "performance tax" or "interoperability tax" to avoid function coloring.
The following is copy-paste of previous discussion links and added Wayback Machine links because lobste.rs is often down. Anyone who thinks Golang made the "right" decision should read why early Rust developers tried green threads and abandoned them. The revised conclusion is that Go's design is a tradeoff that works for their devs but not for Rust. The author of this thread's article does not mention the issues the Rust devs were highlighting.
>Golang and Erlang successfully employ preemptive M:N models and there are no coloring problems in those languages.
The designer of Rust async/await says Go's green threads approach has an unavoidable performance tradeoff: https://news.ycombinator.com/item?id=37439886
Basically, Rust has lower-level performance constraints than Go that they didn't want to compromise on. (I.e. performance constraints of FFI C-interopt with predictable fixed stack space.) :
- https://lobste.rs/s/bfsxsl/ocaml_4_03_will_if_all_goes_well_... (https://web.archive.org/web/20250815150638/https://lobste.rs...)
- https://lobste.rs/s/y3fsrm/what_is_zig_s_colorblind_async_aw... (https://web.archive.org/web/20250402055806/https://lobste.rs...)
- https://lobste.rs/s/eppfav/why_i_rewrote_my_rust_keyboard_fi... (https://web.archive.org/web/20250412170821/https://lobste.rs...)
- https://news.ycombinator.com/item?id=21475154
As counterpoint, Rust's original designer, Graydon Hoare, prefers "green threads". In a recent blog post (2023-June), he mentioned that he understands why the Rust team got rid of it for performance reasons but he's not fully convinced of the ultimate tradeoff:
-> Async/await. I wanted a standard green-thread runtime with growable stacks -- essentially just "coroutines that escape, when you need them too". Possibly with a somewhat-embeddable outer event loop / IO manager library, but that's always going to be a little tricky. Go started and stayed here, but they had to do a bunch of gory compromises to make the FFI work and it leaves a lot of performance on the table and torpedoes a bunch of embedding opportunities. Rust started here too, and it got rewritten a couple times and eventually thrown out because of a lot of reasons but none which completely obviated the need (as evidenced by the regrowth of Async/Await and Tokio). I've softened my position on this and have a grudging respect for where Rust wound up (especially in enabling heterogeneous selects, which I think puts it in a similar and enviable expressivity class as Concurrent ML). But if I'm being honest I never would have agreed to go in this direction "if I was BDFL" -- I never would have imagined it could even work -- and still don't know that I think the result quite pays for itself. -- from https://graydon2.dreamwidth.org/307291.html