Skip to main content

Command Palette

Search for a command to run...

Don't Repeat Yourself: the second copy is the bug

Updated
•3 min read•View as Markdown
A
I'm a working software engineer. Most of what I write comes from the same place: code is easy to generate now and just as easy to make unmaintainable, and the old engineering habits matter more for it, not less. prickles.org is where I collect those habits as short, specific tenets — guard clauses, screaming architecture, verifiable specs, and the rest. If something here is useful, that's where the full set lives.

I watched a team spend a fortnight arguing about a helper function. Six callers, four boolean flags, a name that had been accurate for the first caller and never since. Everyone agreed it was fine because the alternative was duplication. Duplication is what the book warns you about.

Hunt and Thomas wrote two sentences in 1999, and only the first one gets quoted. Every piece of knowledge must have a single, unambiguous, authoritative representation within a system. That is the rule. The second sentence is hard: it tells you what to do when two lines look alike.

The word is knowledge. Two lines that look the same are not automatically the same fact. Two lines that encode the same fact are.

The reflex

Extraction on sight is the failure mode. You see two similar blocks and pull them into a function. You feel like you have done the tidy thing.

You commit to those two call sites changing together forever. If the resemblance was coincidence, that commitment is a liability. It shows up as a flag parameter the first time one caller needs something slightly different. Then a second flag. By the time anyone reads the signature, the name covers nothing.

What counts as knowledge

A tax rate is knowledge. A date format is knowledge. A validation rule about what makes an order valid is knowledge. Two loops that happen to iterate the same way today are not.

The test I use: if the business changed this fact, would both copies need to change? If yes, they are one fact with two homes and the second copy is the bug. If no, they are two facts that currently look alike, and merging them is the mistake.

The bounded context line

Inside a bounded context, deduplicate freely. It is cheap insurance and the call sites genuinely move together.

Across a context boundary, do not. The same word means different things on either side. A shared helper makes you negotiate every time one side's meaning shifts. Two copies of something that looks identical but means two different things is not duplication. It is two models that happen to share a spelling.

Why agents make this sharper

A developer who meets the flagged helper works out what each branch is for and moves on. An agent reads the name and the signature and takes both as given. One over-eager extraction becomes the vocabulary for everything generated around it.

I have seen https://prickles.org/tenet/dont-repeat-yourself/F3

More from this blog

P

Prickles — software-craft tenets for AI-assisted coding

7 posts

Prickles is a set of software-craft tenets, short and specific principles for keeping a codebase maintainable now that coding agents write a lot of it. Each one is argued and sourced, with the strongest counter-argument I could find against it. The full collection lives at prickles.org. This blog is where some of those tenets get the long-form treatment.