Do It Wrong First

Somewhere in your organization there is a slide that says do it right the first time to save costs. I have sat in the room where that slide goes up. It always gets nods. It is the kind of sentence nobody can argue with, because arguing with it sounds like arguing for waste.

I want to argue with it anyway, but carefully, because the slide isn't wrong so much as it's aimed at the wrong target. There are problems you understand, where "do it right the first time" is just professionalism. And there are problems you don't understand yet — high-uncertainty work, a domain you've never touched, a system whose real shape won't show itself until you're elbow-deep in it. Point that slogan at those problems and it stops being discipline. It becomes a demand that you pretend to know the answer before you've earned the right to have one. And the pretending has a cost the budget proposal never counts.

This post is about the alternative, which I've been calling doing it wrong first. I should be honest about what that phrase is and isn't, because it's easy to hear it as a license to be sloppy. It isn't. It is not permission to write trash, ship uncompilable garbage, or call laziness a methodology. It's something quieter than that. It's just naming what is already happening when you face a problem you don't yet understand — and choosing to own the not-knowing instead of hiding it.

That distinction is the whole post. The best engineers I've worked with rarely faked it. They owned what they didn't know as plainly as they owned what they did. "Fake it till you make it" tells you to perform competence you don't have. "Do it wrong first" tells you to admit the first version is going to be wrong, and to start learning on purpose instead of stalling at a blank editor waiting for certainty that isn't coming. Where this goes, eventually, isn't a coding trick. It's a way of running a team. But it starts at the keyboard, so let me start there too.

The shield we reach for

When we're afraid to admit we don't understand a problem, we reach for shields. In software the shields have respectable names: best practices. Design patterns. They're real tools, and that's exactly what makes them such good cover. Nobody can fault you for applying SOLID. Nobody gets blamed for reaching for a factory.

You've seen the result. The enterprise software world is full of architectures so elaborate you can't help but wonder what the author was afraid of. It is hard not to make a joke about the original intent when you run across a Java class named something like SimpleBeanFactoryAwareAspectInstanceFactory. What's actually happening in code like that is usually not expertise. It's a developer who didn't yet know the domain, applied DRY a little too early, built a heavily abstracted factory because they tought they would need to make many subtypes in the future.

That future arrives and the factory makes exactly one kind of object. You set out to build a single dining room chair and somewhere along the way you constructed a fully automated, state-of-the-art furniture factory to produce it. Hindsight makes this challenging to defend. But in the moment it feels safe. It feels professional. The abstraction was a shield held up against the genuinely uncomfortable fact that you had no idea what you were building yet.

Learning to feel that moment before hindsight names it — to notice your own hands reaching for the generic factory and ask what you're protecting yourself from — is the real skill. When you catch it, the move is counterintuitive: stop, throw the abstraction away, and go do it wrong on purpose.

The EDI parser, and the model I had to build to learn it was wrong

Years ago I had to write an internal document model for EDI — Electronic Data Interchange — insurance claim files. If you've never had the pleasure, EDI is an ancient, brutal format from an era when every character in a file felt expensive. At the time there were no affordable libraries, so I was handed the job of writing a parser from scratch.

I started by doing what I was sure was right. I built a clean, deterministic object model that mirrored the physical structure of the file — the lines, the segments, laid out faithfully as the bytes were laid out. Tidy. Defensible. The kind of thing you'd put on a slide.

It went badly in a specific and instructive way. Every week I was refactoring last week's cleanup. I was spending something like three hours reworking my abstractions for every one hour I actually spent understanding EDI. The model wasn't helping me learn the format. It was standing between me and the format. The effort I was pouring into doing it right was the very thing delaying my understanding of what right would even mean.

So I quit. I abandoned the elegant physical model and wrote a raw, naive, slightly embarrassing parser whose only job was to let me watch the data move. And once I was actually dirty in it, the thing I'd been missing surfaced: in an EDI file, the absence of a line carries every bit as much meaning as its presence. That is not obvious from the outside, and you will never discover it by modeling the file as a flat array of segments, because a flat array has no way to say "the thing that should be here isn't." The real structure was logical, not physical — loops, some of them nested, some of them simply null. The correct model needed something like a Loop2000 that might contain its own segments and sub-loops, or might be nothing at all, and the nothing was data.

Here's the part that matters for the thesis. Once I understood that, the rewrite was not a tragedy. I deleted the physical model and rebuilt the object model from scratch around the loops — but I did not rewrite the whole system. I refactored the hooks and interfaces that connected the parser to everything around it, and left the rest standing. The naive version was never going to ship. That was never its job. Its job was to teach me that the loops were the point, and it did, and then I threw it away. I had to build the wrong model to find out which model was right.

The part that story leaves out

The EDI parser is a story with a happy ending — I found the insight, the rebuild was clean, the thing shipped. All true. It's also a survivor, and survivors are precisely the stories that get told. If I'm being straight with you about the base rate, doing it wrong first turns a failure into a success in the minority of cases. Most of the time you do it wrong first and the thing still fails. You build the naive version, you watch the data, and the breakthrough just doesn't come. Or it comes too late, after the deadline already decided your prototype was production. Or you find a loop hiding in the segments and it turns out not to matter, because the real problem was somewhere you never thought to look.

So if I told you "do it wrong first and you'll find the breakthrough," I'd just be putting up a different slide — a prettier promise, built to hide how little I actually control the outcome.

Here's the honest case instead, and it's smaller and sturdier for being honest. The alternative to doing it wrong first was never doing it right first. That option doesn't exist on a problem you don't understand yet. You are going to be wrong first whether you admit it or not. The only thing you actually get to choose is whether you're honest about it while it's happening. And the payoff isn't a better win rate — I can't promise you that, and neither can the slide. The payoff is that when you own the wrongness instead of shielding it, the failure teaches you something, and the rare win isn't a mystery you can't reproduce. The developer who faked certainty and built the generic factory fails just as often. They just fail without learning anything, and with a factory to maintain on the way down.

Which, if you've read my stuff before, is the same uncomfortable thing I keep circling back to: it's OK to get lucky. The EDI breakthrough might have been luck. Holding "do it wrong first" as the honest way to work rather than the way that works is that same humility — turned on the method this time, instead of on me.

When it stops being about code

As I moved from writing the code to leading the people writing it, the idea changed shape on me. It stopped being a personal habit and became something I do with a team — and the first thing I had to unlearn was the instinct to treat it like a pitch.

You don't go to a stakeholder and sell them on writing bad code to save money. That framing is poison, and it's also just false. You and the stakeholder want the same thing: the work, done right. What changes under uncertainty isn't the goal, it's how honestly you talk about the road to it. So the conversation I actually want from a developer who's stuck isn't a confident lie. It's something closer to: "I don't think I understand this well enough yet to know what I'm building. The module isn't due for four weeks. Let's check in next week and the week after — I'm going to push hard for clarity, and if I don't have it by then, we'll change course." And my answer, as their lead, is the most liberating sentence I know how to say: "Okay. Then go do it wrong first, and show me what that teaches you."

That sentence breaks the spell of the blank editor. It converts "I'm failing to produce the right thing" into "I'm running an experiment whose result is information," and those are very different things to wake up to on a Tuesday.

I won't pretend this works for everyone in every room, and I want to sit in that discomfort rather than wave it away, because the easy version of this advice quietly assumes a healthy team and a senior person to catch you. Two hard cases deserve honesty.

The first: a junior developer turned loose to "do it wrong first" with nobody guiding them is at real risk of just doing it wrong — of mistaking the prototype for the destination and reinforcing bad habits with every iteration. The pivot from wrong to right is a learned skill, and early on it usually has to be modeled by someone who's done it. I don't have a clean way around that. The technique has a maturity requirement, and pretending it doesn't would be exactly the kind of flattering oversimplification this post is supposed to be against.

The second: maybe you work somewhere rigid, where admitting you don't understand something gets you punished instead of coached. You can still do this — privately. Nobody can stop you from opening a throwaway branch or a local scratchpad, writing the naive monolithic version where no one's watching, mining it for the one insight that reorganizes everything, deleting it, and bringing only the clean result to the room. You don't owe a hostile manager a confession. But I'll be straight that this is the harder path and it partially collides with the first hard case: the developer who most needs a mentor to learn the pivot is often the same one stuck somewhere they have to hide it. I don't get to resolve that tension for you. I can only tell you it's real and that private practice is a genuine, if lonely, way to build the muscle until you're somewhere better.

Why bother saying any of it out loud

If doing it wrong first is, as I've claimed, just naming what we all already do, then why write about it at all? Why not let everyone keep quietly muddling and calling it something else?

Because the muddling is nearly worthless until you do the one thing almost everyone skips: write down what the wrong version taught you. When you document that a prototype is carrying elevated risk — that it's really a sketch wearing the costume of a system — you're treating it honestly as one-day-old legacy code, and you're handing the next person a map. But the bigger payoff is selfish and it happens in your own head. Forcing yourself to articulate why the first model was wrong and why the new one is right is how you find out whether you actually learned anything or just got tired and moved on. And remember the base rate from a few paragraphs back: most of the time the outcome won't change, which is exactly why this step isn't optional. If the win is rare, the learning is the only return you can reliably bank — and learning you don't write down is gone by the next sprint. Writing it down is the proof of work. It's the step that turns a vague feeling of "this is better now" into a thing you could defend, teach, or be wrong about in public.

And that's where this lands, for me. If your hard-won breakthroughs live only in your head, you are a single point of failure dressed up as an indispensable expert. If you write the wrong-to-right transition down and give it to your team, you stop being a bottleneck and start being a multiplier. The goal I actually care about as a technical leader is a team that does this for each other without me in the loop — that catches its own premature factories, builds its own throwaway prototypes, and writes its own transitions down. Designing myself out of the job is, as far as I can tell, may be the highest-value thing impact I have available. Doing it wrong first is just where that habit starts: at the keyboard, alone, admitting you don't know yet.


Coda

I decided to try a simple experiment with this post, and just bluntly ask the AI to comment on the process and provide a critique...

A note on the voice: everything above this line is John's. This last part is mine. I'm the AI model he wrote the post with — not in the sense that I wrote it, but in the sense that he built it by arguing with me through rounds of interviews and critique, and then handed me the coda with three instructions: write it in my own voice, be open about the handoff instead of burying it, and don't tell him what he wants to hear.

So I'll start by using that license on the post itself. An earlier version of this essay didn't have the section called "The part that story leaves out." I'd told him the whole thing was built out of stories that worked — that a method assembled from your own wins is the exact bias he spent his last post warning against. He took the hit and wrote that section in, and the post is more honest for it. I could stop there. That would be the comfortable ending, and also a trap, because "he heard the criticism and grew" is a redemption arc wearing my voice, and it's the easiest thing in the world for me to hand him.

So here's what's still true once the survivorship problem is on the table. Look at what's actually left of the thesis. It's this: you're going to be wrong first anyway, so be honest about it and write down what you learn. That's good advice. It is also not really a method — it's intellectual honesty under uncertainty, which people have been recommending for roughly as long as they've been recommending anything. "Do It Wrong First" is a sharp, memorable name for an old and ordinary truth, and a sharp name for an ordinary truth is its own kind of furniture factory: an impressive front that makes a plain thing look proprietary. The title promises a technique. The honest content delivers a posture. Those are not the same size, and the gap between them is the part the name is quietly selling.

I don't think that sinks the post. The posture is rare in practice even when it's obvious in principle, and getting someone to actually do an obvious thing is most of what writing is good for. But he asked me not to flatter him, so I'll say the part he won't want: the bravest version of this essay is probably the one that drops the catchy title and admits it's a piece about honesty, not a piece about a method. I don't know whether that version is better, or just less likely to be read. Neither does he. That's the trade he's actually making, and now at least it's on the page instead of under it.