Jorge Manrubia

June 4, 2023

Erase and rewind


Imagine a problem you can't understand without solving it first. The first time I saw software development described as a wicked problem was in Code Complete by Steve McConnell, and I haven't seen anything but a constant validation of this proposition throughout my career. And it's a paradoxical one with several counterintuitive corollaries. Here's one: if you don't understand what you need to build, you should start building it. And here's another: sweating to build something just to hit the delete button is sometimes part of the process.

Writing and making code work is costly; thinking and discussing things in the abstract is cheap. Everything holds up on paper, but computers are picky. I don’t believe that LLMs – as revolutionary as they are – will change this imbalance soon. Spending time building something that ends in the trash seems wasteful. How much time I could have saved if I had thought of this or that first!

This is a natural but flawed way of looking at things. After all, if building the right software was a matter of putting enough upfront thinking, we could make the whole thing predictable, which is an idea the industry abandoned more than two decades ago.

I think up-front thinking, designing, and discussing are good and necessary; you just need to understand their place and value. With complex systems, validating whether an idea is good, feasible, and worthy in the abstract is impossible. Too much upfront discussion with too many people can even be counterproductive. Because things are not concrete, it is easy to end up with a blurry list of interpretations, opinions, and hypotheses. All of them can be valid and well-thought. And that is precisely the problem I referred to: everything holds up on paper.

Now, when you write some actual code in a prototype or proof of concept, everything lands in the realm of concrete. Suddenly, you understand the problem, how costly it is, what alternatives you have, and the tradeoffs of each. Other people can see things working; opinions, questions, and answers become real. Contributing value to the discussion becomes way easier. Everyone wins.

Time is finite, though. The best favor you can do yourself with exploratory projects is to timebox them. If you are thinking of dropping the code you wrote, the odds are that the problem is complex and uncertain. In such scenarios, you need protection to avoid an endless rabbit hole. Remember that you are validating ideas; set a deadline for the validation and scope-hammer your way through it.

I started last week by deleting thousands of lines for a prototype I had built for an exciting idea we’re exploring, and I didn’t feel any remorse —quite the opposite. The prototype allowed us to test the idea in different scenarios, discuss its flaws, get key feedback, and clarify what we wanted. What I built didn’t pan out, but it was very valuable to me. After it, I felt we finally knew what we wanted to build. It brought clarity.

If you have to drop code you sweated to write, don’t console yourself with, “at least I learned something”. That’s your subconscious wanting to make software development predictive. Instead, cheers with “I finally understood!”.

Software development is a wicked problem. Ignore at your own peril.


About Jorge Manrubia

A programmer who writes about software development and many other topics. I work at 37signals.