A historical analysis of async programming's evolution from callbacks to promises to async/await, examining how each wave solved the previous wave's worst problem while introducing new structural costs. Callbacks solved thread-per-connection resource exhaustion but created callback hell and fragmented error handling. Promises improved ergonomics but introduced silent error swallowing and a type split. Async/await made code readable but brought function coloring — a viral infection of async signatures throughout codebases — ecosystem fragmentation (e.g., Tokio vs async-std in Rust), new deadlock classes like 'futurelocks', and a sequential trap where the clean syntax actively hides parallelism opportunities. The post notes that Go's goroutines, Java's Project Loom virtual threads, and Zig's Io interface parameter represent deliberate attempts to avoid function coloring entirely.

13m read timeFrom causality.blog
Post cover image
Table of contents
CallbacksPromises and FuturesAsync/AwaitPaying the Function Coloring TaxA Sequential TrapWhat Async Got RightAccumulating Costs
6 Comments

Sort: