If all code is legacy code, then we are all maintainers. I carry an image in my head of a vast sea of silent, diligent, dedicated coders who silently maintain much of the code that makes the world go round. I carry this image because I am one of those coders. 

For the better part of the last 15 years, I have either directly maintained 30-year-old code or managed developers who did. And I don’t think I’m alone. I figure for every developer discussing cutting-edge topics on Hacker News, there are seven or eight of us out there, quietly grinding away at keeping that inventory system running on the current version of Windows, despite large chunks of the running code having originally been written in Turbo Pascal 3.0 in 1987. 

It is often said, “The worst programmer I know is me six months ago.”  But I know a programmer worse than that — the developer (maybe it was me) who wrote that code from 37 years ago.

I have spent a serious amount of time trying to decipher what that person did. What in the world were they thinking? Who thought that 13 nested if statements were a good idea? Who decided that five interlocking boolean conditions should go into the fourth nesting of those statements? Hadn’t they heard of an explaining variable? What the heck does the literal value 4 mean here? 9280 lines is a bit much for a single procedure, don’t you think?

So I shake my head, puzzle it out, and fix that bug. Or I wedge a new feature into that thousands-of-lines-of-code procedure. And I marvel that the code still runs, still (mostly) works, and still lives on. 

Sure, we all laugh at the crazy stuff developers did back then. But it occurs to me that a little humility is in order. To our modern eye, which has the benefit of the wisdom of the past few decades, that code looks terrible. But maybe we just didn’t know any better back then.

Standing on spaghetti

At the time, the tools casually encouraged you to write code that today makes us cringe. Much of the code we maintain came from the “onClick” era. Back in the 1990s, “rapid application development” (RAD) was all the rage, and it practically begged us to tightly couple our business logic to our user interface. Double-click on the button and start coding! What could be better?

Back then we were all worried that our administrative assistants were going to use these RAD tools to put us developers out of business. Today we worry that it will be AI. I don’t even want to think what the next thing will be that will allegedly put skilled developers out to pasture. (I’m not a believer that it will ever happen, but that doesn’t stop pundits from scaremongering.)

My awkward dance with Turbo Pascal ought to remind us that the code we write today will likely be viewed in exactly the same way by some developer (maybe it will be you) 37 years from now.  

Our profession grows and improves, and we find better ways to do things. We stand on the shoulders of giants. Software engineers like Martin Fowler, Robert C. “Uncle Bob” Martin, Kent Beck, Michael Feathers, and Grady Booch all noticed — and then codified — practices we all take for granted today.

For instance, object-oriented programming (OOP) revolutionized the way we write code. Yet today, the way we do OOP is vastly different from the way we did even 10 or 15 years ago. 

We wrote a lot of OOP code and eventually figured out principles like “Prefer composition over inheritance” and “Encapsulation is the most important pillar.” It was through hard-won experience that Uncle Bob Martin developed the SOLID principles in 2000.  

Beck didn’t start teaching us to write better code through test-driven development until the early 2000s. Fowler didn’t introduce the term “dependency injection” until 2004. Even today people don’t code against abstractions enough. There was a lot of coupled, multiple-responsibility, abstract code written before these folks and others saw better ways, and yet we still argue over whether they are right and whether these practices do indeed make our code better. 

What goes around

So that takes me back to the current situation. I have to confess that for many years, I’d whine and complain about the code I work with. I’d shake my head in wonder and ask how anyone could write such crappy code. I’d think that it all needs to be rewritten and how could this possibly work anyway?

But at some point, I’d come to realize that it does work. It actually works out there on customers’ machines in the wild. And I decided that I respected that. Sure, fixing things takes more time than I’d like, and adding features can often reinforce the “bad” coding practices, but working code is the ultimate goal, right? And if it works today…?

There is a strong temptation to say “We need to rewrite this to make it better,” and maybe that is the better long-term solution. It’s often hard to say. But for the “vintage” code out there, maybe “fixing bugs and making it work correctly no matter what” is kind of a form of “better.” Sometimes the right thing to do is just fix the bug and add 10 more lines of code to that 1500-line procedure.

So as I work through some code that makes little sense to the modern eye, I try to remember that when that code was written, it was probably cool and innovative and exciting. The person who wrote it was doing their best with what they had and what they knew. 

And I try to remember that there is definitely some eight-year-old kid out there who one day will look at the new, modern, and cool code I write today and shake her head in wonder and mild disgust, asking “How could he have possibly written that?”

So maybe the worst programmer I know is me, right now.