If you’re writing code and trying to get it right the first time, you’re doing it wrong. To write good code for any non-trivial problem, you must write it twice. Sometimes more.

Similar to other creative endeavors, like writing, you need to bang out a first draft, and follow it up with several editing passes. As Hemingway says “write drunk, edit sober”. Well, actually, he didn’t say that, but I like the spirit of it: when starting out, be loose, mind open.

Separate your work into at least two stages:

  • A first draft, focused only on problem solving
  • One or more editing passes, to get production-ready

Solving the problem, end to end

Start out solving the essential problems at hand, and eliminating unknowns. Do you need to call a 3rd party API? Do you need to learn a new library? Nail down the algorithm you’ll use?

At this stage you’re figuring things out. Aim only for something that works, end to end. Use whatever makes sense to eliminate unknowns, while doing as little work as possible. Just hack. Use command line tools, scripts, etc.

Take good notes along the way. During problem solving, you may naturally have good ideas about structuring the code, testing it, etc. That’s great. But just acknowledge these in your notes and then shelve them for the next stage.

Don’t worry about how maintainable the code is, we’re not shipping it.

You’re done with this stage when it works. If you’re confident you’ve solved each problem, and connected the solution end to end, then you’re ready to proceed.

But first, if possible, take a break away from the code. Overnight works best for me. I get so much clarity the next morning.

Making the code production ready

You’ve solved the problem. Now your mind is free to focus on creating production-ready, teammate-friendly code.

You’re an editor now. You have a singular focus on refining the code for production, and especially for maintenance by your teammates.

The aim is to make your solution:

  • Understandable and maintainable. Pretend you are the most inexperienced developer on your team. Read the code as them. What context will they have? Do the naming, structure, and comments help bridge the gap for a new reader?

  • Tested. Ensure you have an appropriate level of automated tests in place to catch future regressions.

  • Supportable. How will this behave in production? What logging or reporting will be needed?

Won’t this take longer?

It may seem like this approach will take more time. But time shouldn’t be considered on its own. Rather, we should consider the overall, long-term cost of the code we create. That includes development and maintenance.

Writing code in this way helps me balance problem-solving speed, and quality.