Learning to live with failure
This week I've been talking with a number of students in my cloud computing course who all have a similar bug. They are making network requests to a REST API endpoint, and instead of getting back the expected JSON result, they get an error about the JSON parser not being able to parse a string that begins with <!-- <!doc...
. They keep pasting this error, wanting me to share their offence at its existence; but all I see is software doing what software always does, and ask them, "why is it happening? what is sending that HTML?"
One of the biggest challenges with teaching people how to program is that most people think about computer programs from a user's perspective vs. a developer's. Let's define the difference like this:
- user: someone who spends most of their time using working programs
- developer: someone who spends most of their time using failing programs
When I'm writing software, I'm spending the majority of my time with a program that doesn't (yet) work. If I'm lucky enough to finish it (whatever that means) and ship something, I'm basically done: a program ceases to be interesting to me once it's working. Obviously I'll return to fix more bugs down the road, but in so doing, I'll re-enter this same phase of "working with a failing program."
A user of this same program I've just shipped will encounter it as a tool: something invisible in the process of getting work done. If (or when) it ever fails, the program suddenly becomes visible again, and it needs to go back to the programmer to fix.
Using programs and developing programs require different ways of working. Once you understand this, it's very hard to not always be programming; that is, at this stage of my career, I can't really use software anymore without also finding, filing, and fixing bugs. Meanwhile, my current open source students are telling me that they can't find any bugs in their partner's code!
But back to the process of learning how to do this. When you're starting out, the tendency to treat software you write as a program you'd use is strong, and it causes one to overlook lots of things. It's easy to focus on "it doesn't work" vs. "here is what it is doing," which I've written about before.
Programming is fundamentally about being OK with programs not working. It's the default way that we encounter code, and contrary to what you might think, "working code" is something of an exception. All code is broken, or never worked, and learning to dwell in that knowledge and discomfort means that you'll get closer to the real work of programming.
You need to know that you don't suck, but your code does. So does mine. All code does. It's all part of the process.