alt.hn

4/22/2026 at 5:28:58 AM

What Async Promised and What It Delivered

https://causality.blog/essays/what-async-promised/

by zdw

4/22/2026 at 10:06:24 AM

Function colouring, deadlocks, silent exception swallowing, &c aren’t introduced by the higher levels, they are present in the earlier techniques too.

by joelwilliamson

4/22/2026 at 10:26:43 AM

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.

by chmod775

4/22/2026 at 12:50:01 PM

“Function coloring” is an imaginary issue in the first place. Or rather it's a real phenomenon, but absolutely not limited to async and people don't seem to care about it at all except when talking about async.

Take Rust: you return `Result<T,E>`, you are coloring your function the same way as you are when using `async`. Same for Option. Errors as return values in Go: again, function coloring.

One of your nested function starts taking a "serverUrl" input parameter instead of reading an environment variable: you've colored your function and you now need to color the entire call stack (taking the url parameter themselves).

All of them are exactly as annoying, as you need to rewrite the entire call stack's function signature to accommodate for the change, but somehow people obsess about async in particular as if it was something special.

It's not special, it's just the reflection that something can either be explicit and require changing many function signatures at once when making a change, or be implicit (with threads, exceptions or global variables) which is less work, but less explicit in the code.

by littlestymaar

4/22/2026 at 12:38:17 PM

I wish the “Function coloring” died. It made sense in the context of the original blog post (which was about callback hell), but doesn't make sense in the context of async/await. There's litterally nothing special with async, it's just an effect among many others.

As soon as you start using function arguments instead of using a global variable, you are coloring your function in the exact same way. Yet I don't think anyone would make the case that we should stop using function arguments and use global variables instead…

by littlestymaar

4/22/2026 at 5:41:23 AM

Surely by section 7 well be talking (or have talked) about effect systems

by cdaringe

4/22/2026 at 12:39:09 PM

Wasn’t in the prompt.

by twoodfin

4/22/2026 at 10:38:38 AM

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

by paulddraper

4/22/2026 at 9:33:42 AM

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

by andrewstuart

4/22/2026 at 9:37:05 AM

> It’s unintuitive and hard to learn.

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

by nottorp

4/22/2026 at 10:05:34 AM

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.

by afiori

4/22/2026 at 9:44:20 AM

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.

by palata

4/22/2026 at 11:38:45 AM

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

by brazzy

4/22/2026 at 9:51:56 AM

Except you're hearing it from someone who doesn't have a problem handling state machines and epoll and manual thread management.

by nottorp

4/22/2026 at 10:28:46 AM

Frankly, async being non-intuitive does not imply that manual concurrency handling is less so; both are a PITA to do correctly.

by shakow

4/22/2026 at 9:45:20 AM

It is. A lot.

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

by littlestymaar

4/22/2026 at 10:01:57 AM

It IS intuitive.

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

by andrewstuart

4/22/2026 at 10:03:16 AM

I can't follow that it's hard to learn and unintuitive

by tcfhgj

4/22/2026 at 10:03:23 AM

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.

by brazzy

4/22/2026 at 12:07:40 PM

What different way of doing things?

If I want sequential execution, I just call functions like in the synchronous case and append .await. If I want parallel and/or concurrent execution, I spawn futures instead of threads and .await them. If I want to use locks across await points, I use async locks, anything else?

by tcfhgj

4/22/2026 at 10:21:40 AM

> 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

by swiftcoder

4/22/2026 at 11:12:00 AM

Yes - I was really talking about "asynchronous programming" in general, not the async/await ways to do it in particular.

by brazzy