On the parallels between writing prose and writing software—and what each discipline can learn from the other.
The Craft of Writing Code
There’s an old idea that programming is just another form of writing. On the surface, it makes sense — both involve arranging symbols into structures that communicate intent. But the comparison runs deeper than most people realize.
1 This idea has been explored by many, notably by Donald Knuth in his concept of “literate programming,” where he argued that programs should be written primarily for human readers.Good writers know that the first draft is never the final one. You write to discover what you think, then rewrite to make that thinking clear. Programming works the same way. The first implementation is an exploration — you’re learning the shape of the problem. The refactor is where craft happens.
2 William Zinsser put it well in On Writing Well: “Rewriting is the essence of writing well — where the game is won or lost.”Yet many engineers treat the first working version as the finished product. They move on the moment the tests pass, never returning to ask: is this the clearest way to express this logic?
Every writer considers their audience. A technical manual reads differently from an essay, which reads differently from a novel. Code has audiences too — the compiler is only one of them. Future maintainers, code reviewers, and your six-months-from-now self are all reading your work.
3 Martin Fowler’s often-quoted line captures this perfectly: “Any fool can write code that a computer can understand. Good programmers write code that humans can understand.”This is why naming matters so much. A variable called d communicates nothing. A variable called daysSinceLastLogin tells a story. The best code reads like well-edited prose: each line earns its place, and the overall structure guides the reader from one idea to the next.
Poets work within the constraints of meter, rhyme, and form. Sonnets have fourteen lines. Haikus follow a 5-7-5 syllable structure. Rather than limiting creativity, these constraints focus it.
4 The poet Richard Wilbur once said that the strength of the genie comes from being confined to the bottle. Creative constraints produce creative solutions.Software engineering has its own constraints — type systems, performance budgets, API contracts, backward compatibility. The engineers I admire most don’t fight these constraints; they let the boundaries shape more elegant solutions. A strict type system isn’t a cage — it’s a sonnet form.
Here’s a heuristic I use: if a function can’t be summarized in a single short paragraph, it’s doing too much. This is the programming equivalent of the “one idea per paragraph” rule in writing. Functions, like paragraphs, should be cohesive units of thought.
5 This is loosely related to the Single Responsibility Principle, but I find the “paragraph test” more intuitive than abstract SOLID definitions.When I find myself writing a multi-paragraph description of what a function does, I know it needs to be broken apart. Each piece should be nameable — and the name should be unsurprising.
Writers read voraciously. It’s how they develop an ear for rhythm, an eye for structure, and a sense of what works. Engineers should read code the same way—not just their own, not just their team’s, but code from open source projects, from different languages, from different eras.
6 Stephen King, in On Writing, recommends reading 4-6 hours a day. For engineers, even 30 minutes of reading unfamiliar code daily builds remarkable intuition.Every codebase has a voice. Reading widely helps you develop yours.
The craft of writing — whether in prose or in code — is ultimately about empathy. You’re not writing for yourself. You’re writing for someone who will encounter your words without the context you currently hold. The best code, like the best writing, anticipates the reader’s questions and answers them before they’re asked.