Way back in the good ole days when I went to college to learn programming, one of the things I was taught was to program defensively. I was to check for error returns (remember, this was before exception handling became the rule, not the, um, exception) and try to deal with them appropriately. When your code is full of error checking, it is, naturally, longer; it’s also harder to read, in my opinion.
But like I said, it was a long time ago. I learned on BASIC when you had to use line numbers, and then I learned Pascal and FORTRAN and PL/1 (the first on Apple IIe hardware, the other two on an IBM mainframe running MUSIC of all things). Meanwhile, I took a part-time job programming a Xenix system, and while the main work was in a proprietary system called Profile 16, I took the opportunity to learn K&R C.
Perhaps it was C where I learned my bad habits. You see sample code in books bereft of error handling (since it’s much clearer to leave it out if it’s not actually needed for the example) and you start writing code like that. At least, I did. I mostly checked for error returns on file opening, since that’s when it seemed most likely to be needed. But my code worked, at least, after I got the obvious bugs out. Fortunately for me, very little of that code is still in service anywhere… maintaining it would be a bear.
I kind of fell out of programming for a while, as I started a business selling and servicing computers (yes, I’m a programmer AND a technician). When I finally accepted some work, it was in Visual Basic (well, VBA actually), and I fell back into my old bad habits.
But it was different, this time. VBA gave me useful error messages when my program failed, even going so far as to drop me into the debugger. I trained my users to make appropriate notes if an error message came up, and then I went back and either fixed the code or added the appropriate error handling. Later I had the joy (that’s not sarcasm, it really was joy) of learning Python, and again, useful error messages; in Python, it turned out to be very easy to log the errors for later review, which is wonderful.
Lately, I’ve noticed how much more productive this “bad” habit has turned out to be. My users are all pretty happy, as far as I can tell anyway, and in two cases I’ve had nice compliments from outsiders who have experienced these programs. Oh, they aren’t sexy or anything… just programs that do work that needs doing.
I’m calling my method offensive programming. I charge into the code and create, well, whatever is needed, and except for the most obvious cases, I don’t bother trying to figure out what might go wrong in advance. Instead, I deal with the problems when they arise.
More to the point, I’ve come to the conclusion that, unless you’re designing really critical things (air traffic control software, medical software, etc.), defensive programming is insane. Your goal is to figure out what might go wrong before it ever does, and then deal with it in advance. But programs (and the computers they run on) have more failure modes than anything else humanity has ever created. Trying to anticipate them all is a waste of time, as far as I’m concerned, unless of course your software holds human lives in its virtual hands.