Answering to the Future: Why All Legacy Code Should Die

Recently I happened across an article on Medium entitled Answering to the Future (it's short enough that I won't bother summarizing it). It has an interesting premise and one that we too often fall short of as humans. The simple laziness of designing something a certain way just because it has always been done that way results in extraordinary amounts of waste. Of course, there is an even more nefarious form of waste which we also fall subject to out of laziness: failing to even consider re-designing or re-implementing solutions just because we know how much time it took us to do it the first time and we believe that it will take us equal amounts of time the second time.

This fallacy in reasoning stems from the nature of our reality. Most of the world that we inhabit operates in a non-linear manner, with feedback loops that grow or diminish super-linearly or even exponentially. Yet we as humans too often attempt to reason and approximate things linearly. We don't deal with these kinds of non-linearities well. As a result, if we anticipate something getting better or worse, in our minds, it can only get better or worse at a constant rate. Consequently, we don't believe that things can improve super-linearly or exponentially, yielding false mental barriers to change.

In practice, I experience these phenomenon in a very real way every day. Too often I am asked the question: "how will you handle legacy code?" Legacy code is the bane of most programmers' existence. No matter where we go, we have to deal with it. Some legacy code was elegant and some still is, but more often than not, it is showing its age and is more of a liability than an asset. Just because an application or a system was good for its day, doesn't mean that it still is. Like most other things in our world, our knowledge of software engineering and abstractions is improving exponentially. The implications of this are profound: code that may have once taken us months or years to write, can now be done in days and weeks. Despite this, people refuse to throw away legacy code and start from scratch due to a misguided view that it took them years to write a code one way the first time and it will taken them at best a constant-factor-improvement amount of time to write their code a new way.

Anecdotally, I have personally benefited from completely throwing away my code. On nearly every project I have participated in the past 10 years, at some point I've thrown away the entire code base and started over. In some cases I have done this multiple times. When working on the Legion runtime, I did this three times. The current version of the Legion runtime is actually the fourth incarnation of the system. In the evolution of the Legion, the inherent non-linearities of writing systems code became much clearer to me. Things that took me weeks when building the first version of the system, took me only hours to implement by the time I arrived at the fourth version. More importantly, the same features required exponentially less code and had considerably simpler implementations that were much faster. As a result of my experiences, I will forever after evaluate every project that I work on each year to see which components require entire re-writes.

Of course constantly re-writing code is not without its pitfalls. Perhaps most well-known is the Second System Effect made popular by Fred Brooks. I'll grant Mr. Brooks his premise, but I also believe if we continually iterate multiple times (as is advocated by other programming techniques such as Agile) we tend to reach fixed points without over-extending our feature sets. In my opinion, the benefits of constantly throwing away code and starting over will nearly always outweigh the downsides.

For far too many reasons dealing with legacy code inhibits our progress by creating artificial constraints that are prohibitively restrictive in the design process. The non-linear benefits of better programming systems and tools means that codes that took years to develop the first time can be re-written in weeks and months. From henceforth our designs should be answerable only to the future. We should study legacy code just enough to ensure that we do not repeat the same mistakes, but the idea that code is sacred and cannot be re-written is simple logical fallacy stemming from a lack of insight into the nature of how our world works. We should all embark on a crusade to eliminate all legacy code from the world, starting with our own...