On The Fear of Reading Code
As programmers, we love writing code. Opening a fresh, clean editor, bringing up a blank form in Visual Studio, the world crisp and uncluttered and ready to receive your vision. It’s easy to understand why starting a new project is fun.
However, mostly we don’t like reading code. Dropped into the middle of some densely-packed jungle of a project, filled with obfuscated filenames and cryptic little comments like:
if (section == 0) /* can’t validate section this way */
and having to fight your way through to fix a bug or add a featurette without breaking anything else. It’s a lot like going to certain modern art exhibitions; you end up feeling as if those responsible are deliberately obscuring things just to piss you off. Actually, in the programming world this is sometimes the case. It’s easy to understand why people will go to extraordinary lengths to avoid reading and understanding complicated, real-world code.
This is unfortunate, because reading code – even bad code – is the key to writing good code.
When I was learning to program someone told me that I should try to read as much code as possible. Budding genius that I was, I thought this was advice for stupid people who needed to learn from their betters. I thought the only reason to read code was to pick up tricks from it.
How wrong I was. The real reason to read code has nothing to do with learning from the programmer who wrote it.
Recently I discovered that learning a foreign language teaches you two things: how to communicate in that language and how to communicate in your own language to non-native speakers. You learn that simple grammatical structures and shorter sentences are easier to understand. You get a feeling for when someone’s following you and which words in the sentence are most important to pronounce clearly.
It’s the same with reading and writing code. Reading code teaches you how to read code and it teaches you how to write code that’s easy to read. Both of these are desperately important.
Actually reading code is something most of us subconsciously avoid. I’ve lost track of the number of times I’ve been through this little dance:
- Decide to fix a bug or add a feature to a piece of code someone else has written
- Take a brief look at said code
- Frown in distaste because the original programmer – curse his blackened soul – put the opening brace on the end of the if statement instead of on a new line, as God intended*
- Spend the next 90 seconds not being able to work out why it was put together the way it was, or what’s calling what and why
- Tell myself: “Boy, this code is a real mess! Even I can’t understand it! The best thing to do is clearly to make a clean start and write it myself – it can’t be that hard and I can always refer back if I run into problems!”
- Spend the next few hours, days or (on one memorable occasion) weeks reimplementing a slightly buggier, less complete version of the original code. I now have something that isn’t noticably better by any metric, but I feel I understand it and that lifts a weight from my heart
- “Phew”, I say, wiping my brow with the back of my hand, “it’s a good job I rewrote that!”
It’s only after years and years of repeating this pattern that it has begun to dawn on me that each time I do this I’m really just wasting precious, precious time on something that doesn’t improve the product at all. What’s worse, I’m only doing it because I can’t face the thought of reading somebody else’s code. If I spent one fraction of the time reading and understanding it then I’d learn a lot more about the problem it’s trying to solve and would be in a great place to tweak or refactor it to suit my needs.
The desire to start afresh comes from the fear of reading code, and it’s always, always a waste of time because – guess what? When you’re done, there’s just as much code to be read next time you come back to it. The right thing to do is to read it, grok it and gently massage it into a more suitable shape. Or hack it apart brutally and repurpose it. It doesn’t matter! Once you understand it, you can do what you want with it. Code doesn’t rust and it doesn’t go off. Just read it, change it and use it. Every time I do this now, it makes me happy.
Just being able to read complex code quickly and effortlessly is a wonderful aim in itself, but the real benefits come from the effect it has on your own code. When you first learn to program, you’re really learning to write code that communicates your intentions to the compiler. Initially this seems like hard work, but actually a compiler jumps through a lot of hoops to work out what your convoluted code is supposed to mean.
To become a better developer, however, you need to learn to write code that simultaneously communicates your intentions to the compiler and to other programmers, who would rather do anything than work out what you were trying to achieve.
Even when working on your own you benefit hugely by writing code that clearly communicates its intentions, because most interesting programs end up being larger than you can hold in your head at any one time and end up being worked on for more than one session.
If you think your intentions are clear, but you’re not in the habit of reading code, you’re probably wrong and they’re only clear to you (and only today). It’s when you summon up your courage and dive into the deep end of someone else’s code and try to work out what’s going on without any reference points that you start to notice what makes this easy and what makes it hard. Would a brief comment here have saved you looking things up in that other set of nested classes?
When you come back to write more code yourself, you recognise which parts might be confusing, where a helpful comment or carefully-chosen function name would clear up any potential ambiguities. You recognise that a future maintainer who comes in to change this function will need to know that it’s affected by this other class over here.
In short, you learn to see your code with the eyes of a reader, and in doing so you become better at writing it. You can work on it faster and your team can work on it faster. Everybody wins. I worked professionally for years – years – without ever really reading anyone else’s code. Once I started, I began to see the whole field in a new light. I wish I’d started reading code years ago, I really do.