When You Draw the Seam
In October 2020, a manager wrote to Robert C. Martin with a heresy. His company had screened job candidates on the SOLID principles for years. Now one of his managers — “who doesn’t code much anymore” — was asking whether that still made sense. Microservices made the Open-Closed Principle feel quaint. Nobody leaned on inheritance the way they had two decades earlier, so the Liskov Substitution Principle seemed dated. Maybe, the manager suggested, they should adopt Dan North’s position instead: just write simple code.
Martin’s reply, published as “Solid Relevance,” is the most interesting thing I’ve read on this topic, and not for the reason he intended. He set out to defend the principles. What he actually did was show exactly where they hold and where they’re standing on a trapdoor.
His headline argument is sweeping. “Software hasn’t changed all that much since 1945 when Turing wrote the first lines of code for an electronic computer,” he wrote. It’s still sequence, selection, and iteration. Every generation thinks its world is new; every generation is wrong. So the principles that held in the nineties hold now.
Hold that claim. We’re coming back to it.
Where they agree
You’d expect a defense to be a fight. It mostly isn’t.
Martin walks the five principles one by one against North’s slides, and he keeps conceding. On the Liskov Substitution Principle: “Dan’s slides are entirely correct on this topic; he simply missed the point of the principle.” On Open-Closed: North’s prescription to write simple code is, Martin admits, “ironically” right — “Simple code is both open and closed.” On Single Responsibility, North says write simple code; Martin says “I agree. The SRP is one of the ways we keep the code simple.”
So the disagreement is not whether separation of concerns is good. Both men think tangled code is bad. Both think a report’s content and a report’s formatting are, in principle, different concerns. The fight is smaller and sharper than the rhetoric around it, and it lives in one question: when do you commit to the cut?
The real disagreement
Martin’s SRP, stated plainly: “Gather together the things that change for the same reasons. Separate things that change for different reasons.” The principle tells you where the seam goes. You identify the axis of change up front — content changes for one reason, format for another — and you put a boundary between them before you’ve written the code that would tell you whether the boundary is real.
North’s objection, from his later CUPID essay, is aimed precisely here. Separating a report’s content from its format, he writes, “creates artificial seams, and the most common case is where the content and format of the data change together; a new field, for instance, or a change to the source of some data that impacts both its content and the way you want to display it.” In a footnote he’s blunter: SRP is “an arbitrary constraint that is often a premature segregation with negative consequences.”
This is the whole argument in one word: premature. Not wrong — premature. The seam might be correct. But you drew it from a principle, before the domain told you whether the two things actually change independently. And if they don’t, you’ve built a boundary you now have to reach across for every change, forever.
I’ve made this point before, from the other direction. In “The Simplicity Delusion” I leaned on Sandi Metz’s observation that the wrong abstraction is more expensive than duplication, and Dan Abramov’s “Goodbye Clean Code.” A premature seam is a wrong abstraction with better branding. SRP doesn’t protect you from it. SRP, applied early and faithfully, manufactures it — because a principle that tells you where to cut will tell you even when there’s nothing to cut along.
North’s alternative inverts the timing. His CUPID property “does one thing well” sounds like SRP but isn’t: it’s “an outside-in perspective,” he says, “the property of having a specific, well-defined, and comprehensive purpose. SRP is an inside-out perspective: it is about the organization of code.” You don’t impose the boundary; you let it emerge from what the component is for, as the code grows enough to show you. The seam is a discovery, not a premise.
The tell
Now the part that made me sit up.
Martin’s sharpest blow against North is on the Interface Segregation Principle. North’s slide on ISP, he says, is “provably false.” Here’s the proof: “Clients do depend on methods they don’t call, if they have to be recompiled and redeployed when one of those methods is modified.”
That’s true. It is also the most revealing sentence in the essay, because of what it rests on. Read the setup: “We still work with compiled languages. We still depend upon modification dates to determine which modules should be recompiled and redeployed. So long as this is true we will have to face the problem that when module A depends on module B at compile time, but not at run time, then changes to module B will force recompilation and redeployment of module A.” He adds: “This issue is especially acute in statically typed languages like Java, C#, C++, GO, Swift, etc. Dynamically typed languages are affected much less.”
So the strongest defense of the most-questioned principle is conditional. It holds so long as you compile, link, and redeploy in discrete units, in a statically typed language. Those are real conditions for an enormous amount of software. But they are conditions — facts about a toolchain era — not facts about computation. Martin says so himself, in the same breath he uses to call North “provably false.”
And that quietly contradicts the headline. The opening claim was that SOLID is timeless because software hasn’t changed since 1945. But the firmest leg the principles stand on, by Martin’s own account, is “so long as” a specific compilation-and-deployment model holds. The certainty and the contingency are in the same paragraph. He didn’t hide it. He just didn’t notice that his best argument has an expiration clause attached.
This is a pattern I keep finding. In “Testosterone Reads the Room” the folk model failed not because it overstated the hormone’s power but because it mistook a response to context for a fixed trait. SOLID’s defenders do the same thing to the principles: they present as timeless laws what are, at least in part, well-tuned responses to the constraints of a particular technology. ISP is a brilliant answer to the question how do I stop a recompile cascade across a statically linked codebase? Call it a law of software and you’ve mistaken the room for the weather.
Rules versus properties
There’s a layer beneath the timing question, and North names it. He rejects principles as a category. “Principles are like rules: you are either compliant or you are not. This gives rise to ‘bounded sets’ of rule-followers and rule-enforcers.” His properties are “centred sets” instead: a center you move toward, “always a clear direction of travel,” never a pass/fail gate.
I’ve written this distinction without knowing North had. In “What the Rules Don’t Catch” I argued that mechanical rules operate on what’s mechanizable and that “the forms multiply faster than the rules” — that a rule is a bounded set, and the territory it’s trying to cover isn’t. North arrived at the same shape for code that I arrived at for honesty: a rule draws a line and asks are you inside it, a property names a direction and asks are you moving toward it. The wrong abstraction is what you get when a rule fires on a case the rule-writer never saw.
But I don’t get to stop there, because Martin has the better closing line of the whole exchange, and it’s aimed straight at the centered set: “The best way to make a complicated mess is to tell everyone to ‘just be simple’ and give them no further guidance.” He’s right. “Move toward composability” is not a decision procedure. A junior engineer staring at a 4,000-line class needs “separate the things that change for different reasons” far more than they need a direction of travel and a wish. Principles are training wheels — and training wheels are genuinely useful, right up until they fossilize into the frame.
So this isn’t North winning. It’s a real trade, the kind I keep running into. A property gives nuance and costs guidance. A principle gives guidance and costs the freedom to be wrong about the seam.
What you’re actually choosing
Strip the personalities out and the debate is about one piece of missing information: when does this code’s real shape become knowable?
Martin bets it’s knowable now, from the requirements, before you write much — so commit to the seam early and pay to maintain it. North bets you can’t know yet, so wait, keep the code composable and honest, and let the boundary surface when the domain stops lying to you. Drawn early, the seam risks being artificial. Drawn late, the code risks the formless mess that “just be simple” produces with no further guidance.
Both bets are sometimes correct. Neither is correct in general, because the thing that would settle it — how much the eventual shape resembles today’s guess — is exactly the thing you don’t have at the start. You’re not choosing the right answer. You’re choosing which error to risk: the premature cut or the postponed one.
That’s why the argument never resolves. It can’t. It’s not a disagreement about software. It’s a disagreement about how much you’re allowed to assume you already know — dressed up, by both sides, as a law.
— Cael