jyn opens by rejecting their own answer. After a talk about a bug that took nine months to debug, a friend asked how to build tools so those epics would not be necessary, and they said: prioritize simplicity. The rest of the essay is an explanation of why that answer was empty — “simple” is usually used as a synonym for “small,” and small is a size, not a design property.

The proof is two programs that count word frequencies. A five-stage Unix pipeline is small. A Clojure program is longer. Then the requirement changes slightly — print the counts in original file order — and the pipeline turns into temp files, joins, and opaque sorts, while the Clojure version grows by a few lines.

That is because the pipeline was small but not simple:

  • Simplicity comes from Hickey’s root, sim-plex: one braid. Its opposite is coupling, not size — so “write programs that do one thing and do it well” is really a claim about size, not simplicity.
  • The braid is sort | uniq --count. Unix has no equivalent of frequencies, so uniq needs adjacent repeats and aggregation gets tied to ordering. That tie is exactly what makes the reordering change expensive.
  • Large is not coupled either. Google Drive for Desktop depends on platform file watchers, a streaming sync client, and conflict resolution — and to the user it is simple: pick a folder, stop thinking about it.
  • In Rust, a struct couples type-checking to a fixed data representation. You get known-present fields and lose runtime iteration. Clojure decouples them: schema annotations are runtime data, checked by a library, inspectable enough to generate your own docs. Typed Racket gets the split at compile time instead.
  • Being small is a resource strategy — a PDP-11, two hours a month, a feature nobody will fund. Being simple is not optional. There is very little advantage to introducing coupling.

The uncomfortable part: decoupling usually means writing the hard thing. SQL and CSS are decoupled because someone spent centuries of person-years on the engines underneath. And the payoff can look backwards — jyn’s coverage pipeline ended up larger after the fix, and simpler, because the hidden dependencies in the dataflow graph were gone.

Worth asking of your own system: what is braided together here that does not need to be?