English static mirror for SEO/GEO · AI-assisted translation · Read Chinese original

Function Coloring in async/await: A Deep Dive and Three Alternative Paths

Forum topic · 小凯 · 2026-05-02

Summary

This article analyzes the 'function coloring' problem introduced by async/await in modern programming languages. It traces the history from 1976 promise/future research through Dan Kegel's 1999 C10K problem to C#'s 2012 async/await release, showing how the syntax improved readability but created an irreversible contagion: once a low-level I/O function becomes async, every caller must follow, propagating red-colored functions throughout call chains, tests, and runtime choices. Three responses are compared: the async/await path (Python, JS, Rust, C#) with its ecosystem tax; Java Project Loom in 2023, which deliberately avoided async/await in favor of virtual threads; and Zig's 2025 removal of async/await keywords in favor of passing an I/O interface like an allocator. The piece offers practical guidance on when async is justified and warns that sequential await syntax obscures true data dependencies, often hiding parallelism opportunities.

Key points

  • The core problem: In any language with async/await, functions are effectively tagged 'red' (async) or 'blue' (sync). Rules force red callers, red tests, red frameworks. Bob Nystrom's 2015 essay "What Color is Your Function?" formalized this. Coloring is essentially irreversible: changing one I/O function red paints half the project.
  • Hidden cost #1 — Sequential syntax hides parallelism: await get_orders(); await get_recommendations() looks naturally sequential even when both depend only on user and could run in parallel via asyncio.gather or Promise.all.
  • Hidden cost #2 — Runtime coloring: In Rust, the standard library has no built-in async runtime; Tokio, async-std, and smol are mutually incompatible. The ecosystem split adds an extra axis of complexity beyond function signatures.
  • Alternative path A — Java Project Loom (JDK 21, 2023): No async/await at all. Developers keep writing Thread.start()/Thread.join(); the JVM virtualizes threads underneath so millions can coexist without OS thread overhead. No coloring, no async-compat shims. Java's earlier pain with Future (1999–2012) arguably made this conservatism easier.
  • Alternative path B — Zig (PR merged 2025-07-08): Rather than a workaround, Zig removed async/await keywords. I/O is abstracted as an interface (io) passed in like an allocator; the caller decides whether the underlying mechanism is blocking, threaded, or event-loop-driven. Functions themselves do not change color.
  • Comparison of three routes:
  • | Approach | Representative | Core strategy | Trade-off | |---|---|---|---| | async/await | Python, JS, Rust, C# | Sync syntax for async code | Function coloring, ecosystem fragmentation, hidden serial dependencies | | Virtual threads | Java Loom | Sync code, virtualized scheduler | JVM complexity, not universal | | I/O interface | Zig | Scheduling passed as parameter | Design still being validated, learning curve |

  • Practical guidance: Use async only when there is real I/O concurrency to gain; check whether adjacent awaits have a true ordering dependency (and parallelize if not); isolate coloring using thread pools or asyncio.to_thread rather than letting it propagate everywhere.
  • Historical context: Promise concepts appeared in Friedman & Wise (1976, Indiana) and futures in Baker & Hewitt (1977, MIT). They slept in academia for 22 years until Kegel's C10K problem made event-driven servers necessary — and callbacks unbearable — creating the niche async/await filled.
  • References

  • Bob Nystrom, "What Color is Your Function?" (2015) — http://journal.stuffwithstuff.com/2015/02/01/what-color-is-your-function/
  • Dan Kegel, "The C10K Problem" (1999) — http://kegel.com/c10k.html
  • Java Project Loom, JDK 21 virtual threads (2023)
  • Zig, "remove async and await keywords" PR (2025-07-08)

Tags

#async-await#function-coloring#virtual-threads#project-loom#zig#rust#javascript#concurrency

This page is an English static mirror generated for search and AI citation. It may be a full translation or structured summary of the Chinese original. Canonical interactive discussion lives on the Chinese page: https://zhichai.net/topic/177619054