Moohar Archive

Make it work, make it neat, make it fast

28th February 2024

Something I often tell my team and have to keep reminding myself is it takes three attempts to write good code.

You (should) know what the desired outcome is from the beginning, but you don’t necessarily know how to achieve it. Even if you think you know, you don’t really understand the underlying problem until you actually start writing code. Attempt one is experimental. It's a stream of ideas collected from past experience, Google searches and (for us old people) books. The various chunks of code are held together with sticky tape and good wishes. As you start testing and encounter unexpected issues you patch the code with more code in an increasingly desperate and exacerbated attempt to fix all the holes in your logic. The only goal is to get it returning the correct result without the computer crashing. This is the “make it work” phase.

It’s at this point you now understand the problem. Not only are you getting the output you want, but you know the steps required to get there and all the difficulties and obstacles that you might encounter along the way. You also have at least one solution to study and review. You can now look for patterns. You can use hindsight to avoid issues and make better decisions. Attempt two is about correcting mistakes and making it clean and presentable. The goal is to make a version you can be proud of and would be happy to share with others. It’s also very important you don’t break it in the process. This is the “make is neat” phase.

Now you really understand the problem. You’ve made two versions already and explored it from two different angles. By this point you’ve tested it hundreds, maybe even thousands of times. With any luck it’s been tested at scale too. You start to spot the bottlenecks and inefficiencies. You become confident where shortcuts can be taken and importantly where they must be avoided. A third version starts to form in your mind, a leaner, faster, more efficient version. The goal is perfection. This is the “make is fast” phase.

It’s not an original take on software development. A quick google search shows I must have read it somewhere before because it’s everywhere. Nothing is original any more. Anyway, Kent Beck is credited with the quote “Make it work, make it right, make it fast”. I also found a reference to an article by Stephen C. Johnson and Brian W. Kernighan (yes that Brian) in the August 1983 edition of Byte magazine with the quote ”But the strategy is definitely: first make it work, then make it right, and, finally, make it fast.” So it’s almost as old as me. My version is neater though.

A quote from Byte magazine

I don’t believe it’s exclusive to software engineering. I'm sure other professions have variations of this iterative approach. For example in film editing, they go through various stages: initial assembly; rough cut; final cut; directors cut. I’m sure writers have a system too. I should probably research what the suggested stages are for writing blog posts. Even my journey to become physically fitter is going through stages of increased understanding. The outcome has never changed but as I try more things I slowly begin to understand what the actual problem is.

The point, which I keep having to remind myself, is we very rarely get things perfect the first time. If we aim for perfection on the first attempt, we are setting ourselves up for failure. In many cases, aiming for perfection from the beginning can cause a kind of paralysis that prevents us from making any progress. The “make it work, make it neat, make it fast” aphorism gives us (well me at least) permission to focus on the important parts in the correct order and make progress.

Obviously there are subtleties, not every bit of code needs to go through three versions. Some need to go through many more iterations to get them right. It can also be nested, where the various modules of the program go through each phase as does the whole program.

The risk is that due to real world time pressures we never get a chance to go through the “make it neat” or “make it fast” phase. I see this a lot. Most of the work my team has developed and deployed only had time to go through the first phase. Which means the work delivered from the “make it work” phase, still needs to be neat enough to be maintainable and still needs to be efficient enough it doesn't take too long to execute or set the CPU on fire.

The reality is the code we deliver has gone through a few cycles but often there is a bunch of outstanding work we know that could be done to make it neater and or faster. We just don’t have time. Also “code something, test it, fix it, make it do more things, test it, fix it, test it, make it neater, test it, fix it, test it, make it faster, test it, fix it, test it, test it more, fix it, test it, panic, roll back, deploy, run away, come back later” is not as concise as I would like. Might make a cool dance track though.

Now I’ve got that out of my head, I can return to the blog module and resume with phase two “make it neat”.

TC