The Right Tool for the Job

1 March, 2001

Lately I've been noticing a recurring theme: "The right tool for the job". I moved last month, and during the move I had some useful tools packed away in the truck. You never realize how much better a drill is versus a screwdriver until you try to hang blinds into old wood with about fifty layers of paint. My ladder was also packed, and standing on a milk crate just doesn't work as well. So I decided to give up on the blinds and wait until we got unpacked. What a difference having the right tools made! Between the ladder and the drill, I had all of the blinds up in two rooms in the the same time it took to put up two sets without the proper tools.

Software is the same way. You have to select the right tools for the job. For example, nobody in their right mind would program device drivers in, say, Tcl or Python; C, C++ or Assembly would be much more appropriate. You might also think that nobody would really want to produce a UI-intensive application in C or Perl when something like Python or Tcl makes the job much easier. But we do it all the time, which forces us to constantly reinvent the wheel. The study of physics wouldn't have gotten anywhere without standing on the shoulders of giants. Computer science and software engineering are the same way. We have to leverage the work of those that came before us.

Don't misunderstand the previous paragraph: there's nothing bad about writing a UI in C. Some rather nice products have been produced this way. But I think that some of the best examples have managed to leverage existing libraries to produce their product. How much useful work can you get done when you have to recreate that which has been done many times over?

A case in point: embedded operating systems. Hundreds have probably been written over the years. A company I used to work for put about two man-years into developing an in-house OS because it would have been " too expensive" to acquire a commericially available OS. (No free OS was ever under consideration.) After two years, we were able to convince management to discontinue maintaining the in-house OS and to purchase a widely-used commercial product. We immediately saved one to three man-months by removing two incredibly painful, nagging, intermittent bugs (by nature of their not being present in the new OS). And we saved even more time because we didn't have to add features like an IP stack, I/O system, console shell commands, etc. to the in-house OS. Further, we were able to debug our applications much more effectively because the commercial OS was integrated with a host debugger. Not to mention that the guy who wrote over 95% of the in-house OS left the company... after the only other person who had looked at that codebase had already left.

As I just hinted about, using the right tools for the job often allows you to interoperate with other suitable tools. Something as simple as using a standard, well understood language will allow you to hire people that are highly skilled at using that language. Other benefits come from having access to tools such as compilers, debuggers, code profilers, code generators, code to documentation converters, etc. If you doubt this fact, try starting a medium to large development effort using a somewhat obscure language like Dylan, Eiffel, or Ratfor. You will have difficulty finding developers, you will not be able to find a long list of vendors for your toolchain, and several of the tools listed above might not even be available. Your project will be doomed from the start! A more widely-used language like C, C++, Java, or even Python, Tcl or PHP will get you much further.

Apart from standards, suitability is the other half of using the right tool. I recently rebuilt portions of my PC to upgrade the CPU and motherboard, and install a new case fan. I managed to get it all to work (standards again!), except for the case fan. The case fan works ok, all that really takes is plugging in a wire. The problem is that I don't have the right kind of screw to mount it to the case. A quick dig through the junk drawer reveals all sizes and types of screws, but none that are truly what I need. So I tried to rig the fan in place with a couple of (mismatched) screws that looked long enough. Unfortunately I couldn't find any nuts to lock the fan in place, so it just dangled precariously inside the case in front of the vents. I've got it disconnected now, until I get a free moment to run into the hardware store to pick up a more suitable set of nuts and bolts.

Suitability is necessary when writing software, too. It is painful to even think about writing application software without heap-allocated memory. But in some embedded systems, you have to think twice before allocating from the heap. This is because issues like running out of heap space and memory fragmentation require serious consideration in the embedded world. These issues need to be addressed during the design phase -- at the latest. Sometimes these need to be addressed during the architectural or even requirements phases. Not deciding what tools are the right tools until late in the game results in lost time, frustration, and late projects. Not to mention the costs associated with possibly buying the wrong tools and having to replace them with the right tools, and necessary (re-)training when the right tools arrive.

So next time, before you start a job, take some time to think, rummage around your toolbox (or toolshed!), and lay out the tools you'll need for the job. If you realize that you don't have everything that you're going to need, I suggest running down to your local hardware store to pick up whatever it is you're going to need halfway through the project.