What color is your function? (2015)
Sync vs Async in Practice (especially Python)
- Several commenters report success with a “default sync” policy for backends, using threads/processes/replicas for scale instead of async.
- Objections: this can waste performance and developer ergonomics where async frameworks (e.g., in Python or JS) already provide cheap concurrency primitives.
- Counter‑objections: explicit async is cognitively heavy; many workloads don’t justify it, and threads are often easier to reason about.
- Concrete pain point: migrating a deep synchronous call chain to async can force widespread signature changes.
What “Color” Really Means
- Key refinement: a “color” is a non‑optional property that must propagate up the stack; you cannot locally hide or stop it.
- Error returns are not necessarily colors, because errors can often be handled locally and not bubble further.
- Async is usually a true color; context objects or parameters (like Go’s
context.Context) are not, because you can fabricate or ignore them locally. - Some argue that “everything has a color” (e.g., thread‑safety, blocking, IO), but others say that dilutes the concept.
Go, BEAM, Threads, and Coroutines
- Go is praised for hiding async via goroutines; any function can block or be launched with
go, avoiding explicit async markers. - Debate over whether this means “no colors” (all functions are effectively “blue”) or “everything is implicitly red.”
- BEAM languages (Erlang/Elixir) and stackful coroutines (Zig, Java virtual threads) are cited as pleasant models: write blocking code, runtime handles scheduling.
- Some note Go still has propagation burdens (errors, contexts) but these are weaker than async coloring.
Algebraic Effects and Theoretical Tools
- Some propose algebraic effects as a general solution: functions declare effects, and callers decide how to handle them (sync, async, mocked, etc.).
- Others warn effects could multiply colors if every library introduces its own, though effect handlers can improve reuse.
Sync Code Waiting on Async (dontawait idea)
- Several want a world where sync code can simply “wait” on async without becoming async itself.
- For Python and JS this is argued to be intentionally restricted: naive blocking from sync code can break event loops, harm performance, or correctness.
- Workarounds like separate event loops or blocking bridges exist but are seen as either second‑best or dangerous.
Reception of the Article & Async/Await Today
- Some say the article overstates the problem; years of JS/C#/Rust async/await usage show coloring is manageable and often not a real‑world blocker.
- Others report concrete pain (e.g., large C# codebases, Python asyncio) and consider the article still accurate as an ergonomics critique.
- There is broad agreement that async/await is far better than raw callbacks, but not that it is the final or best concurrency model.