Skip to content

Reflection

Notes on the practice of engineering.

Quieter, more reflective writing from the journal — programming habits, debugging instincts, career observations, and the slow business of getting better at this.

Long view

What we mean by software craftsmanship.

The phrase software craftsmanship gets used to mean different things depending on who is selling something. Some people use it to mean a particular kind of test discipline. Others use it to mean refusing to ship until the code is perfect. Both miss what we mean by it on this site. Craftsmanship, as a working definition, is the slow accumulation of judgment that lets an engineer choose well under uncertainty — about what to build, what to skip, what to abstract, what to leave concrete, when to ship, and when to wait. It is mostly invisible. It shows up in the bugs that never happen because the engineer noticed something subtle two layers down, or in the codebase that is still readable five years after the last person who understood it left the company.

You cannot get there by reading a book about it. You can read a book and recognize, afterwards, things you were already doing. You can also read a book and pick up a vocabulary that helps you talk about your instincts with other engineers. But the actual skill is built the same way woodworking or surgery is built: by repeated, attentive contact with the work itself, with feedback that is honest enough to correct you when you are wrong. Most of what makes someone a good engineer is the residue of having been wrong many times in ways that mattered, and having paid attention.

Reading code as a first-class skill

Engineers spend much more time reading code than writing it, and yet very little training is devoted to reading well. Most working programmers were taught to write functions, not to read systems. The result is a generation of engineers who can produce a clean module from scratch but become helpless inside a forty-thousand-line codebase that someone else wrote in a hurry between 2014 and last Tuesday. Reading code is not a passive activity. It involves forming hypotheses about what the original author was trying to do, finding the seams that betray when those intentions were abandoned, and noticing the comments that explain a decision the code itself can no longer justify. It is closer to literary criticism than to code review.

A good practice: pick a project you do not work on, and read its source code for thirty minutes a week with no goal except to understand it. Choose something that has survived a long time — a database, a compiler, a window manager, an interpreter. Do not skim. Read the way a careful reader reads a difficult novel, with the patience to let the structure reveal itself. After a few months you will discover that you have learned more about how real systems are organized than any course or blog post ever taught you.

Debugging as a thinking discipline

Most of the engineers we have worked with who were genuinely strong shared a quality that is hard to describe but easy to recognize: they refused to be confused. When something did not behave the way they expected, they treated the gap between expectation and reality as the most interesting thing in the room. Average engineers, by contrast, tend to absorb confusion silently. They reach for a workaround, ship something that mostly works, and move on. The bug stays alive in the codebase, waiting.

The discipline of refusing to be confused is the discipline of taking your own surprise seriously. It is also, in practice, the discipline of writing things down. When a system behaves unexpectedly, the act of describing the behaviour to yourself in writing — what you expected, what happened, what you tried, what changed — almost always advances the investigation more than another round of poking at the runtime. The page is patient. The runtime is not.

The cost of clever abstractions

There is a particular kind of engineer who, given a problem, will reach immediately for the most general solution. They will refactor the duplicate three times before it has earned its abstraction; they will introduce a configuration system before there is a second configuration; they will write a plugin interface before there is a second plugin. The work feels productive. It often is not. Premature abstraction is the dominant cause of unreadable code in the codebases we have inherited, and the dominant cause of engineering teams who feel that they are sprinting through mud without ever moving forward.

The conservative move is almost always to keep the duplication. Three copies of similar logic, sitting next to each other, are easy to read, easy to delete, and easy to refactor when the right shape finally shows itself. A single clever abstraction with three callers is, by contrast, a contract that will outlive the assumptions that produced it. Keep the duplication until the cost of duplication clearly exceeds the cost of the wrong abstraction. In our experience that point arrives much later than most engineers want to admit.

Quiet engineers ship

The most productive engineers we have worked with were rarely the loudest in meetings. They tended to be the ones who quietly understood the system better than anyone else, who took notes during reviews instead of pushing back instinctively, who left work at the end of the day with the bug fixed rather than the argument won. None of them were unambitious. They had simply noticed, somewhere along the way, that the work itself was more interesting than the credit for it, and that the people who ended up trusted with the most consequential decisions were the people who kept their heads down and got the previous decision right.

That observation is not a moral instruction. It is a description of how, in our corner of the industry, real authority accrues over time. The engineers who treat their reputation as a side effect of their work, rather than as a thing to be cultivated directly, end up with reputations that survive the next reorg, the next platform shift, the next round of fashion in tooling. Craftsmanship, in the end, is durable. The rest is mostly weather.


Essays from the journal

Reflective writing

A growing collection of shorter essays that follow the same long view.