Blocking code is a leaky abstraction

What is a “leaky abstraction” here?

  • Several commenters argue the article misuses the term.
  • A leaky abstraction is described as one where hidden implementation details still affect visible behavior (e.g., ORMs over SQL, “everything is a file”, fsync semantics).
  • Some say “difficulty integrating two styles” (sync vs async) is not itself “leakiness” but just incompatibility or design cost.
  • Others argue blocking is “leaky” because whether something may block is not expressed in types and can surprise higher-level code.

Blocking vs async, and function coloring

  • Strong disagreement over whether blocking or async is the real “leak”:
    • One side: blocking is the leaky abstraction because any plain function might hide I/O or long waits.
    • Other side: async is leaky/“viral” because once one function is async, many callers must become async too.
  • Some propose three-way distinctions: async / pure / blocking, or using effect systems to express I/O and blocking explicitly.
  • A recurring theme is “function coloring” pain: having to thread async upward through large call stacks.

Rust async/await and Tokio

  • Many find Rust’s async model powerful but complex, especially around Send, runtimes, and integration with blocking code.
  • Frustration that many crates assume a specific async runtime (often Tokio) running in the background, causing runtime panics and version conflicts.
  • Suggestions include explicit runtime “tokens” in types, or effect-like annotations, though practical designs look hard.
  • Some feel async/await is a poor fit for Rust compared with green-thread models; others say it’s necessary for very high concurrency.

Threads, green threads, and alternative models

  • Several people advocate n:m green threads (Go, Erlang/BEAM, Haskell) as a better user-facing abstraction than explicit futures.
  • Others note async/await can be seen as a lower-level generalization of those models, but with more manual bookkeeping.

Domain-specific perspectives

  • Embedded developers split: some say turning blocking into async is easy; others say building sync APIs atop async can be fragile and deadlock-prone.
  • In single-threaded environments (browsers, Node), blocking is clearly harmful; async is essential.
  • UI toolkits requiring a single UI thread are seen as standard, not as a “leaky abstraction”.