Async await: the worst thing to happen to programming?
Scope of the Debate
- Two main threads:
- Is async/await a good concurrency model vs threads, goroutines, actors, etc.
- Is async/await’s syntax and “function coloring” design a problem.
Why Async/await Exists
- Designed to handle large amounts of I/O without exhausting OS threads.
- Blocking on many OS threads (e.g., thousands to millions of sleeping connections) is seen as impractical in some environments; green threads/event loops mitigate this.
- Particularly valued in server code and UI frameworks where blocking the main thread is unacceptable.
Function Coloring & “Infectious” Async
- Many comments focus on “async is viral”:
- Once a function awaits, it must be marked async; callers must often do the same up the call stack.
- Bridging async and sync code (especially in Python, JS, C#) is awkward and error‑prone.
- Some see this as analogous to an IO monad “polluting” code, but at least making side effects explicit.
- Others argue this “infection” is inherent to expensive/IO operations and that making it explicit in the type system is a feature, not a bug.
Comparisons to Other Models
- Goroutines / stackful coroutines:
- Seen by several as conceptually “just threads with cheaper scheduling,” blocking semantics, and no function coloring.
- Argued to be easier to teach and use in large apps, though some find Go’s concurrency still “low level.”
- CSP, actors, green threads, virtual threads:
- Suggested as cleaner ways to express concurrency, especially for large systems.
- Some believe these models scale better conceptually; others note they demand more background in formal methods.
- Generators, callbacks, and promises:
- Async/await widely regarded as a big improvement over callback “pyramid of doom.”
- Some prefer promise/future APIs or event-loop abstractions without new keywords.
Language- and API-Specific Friction
- C#: legacy sync codebases and synchronization context semantics are pain points, though many find async/await easy for typical IO/DB-heavy apps.
- JavaScript:
- Event-loop model makes sync blocking APIs and sleep impractical on the main thread.
- Complaints about async-only Web Crypto forcing async “all the way down.”
- Python:
- Async/await separation (e.g.,
asyncio.runvs running in a loop) makes composition tricky.
- Async/await separation (e.g.,
Meta and Tone
- Several comments call the “worst thing to happen to programming” framing exaggerated or clickbait.
- Overall split:
- Strong approval from those who value explicit, ergonomic async I/O.
- Strong criticism from those who dislike function coloring, ecosystem churn, and compositional limitations.