Never Send a Human To Do a Robot's Job

In my article Software Development Considered Harmful, I talked about a number of mistakes that are often made by developers who should know better. I’d like to expand on one of them here.

Never send a human to do a robot’s job.

A lot of the code we have to write to make programs run on modern platforms is code that can be more effectively generated by programs than by a human. This is particularly true of things like XML files or other structured data. Let me put it simply: if you’re editing a file that contains structured data by hand, you’re making a mistake. You’re editing the Info.plist in a Macintosh application bundle by hand using vi? You’re making a mistake. Editing your DNS/BIND zone info files by hand? You’re making a mistake. Creating RSS feeds by hand? You’re making a mistake.

I’m overstating the case a little, of course, but not by much. I generally see this sort of mistake made by two classes of people. The first are sysadmins who don’t have access to adequate tools and don’t have the desire or ability to learn how to write them themselves. I mostly sympathize with these folks, whose only option is basically “hope someone else writes a tool that does what I need.” (When I was in this position, it motivated me to learn to program, but I understand that not everyone wants or needs to learn a new skill.)

The second group of people I have less patience with: developers who somehow have gotten the idea that it’s more impressive to start a fire by banging two rocks together than by using a match. These are people who know that tools exist to do what they are doing, who know that the tools will do a better job than them, more consistently, at generating provably correct output, but who still dive in anyway because they don’t want to bother learning a new tool.

You see this a lot with developers who want to write an app for Mac OS X who have come from a pure Unix background. Yes, OS X is BSD under the covers. Yes, there’s a shell prompt. Yes, it is conceivable that you can write an application that requires the user to install (non-framework) shared libraries and wants to create .rc files and acts like a Unix app, and doesn’t require you to build an Xcode project, or use the Property List editor to create a property list. But just because something is conceivable doesn’t mean it’s a good idea. Xcode (or Codewarrior, or some IDE that has robots to do the drudge work for you) is the correct solution. If you start writing shell scripts and makefiles to solve a problem that was solved long ago by someone else, you’re screwing up.

There is no other side to this coin: if you reject superior tools because of some misplaced Slashdot-begotten “artisan” ethos, you are saying that you think it is more important to work on boring, stupid problems that other people have already solved than it is to work on something important. How many bugs lingered on in Linux because of Linus’s completely irrational and wrongheaded belief that using a kernel debugger means you’re less of a man? (Or the belief that a number of developers who worked on Linux’s old TCP stacks had that memory copies are effectively free; but that’s the subject of a rant for another time.) There are other examples, of course, but suffice it to say that this isn’t a theoretical concern. I see developers trying to end- run around Apple’s admittedly ugly and clumsy IDE and toolset (or, on the Windows side, Visual C++) all the time. It always causes more pain than it saves.

We all like to gripe about users being dumb, but in some ways users are extremely smart. In particular, many users grew up watching Sesame Street. They are extremely good at playing “which one of these is not like the other? Which one of these does not belong?” Every platform has its own natural development environment. The more you, as a developer, diverge from that development environment, the more likely your app is going to feel “different” from other applications on that platform. If you’re writing an app for an X windows environment, where everything being inconsistent and utterly broken is the norm, that’s not such a big deal. If you’re writing an app for the Windows or Mac OS environments, where users expect applications to look and behave in a consistent way, it’s the kiss of death.

There’s a corollary to this discussion, which is that some of the best use of a developer’s time is spent writing code to generate code. I love generated code, because when I find and fix a bug in the code generator, I’ve really fixed every possible instantiation of that bug in one fell swoop. And often, debugging generated code is easier than debugging handrolled code, because you tend to have the same bug in many places, which usually makes it easier to reproduce.

It’s fine to eschew the use of sophisticated tools for personal projects because you want to know what’s going on under the hood. But if you’re going to give that car to someone else to drive, be a responsible mechanic, and use the best tools you have available.

Let the robots write the boring code, so that you can focus on the problems that really need your intellect.