Back to News
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 (18 Comments)Read Original on HackerNews

joelwilliamsonabout 2 hours ago
Function colouring, deadlocks, silent exception swallowing, &c aren’t introduced by the higher levels, they are present in the earlier techniques too.
chmod775about 1 hour ago
Function coloring also only applies to a few select languages. If your runtime allows you can call an async function from a sync function by pausing execution of the current function/thread whenever you're waiting for some async op.

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.

paulddraperabout 1 hour ago
> This was bad enough that Node.js eventually changed unhandled rejections from a warning to a process crash, and browsers added unhandledrejection events. A feature designed to improve error handling managed to create an entirely new class of silent failures that didn’t exist with callbacks.

Java has this too.

cdaringeabout 6 hours ago
Surely by section 7 well be talking (or have talked) about effect systems
andrewstuartabout 2 hours ago
I like async and await.

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”.

nottorpabout 2 hours ago
> It’s unintuitive and hard to learn.

Funny, because it was supposed to be more intuitive than handling concurrency manually.

afioriabout 2 hours ago
Some come to async from callbacks and others from (green)threads.

If you come from callbacks it is (almost) purely an upgrade, from threads is it more mixed.

shakowabout 1 hour ago
Frankly, async being non-intuitive does not imply that manual concurrency handling is less so; both are a PITA to do correctly.
palataabout 2 hours ago
It is a tool. Some tools make you more productive after you have learned how to use them.

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.

brazzy7 minutes ago
> 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.

nottorpabout 2 hours ago
Except you're hearing it from someone who doesn't have a problem handling state machines and epoll and manual thread management.
andrewstuartabout 2 hours ago
It IS intuitive.

After you’ve learned the paradigm and bedded it down with practice.

littlestymaarabout 2 hours ago
It is. A lot.

But concurrency is hard and there's so much you syntax can do about it.

tcfhgjabout 2 hours ago
I can't follow that it's hard to learn and unintuitive
brazzyabout 2 hours ago
What's awesome or rewarding 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.

swiftcoderabout 1 hour ago
> 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.

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

brazzy34 minutes ago
Yes - I was really talking about "asynchronous programming" in general, not the async/await ways to do it in particular.
jasodeabout 2 hours ago
>And some languages learned the right lessons from the coloring problem. For example, Go deliberately chose goroutines over async/await, accepting a heavier runtime in exchange for no function coloring at all. Java’s Project Loom (virtual threads in Java 21) made the same bet: lightweight threads that look and behave like regular threads, so no code needs to change color. The Loom team explicitly cited function coloring as a problem they wanted to avoid.

>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