Sunday, April 6, 2008

The Absurdity of "Don't Reinvent the Wheel"

As developers, we've had this adage drilled into us from the beginning: Don't reinvent the wheel. In short, don't rewrite what's already been written. The idea is sound, in theory. You can save yourself time and money if you'll simply reuse existing code and/or components rather than writing them yourself from scratch. This time and money is saved up front when you write it (or would have written it), and down the road, when you have to maintain your system.

However, I'd like to point out another, equally applicable adage: There's nothing new under the sun. Anyone who's ever tried to write a novel, a short story, a play, a movie, a song, or a piece of software, will know this one simple truth: somewhere, at some point in time, it's already been written.

Every algorithm, every piece of code that we will ever attempt to write has already been written somewhere, at some point in time, by someone. Only the names have been changed. You're not inventing anything that is completely new, that's never been seen before. You should wisely disabuse yourself of that notion as quickly as possible.

In the grand scheme of things, at the application level, you may very well have an idea for a system that is unlike anything that has been done to date. But the algorithms that drive it have already been written. Bubble sorts, hashes, exception handlers, encryption, data access, socket management, shopping carts, entire application frameworks, date management, document management, serialization, port I/O, and all that other stuff has already been done. Further, it's already been done several times over in many different languages to varying degrees of success.

Tragically, if you're using a large application framework, like Java's EE or Microsoft's .NET, the chances are good that the functionality you're looking for is built right into the framework itself. The problem is that the framework is so vast that you'll spend more time looking for it, and determining whether or not it works the way you need it to work than you would just rewriting it yourself.

Application frameworks are stunningly afflicted with feature creep. They must do everything under the sun, must meet every possible need. The problem, then, is that their scope becomes so broad, so vast, that no one in their right mind could possibly grasp the totality of all that they can do. It is inevitable that anyone using them will reinvent some of their functionality. The scale of that functionality might be small (reformatting dates) or it might be substantial (pooled database connections).

In the end, it's absurd to think that we can possibly avoid reinventing the wheel. Of course we're going to reinvent it. Every application we write is a reinvention of someone else's wheel. It just so happens that our wheel is a custom wheel. All this paranoia about reinventing the wheel is blown out of proportion. A proper buy vs. build decision should never be neglected; but don't ever think for one minute that what you're creating hasn't been created before.

Consider the scenario where you're under the gun to get a product out the door. And I mean it's a really tight schedule. And don't act like it's a perfect world, and you have leverage over the schedule. This is reality here. In the real world, the customer controls the schedule, because it's tied to when the product is released, and that's tied to this big, huge monstrosity in another state or another country. The product's delivery schedule is a train barreling down the track at 120mph and no one short of God can stop it. Now, you have a very finite amount of time to work in. You need an algorithm. You know you could write it. Or you could look to see if someone else has written it.

If you do the whole Web search thing, you have to ask yourself a few questions: Is it from a source you trust? Is it in the language you're using, or do you have to convert it? Does it work? Does it need to be tweaked? If any of these fail, you're back to the drawing board. Time's wasting here, and that train's getting closer to its destination. If all the answers pass, you have to make sure you don't run into any copyright or licensing issues with that code. (You are paying attention to that, aren't you?)

If you decide to peruse your application's framework, you'd better hope it's well documented, and very easy to search. Good luck using the search features in .NET. It's not like the ASK.COM interface, where you can ask, "How do I convert a date in DOD format to Gregorian format?" Yeah. Good luck with that. On the other hand, you could ask your coworkers. They might know. Then again, they might not. If they don't, you're off to Google to get the information. Here's hoping you get a timely and accurate response.

Sure, this is an extreme example. But it makes my point: At some point, the work has to get done. You can't afford to spend days or weeks scratching your head about whether or not that wheel's already been invented. Believe me, it has. The problem is, there are a countless number of wheels, and none of them are labeled, and you don't know where to find the wheel you're looking for.

Stop wasting time, and invent your own damned wheel.

After all, whatever code you might reuse, is just someone else's reinvention of the same wheel.

2 comments:

Anonymous said...

I agree that for trivial problems (eg drawing a picture on a GUI), it's faster and easier to code one's own solution from scratch than to both find and learn to use the pre-existing "PrettyPicture.NET", or whatever such things are called.

However, I think you'll agree that for non-trivial problems, it goes the other way.

For example, are you prepared to claim that one can implement a conditionally HTTP 1.1 compliant Web server in less time than it takes one to install and learn to use Apache? I doubt it. Or how about Linux - have you written many operating system kernels lately?

You also make what I hope is a mistake: you list the costs of NOT reinventing the wheel as both finding, and also learning how to use, other peoples' pre-existing solutions.

This is unfair/misleading: programmers have a 'toolbox' of re-usable techniques. We pay the 'finding the existing wheel' cost only once, and we climb the learning curve only once; but we deploy the solution we've learnt how to use (and which is superior to anything we could have made alone) every time the same problem rears its head. Over time this pays dividends.

By contrast, re-inventing the same wheel multiple times doesn't radically reduce the duration of any single given wheel-reinvention task.

You're right that time to market is very important; but too-great a concentration on this can cause crippling time costs down the road as one is forced to rewrite unmaintainable reinvented wheels.

There's rarely a day goes by in which I do not discover a non-working re-invention of a wheel by a half-wit long gone, which wheel naturally came out triangular. It breaks my heart when I have to delete the cruft and just start again. The other day it was a home-made PDF parser using Perl and the UNIX 'strings' utility. Feh. It just wasn't fixable; that's just not the way to do that. If the author hadn't have tried to do it himself, he wouldn't have done it wrongly.

So *you're* one of the people who cause this type of mess. Ha! Found ya.

I truly hope you get rich, running your software company, with its incredibly low times to market.

But I hope I never have to use any software you've written, nor work with you, nor have to work on any system which you've touched. You're dangerous.

You sound like you're pretty early on in your career. Your attitude may change over time. I reckon you should keep your post here, to compare it with your later ideas.

Olivier said...

How could you NOT get a *timely* response using Google? :)
Just kidding.
Excellent blog! Please keep rants coming!!