How to think better about code and be more effective
Carl Masak describes a way to mass-produce “anti-confusion particles”, bringing more clarity into the process of reporting bugs, unit testing, or tracking down surprising behaviors in code.
Just like bad hair days, we sometimes have bad programming days. And sometimes good ones. I know that some days I’m unfit to work even on a simple script, and other days I’m happily hacking on the innards of some compiler or other. Our skills don’t just fall on a single point on some skill spectrum. We fall within a bell curve.
And we have precious little ability to tell for ourselves when we’re being smart, and when we’re being stupid. See, part of the reason ignorance is bliss is that we’re usually not aware we’re having a Homer moment. We’re so confused that we don’t even notice that we’re confused.
The times when I do mess up, I’m usually really grateful that I wrote unit tests. Conversely, the times I mess up and didn’t write unit tests, I usually curse the hubris and laziness that led me down that path. I sincerely believe that I don’t write buggier code just because I’m using unit tests. The number of bugs going in is probably about the same, but the number of bugs discovered right away is larger with the tests. Which makes me go “d’oh!”, and fix the code. But every such “d’oh!” is one fewer “aaargh” in production, so it’s not so bad.
Though tests are only a small part of the thing I wanted to write about today: a systematic way to improve our worst performance as programmers.
Every good bug report needs three things
I’m on an open-source project with an active issue tracker, a test suite, and an actively developed implementation. (It’s a Perl 6 compiler.) I’ve submitted over a thousand issues by now, and I’m at the point where the whole process of submitting an issue for something has lost the charm of novelty, and I’m just formatting the thing in as short a time as possible. However, I’ve learned from Joel Spolsky long ago that every good bug report needs exactly three things:
- Steps to reproduce,
- What you expected, and
- What you got instead.
Since we’re all living in the future nowadays, we have tools to make this easier. On our IRC channel, there are bots that run code for us in all of the big implementations. They reply on-channel with the output, and include pertinent build revision numbers. Which covers 1 and 3 above. The ensuing discussion usually covers 2; otherwise I add some clarification. But the upside is this: bug reports basically write themselves. Nine times out of ten, they consist of a few lines of (heavily trimmed) IRC conversation between humans and bots.
I’m proud to be called a bot sometimes myself on the channel. (Only 52 times, according to the IRC logs.) I make it a thing to submit as many issues as I see, because the process is painless and semi-automatic to me by now. I can do something useful even when I’m having a bad programming day. The whole thing has led me to believe that we should make more parts of the coding experience painless and semi-automatic, because it makes us more effective.
The Anti-Confusion Particle
But we’re our own worst enemy. We’re programmers; we like complexity; we live for it and tackle it every day. And the times when the complexity conquers us, we’re often to absorbed in the problem to realize that we’ve lost.
In the surprisingly well-written fanfic Harry Potter and the Methods of Rationality, the first step to regain touch with reality and start thinking clearly again consists of saying out loud:
I notice that I am confused.
That’s all. You’ve broken the spell of confusion. You’re free, and can do something about it.
The thing we do is simple. We describe what we find confusing. We do this as succinctly as possible. We do it using three things:
- What did I do,
- What did I expect, and
- What did I get.
Look familiar? Why, it’s the same triple as with bug reports! And with good reason: if a program or a system goes against our expectations, that’s confusing. It’s also a potential bug report. In a way, we can get rid of our confusion by submitting a mental bug report to ourselves.
I call this triplet the “anti-confusion particle”. It’s like an element from the periodic table, which catalyzes a reaction with your confusion and helps turn it into understanding. It has three quarks.
A natural part of getting the anti-confusion particle to work well is to remove all the cruft. Get it to have as few moving parts as possible. Throw away bits of code, all the while trying to retain the surprising element. In our community, we’ve started calling this “golfing the code”; the practice being named after the recreational activity sometimes seen in Perl 5 circles, of writing programs with as few characters as possible. The shorter you get your code, the clearer the unexpected thing will be.
Unit tests fit nicely into this kind of thinking. A unit test consists of quarks 1 and 2 (do and expect), and your testing framework runs all the tests and spits out anti-confusion particles at you.
When confusion goes away
Sometimes, in programming help channels on IRC, I’ve seen newcomers enter and pityingly utter “I tried this and that, but it didn’t work!”. (And the fact that they omit the expect part is a sign that they’re too confused to know they’re confused.) A regular on the channel will approach them, and say “tell us what you did, what you expected to happen, and what actually happened”, providing the newcomer with the recipe to figure out stuff yourself.
You know what the eventual reply usually is?
“Thanks, it works now!”
You see, what usually happens — what in a sense must happen — with confusion is that it eventually resolves itself. We just have to make sure we have the tools and vehicles to arrive at the resolution as quickly as possible. The anti-confusion particle is the first such tool we use.
What follows next is usually popping the hood of the system, following code flows and connections, and basically playing digital doctor. This process can take seconds, hours, or days. It may be trivial, or it may be oh-my-complexity-class NP-hard. But at that point, we’re well on our way to understanding the problem.
We’re un-stuck. The spell of the Homer moment is removed. We can be productive again.
Carl Mäsak has a passion for software and software process. He works as an architect and programming mentor at Edument. He likes to work on healing systems in need of an architecture, or to help introduce order into a chaotic domain. In his spare time, he likes riding a bike, cooking good food, and writing music. Not necessarily all three at the same time.
Through Informator, Edument offers courses in testing, Git, CQRS and Event sourcing, C#, Perl, testing, and web security. All our courses are delivered by our passionate and experienced coworkers. Check them out.
Entry filed under: Uncategorized. Tags: .