Back in my introduction to debugging, I observed that debugging often causes enormous frustration:
No other development activity frustrates so frequently or consistently (difficult debugging sessions often elicit loud swearing from even otherwise soft-spoken developers).
While I’m not a perfect Stoic debugger nowadays, I’ve improved a great deal since I started programming. During my freshman year of college, I realized that if I was going to spend years of my life working on computers, I was going to have to figure out how to get less angry while fixing them or I was going to have a needlessly stressful life. In my opinion, here is by far the most important lesson to learn to avoid needless stress while debugging: it’s probably your fault.
That might not sound comforting, but it actually is. Here’s why.
Complaints and control
I like complaining about things I can control but don’t.
my high-school physics teacher
In this lovely piece of self-deprecation, my physics teacher implies that we complain about two types of things: things we do control and things we don’t control. Things we don’t control are easy to identify and common sources of complaints: the weather, tax rates, strangers being jerks to us. While it’s probably not healthy to complain too much about anything, complaints of this type at least make sense. They don’t accomplish anything, but they might make us feel better. And whether we do or don’t complain, the weather tomorrow will behave precisely the same and there’s nothing at all we can do about it.
But we also complain about things we do control: we got wet because we didn’t bring an umbrella to work and it rained, there’s no food left in the refrigerator, we don’t have any time left to complete an important task. Complaining about things we do control not only annoys us further but also limits our ability to improve matters going forward.
Now you’d be right to argue that our choices leading up to the subject of the complaint may be a reasonable and defensible immediate reaction to things beyond our control: maybe there’s no food left in the refrigerator because we got dragged into working a 60-hour week or someone in our family is in the hospital, and we didn’t have time to get groceries. But even when they are reasonable, this kind of complaining is still dangerous because it hides the source of the problem. The refrigerator doesn’t control whether it’s empty: it’s up to us to replenish it. Maybe we failed to replenish it as a result of circumstances beyond our control, but if that’s the case, those circumstances should be the focus of our negative attention, not the result we don’t like. This way of thinking helps us figure out how we might be able to act differently to avoid a recurrence in the future. Maybe we can manage our work differently to avoid cramming all the overtime into one week when we already needed groceries. Maybe we need to keep a bit more food around for these unexpected situations. Or maybe we realize we’re just grateful our family member is doing well, we won’t mind dealing with this again, and it doesn’t matter that we’re out of food.
Blaming the computer
When debugging, many programmers seem to carry a tacit assumption that their code is right. Of course, this doesn’t make any sense; if the code was right, there wouldn’t be bugs in it and they wouldn’t be debugging it. And I’m sure if you stopped an average programmer while she was debugging and asked if her code was currently correct, she would tell you “no,” or at least “probably not.” But this assumption perfectly explains the reaction recalcitrant code gets from programmers. Take this outburst by my college roommate one night:
4 + 4 is not equal to 7, it’s [expletive] 8!!
Was his computer actually asserting that four plus four equals seven? Surely not – if its basic arithmetic operations were that faulty, it could not have even booted. Similarly, beginning programmers often get upset at syntax errors. Is it possible the compiler has a bug that has made it believe some valid code has a syntax error? Sure – but unless we’re using a new programming language we’ve just developed ourselves, the odds are about a million to one that our code does in fact have a syntax error. It’s hard to imagine that not only the designers of the language but all its previous users haven’t found such a basic issue. And you can bet that any such issues that do slip through will be corrected in short order, given the amount of frustration they’re liable to cause!
Obviously, my roommate’s problem ended up involving an issue in his own code, in which it incorrectly performed some operation other than 4 + 4 leading to the result of 7, and once he figured it out, he fixed it. That’s the nice thing: if the problem is with your code, you can fix it, just as soon as you stop believing that your code is right. If you start with the attitude that you’re going to prove the computer is doing the wrong thing, you’re not only mistaken, it’s almost certainly going to take you much longer to find the bug: you’re not trying to find it, you’re trying to prove it’s not there! That means you’ll likely read right over it when you come to it (see semantic errors, and for a useful way to get around this mental block talking to ducks).
It’s not the computer’s fault, it’s your fault. Accepting this basic truth at the start yields both faster solutions and lower stress levels.
Once in a long while, it really isn’t your fault. Sometimes code literally doesn’t work because of the weather (say, a network error caused by line noise, or even a complete outage). Sometimes a service you’re requesting data from sends back data its documentation says it never can. We can end up taking this mentality too far and start blaming ourselves for everything. The key is to reflect on all the outcomes you don’t like (the program doesn’t work, the refrigerator is empty) and seriously consider where responsibility lies and what you can do to improve those outcomes, if anything. And keep in mind those can be different: something can be not your responsibility even as you have the power to improve it. This should not be about blame or fault but about opportunities for improvement (see also blameless postmortems). It wouldn’t be my fault if someone broke into my house and stole my laptop, but I can and should limit the chance of that by locking my door.
So next time you’re tempted to complain about something, ask yourself: is it me? You may be empowered as well as humbled by the perhaps too-obvious answer.