I’m a terrible programmer. You would think that having done this for nearly 25 years that I should be pretty good at it by now. But nope, I still put bugs in my code, use the wrong types for variables or subprogram arguments, forget to make the right library calls, mess up the expression in an if statement, and on and on and on now for 25 years.
Sometimes the code won’t compile, and I can fix those bugs right away, but the rest of the time I have to actually run the program to be made aware of my failings. If I’m “lucky”, the program will start up and then crash in a blaze of error message glory that I can then pick through and use to figure out what I did wrong. If I’m not so lucky, the program will start and then almost immediately exit (assuming that wasn’t what it was supposed to do), or go off into la-la land, neither doing what it’s supposed to do, nor exiting. Or worse, look like it’s working just fine, and only when I’ve worked my way to some corner of the program’s functionality will something go subtly awry—occasionally so subtly that it’s not even noticed for awhile. Then of course there’s the non-deterministic bugs that manifest themselves only when a sequence of events (which may originate externally to my program) occurs in a particular order over a particular set of time intervals. The program may run right 999 times out of 1000, but that 1000th run may lock up the entire system. (Been there, done that, found the vendor library’s bug.)
The odd thing though about the programs I design and write is that once they’re delivered to the customer or as a baseline release they usually work like they’re supposed to, which would seem to be surprising given that such a terrible programmer wrote them. I mean I usually deliver the system on time, with the required functionality, and with very few bugs.
So what’s my secret?
Well, it’s one of these pseudo-Zen made-up Ancient Software Master’s secrets:
You will never become a Great Programmer until you acknowledge that you will always be a Terrible Programmer.
And as you saw in the very first sentence, I fully concede that I am a terrible programmer. So since I love programming and this is my chosen career, I have to deal with it.
Fortunately there’s a lot of ways I can cover up the fact that I’m a terrible programmer:
1) If I get to pick the programming language for a particular program, my “go to” language is Ada. Yeah, I know it’s pretty much unheard of today outside of the defense industry, and even there it's struggling, but it has few peers when it comes to pointing out to a terrible programmer just how bad they really are. With all the language’s typing and run-time checks, it’s little wonder that programmers didn’t like Ada, since it was constantly pointing out bugs in their code!
If I can’t use Ada, well, then Java is the next best choice, since it’s got a lot of the same built-in bug detection capabilities.
But please, please don’t make me use C++ any more, which is definitely the enabler of terrible programmer egos. It lets most everything through, so a) I feel good about getting my code clean compiled and “done”, and b) I get a huge ego boost after the Jolt-fueled marathon debugging session that's needed to successfully get the program mostly working.
2) I use programming assertions, a lot. If some variable should never be null, I assert that it’s not null, even if Grady Booch has sworn on a stack of UML standards that it will never be null. Here’s how paranoid I am about being found out: even when I control both sides of an interface, I’ll assert the validity of what the data provider is providing, and assert what the receiver is receiving. Why? Because I’ve been known to change one side of an interface and forgotten to alter the other, so the assertions catch those for me right away.
3) Be a testing masochist, i.e., I ruthlessly try to break my own code. No programmer likes doing this, we’re usually happy to just get the damn thing running the way it’s supposed to with the test case data, so why go looking for trouble? I admit that it’s a mental challenge to intentionally attempt to break one’s own code, but if I don’t, somebody else will, and my secret terrible programmer identity would be revealed.
4) Have other programmers inspect my code. Despite everything I do, as a terrible programmer there’s still going to be bugs in my code. So I need other programmers, especially other Great Programmers, to look at my code and find those bugs. And I’m serious about these inspections, I don’t want some cursory glance that simply makes sure I’ve included the right file header information, I want an inspection, dammit! I had to pound on one of my inspectors once because he was “doing me a favor” by not recording all the defects he found, because he didn’t want me to “feel bad”. Look, I have no self-image as a programmer, so “feeling bad” isn’t something I get hung up on. I need to end up with Great Code, so as a Terrible Programmer I need all the help I can get!
With these and other terrible-programmer-obfuscating techniques, my code often does come out looking like it was written by a great programmer. And I’ve done well by those techniques over the years, during my career I’ve had the opportunity to work on the real-time executive and aero data analysis for flight simulations, did a clean sheet redesign of a major defense system’s command and control planning system, taken sole responsibility for rehosting a large command and control system, done data mining and event correlation in an XML framework for another large defense system, and replaced a legacy wargaming operator console with a net-centric ready version. Outside of my day job I write open source software (in Ada!) and some of it has been picked up and used by a company supporting the European Space Agency. (I’m goin’ to the moon! Helping, anyway.)
So I’ve been successful in hiding the fact that I’m a terrible programmer up to this point, and I need to make sure that I can continue in this career path until my retirement. Heeding Han Solo’s admonition ("Great kid, don't get cocky."), we come to the second fake Zen Old Software Master italicized aphorism:
You will remain a Great Programmer for only as long as you acknowledge that you are still a Terrible Programmer.
Over the years I’ve learned more ways to hide my programming failings. One technique: let the program crash—This works, just stay with me. I’d joined a development project where the original developers had so many problems with run-time exceptions that they simply starting including “null exception handlers”, i.e., catch all unexpected exceptions, suppress them, and keep on going. Needless to say, the system would run fine for awhile, sometimes hours, and then slowly start to...hmm..."veer off".
When I got the chance to redesign the system, one thing I immediately forbade was those null exception handlers (though handlers for recognized exceptional conditions were permitted). If an exception occurred, I wanted it to propagate up until it took the application down so that we would know about it and could fix it right then and there. I got my wish, but was almost found out in the process. The program manager got wind that we were seeing a lot of system crashes during testing, and he wanted to know why the redesigned system was crashing so much more often than the one it was replacing. Explaining that we were uncovering errors and getting them fixed now, and fixed right, didn’t really give him the warm fuzzy he was looking for, as there were deadlines approaching and the reported error rate wasn’t declining as fast as he liked. The team stuck with this practice, though, and when we were done (on time and on budget) the system ran reliably and correctly for days under both light and heavy loads.
For me, this cemented my self-image as a terrible programmer. If I could bring this kind of a system to fruition, meeting all its requirements and budget and schedule constraints, just by conscientiously applying a slew of techniques for uncovering my programming failings before they got into the final product, then I knew that I would be able to fake it for the rest of my career.
Now if you look at my code you might find it to be pretty bad, and that’s normal, pretty much any programmer that looks at almost any other programmer’s code will judge it to be a pile of offal and then proclaim that the only way to fix it is to rewrite it. (I wonder why this is?)
But if you want to sit down with me and go over my code, and tell me what’s wrong with it, then I think we can work together to fix those problems and make it truly great code. And who knows, maybe you’ll end up being as terrible a programmer as I am.