No one wants to write bad code. There’s no programmer out there that is trying to miscommunicate with their computer. In fact, I’d say that for the majority of us, we get an immense sense of pride, accomplishment, and dare I say self-meaning from the code that we write. Of course we’d want what we write to stand the test of time, to live on like the bank mainframes of our grandfathers. Why wouldn’t we?
I don’t want this essay to leave the impression, before I give myself a chance to miscommunicate and express it, that I want someone to write bad code or code that breaks, however you want to define that. I don’t believe that nor would I want my team to try that. Instead I want us to build the best code, however that may be defined at the time.
It is the at the time part that I want to focus on. Because no one has a way of looking into a crystal ball and seeing what will happen in the future, all we can do is gather information now and make guesses about what will happen later. This realization is, I believe, centred around the emotions that started the Agile movement. Put another way, the Agile movement, whatever you want to call it, is a reaction to the fact that we cannot foresee the future but still need a way to plan in it.
The Agile movement had some proponents that created this idea of eXtreme Programming, or XP. It tells us that trying to plan for the future or to code for reusability are a fools errand. It tasks the programmer with meeting the change in requirements head-on, with gusto and courage, to totally embrace the fact that we cannot tell what will happen in the future.
Even before XP, there was a school of thought, expressed by Fred Brooks in The Mythical Man-Month, that we should just plan on throwing one away because we have no idea what we actually need to build until we build it.
In most projects, the first system built is barely usable….Hence plan to throw one away; you will, anyhow.
Fred Brooks | The Mythical Man-Month
I want to take Brooks’ idea and push it one step further in saying
Plan to throw every program you write away
Brooks thought that eventually we would know the requirements to the system we need to build, just like XP thought that we could write enough tests and acceptance criteria to know that we built what we actually needed. In my experience, and in the experience of most of my past teammates, this is not true.
Never do we get to take a step back and say “This is what the client asked for.” There is always a misunderstanding, a change in understanding.
Sometimes this change is internal. We are told that the user actually wanted the font to be bold not italic. Other times, this change is external. A new language comes out, a new paradigm is invented, faster and more robust computers are built.
When my grandfather worked for IBM, he could not fathom a gigabyte. He could not comprehend holding that munch information on a reel to reel cassette tape. However, once we invented hard drives and flash storage, of course we would have gigabytes, even terabytes or petabytes.
Eventually, some way or how, what you think is true will be proven to be wrong. Hell, even Newton was kinda wrong about gravity. Fucking Newton. Do we really think we understand our requirements better than fucking Newton understood gravity? I am not going to go on record saying that.
Instead of trying to protect ourselves for being wrong, I believe that we should embrace it. Embrace that we will be wrong no matter how right we are today. Embrace that we will, one day sooner than later, realize how silly our understanding was.
The larger point I am trying to get at here is that there is no such thing as correct in software. There is no such thing as done. All we have are half-baked attempts, usually done by someone that has long since left the company (with only 18mo avg tenure, it’s not hard to be the last one holding the potato), that at the time were thought of as correct or at least good enough.
Most of our pain and misery in software development comes from when we learn that we are wrong but are unable to change, such as when you are given a “legacy” codebase and are told that it needs new requirements or that the old ones have bugs in them. If that code is not amenable to change, if you cannot easily and quickly iterate on that codebase, I at least get filled with dread, imposter syndrome, negative emotions and thoughts because of my investment in my skills.
I propose that everything we write be able to be thrown away at times like this. When the next engineer comes along and the new management says that they need to fix some bugs or add features, I want them to be able to start fresh, without any of the baggage that my misunderstanding might have caused. I don’t want them to have to decrypt what I thought was truth when they think something different. I don’t want them to have to spend hours if not days pouring over my code and notes just to make a change.
We should, instead, just start fresh. The problems that we are solving are not that hard. We are putting buttons on a screen, we are munging some data from 1 or more data points, we are authorizing a request. None of these things are rare, hard, or complex by themselves. Everything that we get paid to do, by and large, is already a solved problem. Someone on StackOverflow or some random tech blog has already solved this problem. Sure, they didn’t solve it with K8s running on a cluster of Pis or with WizBangBoom running Widget OS on something yet to be created. But that’s not the problem that we are getting paid to solve. We are getting paid to fix a problem that our customers are facing.
The entire software industry is centred around solving problems for humans but most of our job is spent solving problems caused by humans: CI is broken, Typescript is failing, we need to upgrade our dependencies. None of that shit matters to the user that just wants to be able to get their emails on their tablet. We need to stop and think on how we can get rid of all the shit that isn’t directly helping us build features for those users.
Maybe we go back to PHP and Monolithic applications. Maybe we stop trying to ship 5mb of data to our users just so they can fill out a contact form. Maybe we stop using the web all together. I don’t pretend to know. I do, however, know that how we build software today is not going to work tomorrow. We need new ways of thinking, new paradigms for building, new ways of working together to build shit.
Regardless of how we get there, I believe that there looks like building software with Lego blocks, each one a small step away from being replaced with another one. Each small program we write will be able to be replaced at a whim, because that’s what the “market” wants.
Throw your code away, stop putting shit onto shit, get a complete understanding of the problem space. Anything less than that and you are just passing the potato to the next shmuck that gets in your shoes, probably 18mos from now.