Tuesday, August 21, 2007

Rewriting Software

Ovid is wondering about rewrite projects. It’s a frequent topic in software, and there’s no one answer that fits all situations.

One of the clearest opinions is from Joel Spolsky, who says rewrites are “the single worst strategic mistake that any software company can make”. His essay is seven years old, and in it, he takes Netscape to task for open sourcing Mozilla, and immediately throwing all the code away and rewriting it from scratch. Joel was right, and for a few years Mozilla was a festering wasteland of nothingness, wrapped up in abstractions, with an unhealthy dose of gratuitous complexity sprinkled on top. But this is open source, and open source projects have a habit of over-estimating the short term and under-estimating the long term. Adam Wiggins revisited the big Mozilla rewrite issue earlier this year when he said:

[W]hat Joel called a huge mistake turned into Firefox, which is the best thing that ever happened to the web, maybe even the best thing that’s ever happened to software in general. Some “mistake.”

What’s missing from the discussion is an idea from Brian Eno about the differences between the “small here” vs. the “big here”, and the “short now” vs. the “long now”. Capsule summary: we can either live in a “small here” (a great apartment in a crappy part of town) or a “big here” (a beautiful city in a great location with perfect weather and amazing vistas), and we can live in a “short now” (my deadline is my life) or a “long now” (how does this project change the company, the industry or the planet?).

On the one hand, Joel’s logic is irrefutable. If you’re dealing with a small here and a short now, then there is no time to rewrite software. There are revenue goals to meet, and time spent redoing work is retrograde, and in nearly every case poses a risk to the bottom line because it doesn’t deliver end user value in a timely fashion.

On the other hand, Joel’s logic has got more holes in it than a fishing net. If you’re dealing with a big here and a long now, whatever work you do right now is completely inconsequential compared to where the project will be five years from today or five million users from now. Requirements change, platforms go away, and yesterday’s baggage has negative value — it leads to hard-to-diagnose bugs in obscure edge cases everyone has forgotten about. The best way to deal with this code is to rewrite, refactor or remove it.

Joel Spolsky is arguing that the Great Mozilla rewrite was a horrible decision in the short term, while Adam Wiggins is arguing that the same project was a wild success in the long term. Note that these positions do not contradict each other. Clearly, there is no one rule that fits all situations.

The key to estimating whether a rewrite project is likely to succeed is to first understand when it needs to succeed. If it will be evaluated in the short term (because the team lives in a small here and a short now), then a rewrite project is quite likely to fail horribly. On the other hand, if the rewrite will be evaluated in the long term (because the team lives in a big here and a long now), then a large rewrite project just might succeed and be a healthy move for the project.

Finally, there’s the “right here” and “right now” kind of project. Ovid talks about them briefly:

If something is a tiny project, refactoring is often trivial and if you want to do a rewrite, so be it.

In my experience, there are plenty of small projects discussed in meetings where the number of man hours discussing a change or rewrite far exceeds the amount of time to perform the work, often by a factor of ten or more. Here, the answer is clear — just do the work, keep a back up for when you screw up, and forget the dogma about rewriting code. If it was a mistake, rolling back the change will also take less time than the post mortem discussion.

Ovid raises another interesting point: large projects start out from smaller ones, so if it’s OK to rewrite small projects, and small projects slowly turn into large projects, when does it become unwise to rewrite a project?

The answer here isn’t to extrapolate based on project size, but rather on the horizon. A quick little hack that slowly morphs into something like MS Word will eventually become rewrite-averse due to short term pressures. A quick little hack that slowly morphs into something like Firefox will remain somewhat malleable, so long as it can take a long time to succeed.

9 comments:

Anonymous
said...

Well if I read "rewrite" then I mostly think of the idea rewriting some software in another language. Especially from "non-mainstream" languages to mainstream languages and for that I can not see any good reason. And I also can not see any good reason to rewrite a working software just because one can. But what I has especially about rewrite is that you simply can forget the old software, you can run that software with the old libraries but if there are bugs you are "alone" you are forced to update your software just because the library developes just do not find backware compatibility worthwhile...

The problem with any rewrites is the SSS ;-)(second system syndrom) which you can find in the literature as one of the most dangerous things for programmers.

That means: While you have learned so much during development you write your second version with a lot of new things and most of the time fail miserably.

However I also have seen that software really does age. And what happens is that constraints under which once software was written have vanished. But the software still uses "old tricks". So it's seems some sort or rewriting must take place to keep the software running.

Tell anyone who owned stock in Netscape that a rewrite was a good idea. Just because firefox eventually turned out well doesn't mean that it was better or faster than working with the existing codebase would have been. We arguably could have had firefox two years earlier and have 50% of the browser market now if there wasn't a rewrite.

The choice here is not simply a binary decision of whether or not to rewrite. In most cases there is a 3rd way: incremental evolution. Evolution from Netscape to Firefox would still produce Firefox in all its glory, without seceding the browser market to IE.

Joel says as much in the later part of the article. The lesson I take away is not "don't rewrite", but "don't rewrite all at once."

Tell anyone who owned stock in Netscape that a rewrite was a good idea.

That's precisely the point. Viewed in the short term (the company and its shareholders), the rewrite was a waste of time and money because it produced no (short term) value. Viewed in the long term (the project, the web, etc.), the rewrite was worthwhile, because it produced lasting value (for the web, eventually).

You're not in a position to even begin to make that judgement. The word is that the code was a mess--a huge mess--and if code is bad enough, it takes longer to fix it than it does to start from scratch.

Consider that Netscape was first forked off Mosaic code back when there was no CSS and the layout engine was extremely simplistic (no tables for crying out loud). There's no credible reason to second guess Netscape's management. IE ate their lunch because it was bundled--what would stringing people along with a few more bassackwards releases of Netscape 4 have done? It doesn't seem likely that they could have gotten CSS support anywhere near IE5-level.

Paid software versus free software, that's a huge part of the difference. In paid software, you usually have competitors and it's the competitors who are driving much of the need for a rewrite (OMG, we can't compete! They're so much better than we are that we have better rewrite this!). If they stall to long on whatever they're doing, the competition will have 'em for breakfast.

Free software projects, on the other hand, often have either less competition or are less worried about it. They're usually open-source and if the main project languishes, others often come in to pick up the slack while the rewrite is being finished. Financial pressure is what so much of this is about.

Now if only programmers could swallow their ego and forgo useless rewrites ...

i dont like arguments based on one example, once someone felt from 3rd floor and he wasnt even hurt, so that means that jumping from 3rd floor is not dangerous.

i think rewrite is always a bad idea, many bugs were found and fixed, not just trivial bugs. maybe there is alot of hacks, but hacks can be refactored too.

Latly i was working to extend my old home-grown project and it was really bad, but now after alot of refactoring i think its beautiful. I did re-write parts that really were terrible, but if i have to do the whole thing again it would took me alot of time and finally i would give up.

However is program is trivial you can always try to re-write it, but if its not than i think you shouldnt.

I believe Firefox being open source makes the difference. It's not as if you got paid to work on the Firefox project (at least not in the beginning).Developing concepts, trying new things, writing your code from scratch - that is fun and rewarding.Maintaining thousands of lines of crappy code, fixing bugs you didn't put in, working with concepts you find appalling and aged - that is no fun. You got to be paid to do that. Firefox would have not worked if Netscape just open sourced their crappy code and everyone had been forced to work with that. Programmers interesting in browser technology would have just flocked to other project or started their own. Maybe we'd seen a great windows version of Konquerer instead.Working with legacy code is no fun, you cannot force open source developers to do that. Throwing away the old code base was the only way to end up with a great browser, because it had to be inspiring, interesting and motivating to work on the code.