About Rewriting and our Moronic Predecessors

Over at the schauderhaft blog, people started discussing on whether and why rewriting software might be a good or bad idea.

Some comments go along the lines of:

“What if the guys who wrote the code in the first place were complete idiots and had not the slightest idea what they’re doing?”

You know what: chances are they weren’t, even if you think so. I know I’ve come to the conclusion that moron who wrote this method or that class should be tortured for at least a decade for what he/she did back then quite a few times, hoping they’ll be cooked slowly on some real painful spear for all eternity. But sometimes you find yourself throwing all that perceived crap away and rewriting that stuff “the only clver way to do it”.

And sometimes I found myself getting Trouble Tickets with very strange errors where somehow something wasn’t working any more, or some strange edge case made the application go wild and make its users really, deeply unhappy. Because back then there was a long discussion with the IT guys about why something has to work exactly the way it did just until recently. And trying to reimplement that missing feature I ended up writing surprisingly similar ugly code that was there before. Or I had the time to take a step back and try to get a bigger picture and introduce a redesign. Maybe what they tried to do in a fix was some kind of specialization of what was there, but the risk of introducing a subclass was too high in the light of a near delivery date.

We should keep in mind that legacy code is most likely not the work of mutant neandertals who had just discovered that not all kinds of mouse are edible and keyboards aren’t weapons to kill saberteeth. More often than not they probybly even knew they were writing ugly code, but for a reason. You can probably blame them for not documenting the fact, but on the other hand, would we have read and tried to understand that?

Ten or twelve years ago, many techniques or toolsets weren’t available and the way people solved their problems back then was pragmatic, even if we see that as the wrong way to do it today. But the way they did it was probably very intelligent and clever according to standards that we consider irrelevant today but were state-of-the art back then.

One more thing to keep in mind is that chances are the same developer would probably write completely different code today, knowing what they know now and having the tools at hand today that were science fiction back then. Look at yourself and the code you wrote five years or two weeks ago. How much of it would be the same today?

One of our personal problems as developers or programmers is that we tend to consider ourselves to be geniusses, just because we learned something new or took some hurdles in our daily work that we considered hard and complicated before. And we try to make our work look much better in our own eyes than the one of our colleagues. Maybe that’s because nobody ever says “Thank you for your good work” to us – so we need to do it ourselves. But we overdo sometimes.

I will now even contradict myself to make another point: We tend to think our tools and techniques are so much advanced over the ones people had 5 years ago. But this is often complete nonsense, we are re-inventing the very same things over and over again, pack a bit of cemplexity on top of the last iteration and give it a fancy new name. Just look at the programming language arena: how many languages claim to combine the best of x, y and z and eliminate the weaknesses of a and b? And how many of them introduce something really new? How many stand the test of time?

Rewriting complex software is often nothing else than that: trying to reinvent a ready-made wheel. The low hanging fruit of a new language or platform are so attractive (remember how much endorphine your first “hello world” in javascript produced?) that we tend to forget the essence of rewriting a system is to re-gain all the business and technological knowledge that is buried inside of it. I’ve seen projects fail miserably on this. Without the domain knowledge and a complete set of requirements, your rewrite is a risky endeavour. And I must admit I’ve not yet met a project in which just one of these two was available.

All of this is not to say that rewriting is a bad idea in all cases. But it is well worth trying to understand that turning rusted code into a shining system can be a lot less risk, much cheaper and most likely even provide a much better experience for users and stakeholders. It feels much better to pay for a visibly improving system that makes baby steps to the right direction than for a promised shining new masterpiece that you won’t be able to touch any time soon. And it’s important for us to understand that a black belt in refactoring and sensible redesign is at least as much a sign of MASTERY as being the world’s greatest greenfield programmer. Most rewrite projects aren’t really greenfield anyways and throwing away millions of invested bucks to reinvent the wheel is often not really buying much.

I find myself learning a lot from code that looks bad and ugly in the first place, and I find it rewarding to see I can simplify existing code, clean up a strange design and extend it for new requirements.

Trashing working code is often a rookie mistake and just a sign of unwillingness to understand the reasons for the state of things. But thinking a rewrite keeps you from understanding the domain while making anything better code is making up an expensive illusion. There’s no such thing as a “purely technical” rewrite, because that would mean zero improvement for the deliverable (Meaning: a project you should be fired for).