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.

Related

25 Responses

really interesting post. makes me want to download a bunch of open source stuff over the weekend and start reading through it. 🙂

> 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

especially liked this bit. i feel like i read code all the time (from other programmers, of course ;)) that achieves the desired effect, but does it in the “wrong” way. i’m not talking about stylistic differences here — using a for loop on indexes to iterate over an array as opposed to a for: loop in Java, for example — but rather code that speaks to the compiler and not other programmers. i like the way you said it, and i think i’m going to steal it in future conversations. 😀

I just wanted to say that I dig your blog. You have a good tone, and you write very clearly. I imagine as a result of coding. I’m a programmer starting out. I just read Code Complete and the Pragmatic Programmer and I’m looking around for more resources for a beginner. Your observations are totally helpful.

Thanks 😀 It sounds like you’ve found some great places to start; I could recommend reading all of Joel’s old essays – he’s got a bunch of ‘reading lists’ on the front page these days that probably cover his best stuff. Equally, Paul Graham’s essays. Good luck and have a great time!

Yea this is pretty much what I was taught when I started work (I’d only ever worked in FORTRAN and C++ on code that only I (and barely even I) would read again in Physics Undergrad,) and it was so weird at first to have a set of rules about code and (shock horror) reviews…

…but it paid off. The skill you describe is invaluable when you are at a company who do random service and support work on products which we only wrote ourselves some of the time (!! 🙂 )

I totally agree on getting into the habit of reading code, but reading reviews can be more fun and/or useful, and being in a team where your code really has to explain itself to pass review (large comments above every public method, smaller but significant ones on private ones, very few comments in actual code because, according to clean code principals your methods and objects should be named so the code speaks for itself, etc) really beats the lot.

Good post, it just seems weird to me that there are people who don’t do this already! 🙂

I’m a Programmer Analyst college student, and have been working at a placement job as an “web/application” developer for the past year. And since I’ve been here, I have struggled with what my problem is. I can write lots of great stuff on my own from scratch, but 90% of my work is bug fixes I don’t understand, and enhancements that break everything around it.

You definitely hit the nail on the head with this one. I’m inspired to read as much open source code I can get my hands on.

Heh, this made me sit up and pay attention:
/* Hairy buffering mechanism for grep. The intent is to keep
all reads aligned on a page boundary and multiples of the
page size, unless a read yields a partial page. */

[…] a great blog post from Hacker News. Two really, but both are from the same blog. The first is “On the Fear of Reading Code” which is a spot on description to how I first began my coding career. Everyone has to go through […]

Excellent post, thanks. You, however, don’t fully address the problem of reading the code vs maintaining it having read and (somewhat) understood it.

In my experience, I’ve found that code written by novice programmers (either those who are just getting started and learning how to program, or those who have been around for a while but have no taste/appreciation for or interest in such things as elegance, simplicity and readability, clean and clear logic, etc) is not only hard to understand but hard to fix and maintain. If such code is running fine already, we could live with it no matter how ‘bad’ it is. But usually, this inelegant and difficult-to-read code is also (coincidence?) severely ridden with (end-user reported) problems. What do you do in such a case?

Now, you may disagree with it, but I’ve found that once I know I’ll be the maintainer/owner of a piece of code for a while **AND** my manager/end-users will be willing to put up with my learning curve on this code somewhat (which means, I may accidentally break something else sometimes (due to lack of unit tests and even thorough feature documentation sometimes!)), it’s best in terms of overall productivity to rewrite that piece of sh!t again. This is sometimes so important to me, to my peace of mind, that I would even work long and extra hours… unpaid!

Obviously, this is not what I would (or, one should) do **ALWAYS**. I guess, a case-by-case decision needs to be made. It’s a judgment call, at the end of the day.

I wish I had the skill of fixing the lousiest, most obfuscated code in the world with just the bare minimum changes. Unfortunately, I don’t. Pray for me, if you can.

Yes, there will sometimes be code that, perhaps, the intern – or manager – wrote yesterday that’s completely wrong and just needs rewriting. This post is about code that’s already been used, maintained. It’s about grown-up code rather than newborn code.

We’ve got to be very careful though, because the tendency is always to rewrite, even when it’s not justified.

When I talk about not rewriting code, I don’t mean not refactoring! Old code should be grokked and then refactored; the problem is most of the time we want to skip the understanding part and simply start writing what we think it ought to do from scratch.

To answer your question, once I’ve gone to the effort to understand a particularly torturous bit of code, it’s usually easy to see how to clear it up and make it simpler and more elegant without breaking it.

It’s like Ender: you’ve got to know a piece of code so deeply that you see it with perfect love before you can destroy it utterly 😉

Excellent blog — went through many posts. I’d follow you on Twitter to catch up with your posts — you could set up an account to update automatically from your RSS (there are services that do this). Thanks!

[…] 看到这段话，来自这里： 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. […]