Software development is often seen as a "man vs machine" endeavour. In reality, it's still people who do the work, a work that often has a clear artistic component. It is work we do with others, for others. And here are some of my thoughts on that

Sunday, June 12, 2011

We've all been there. Faced with lines and lines of code, written by an intern, a programmer long gone, or a vendor with whom you do not have a support contract.

Code can be quite hard to read. Why is that?

Without looking at the language or frameworks used, some of which are easier to read than others, there are other, more human factors that make it had to puzzle out what code does. I'm not talking about how the code was written, but how we attempt to read it.

1. Reading code usually involves two actions: identifying what the code does, and what it was actually meant to do.

When we approach code, it's rarely because we're just curious; we usually want to fix bugs or improve it. We must know what the code does, but for the structure and implementation of the code to make sense, we have to figure out what the programmer intended to do. It's usually easier to figure out the intent first, then work out the discrepancies - where we think the code doesn't do what it was meant to.

This can be particularly hard when we have to look at code that was edited multiple times, by multiple people with different approaches. Then, it's more of an archeological expedition. That's the situation that can lead to some pretty ugly or silly code. I remember looking at code once that, I can only imagine, was the product of too many edits:

if (someCondition == true) {
myVar = false;
} else {
myVar = false;
}

2. We're talking too loud, and not listening enough

When we see code like the one above, we laugh, we point, and our opinion of the code (and the programmer(s)) goes down. We start generalizing and thinking the worse. How can code with that in it be any good? And what were they thinking? who would wrote such poor code?

And that's when we start losing faith in the code. Our disdain takes over, and our ears close. We see some odd code, and instead of genuinely asking "what were they trying to do here?", we throw our hands in the air and sigh, "what were they trying to do here!"

If you want to understand the code, you must listen to what the previous programmers were trying to say. Withhold judgement, open your eyes, your mind, and assume they were trying to accomplish something. They may even have something to teach you about how to solve problems, about the business, or about the history of the code.

3. It's not written how we think

If you've ever written in perl, (and even if you haven't) you know that there's more than one way to accomplish a task. Sometimes, it's a simple syntax tweak, but sometimes it's a whole approach. For example, if I were to put an apple and an orange on the table and ask you to describe what you see, would you start with "I see two fruits" or "there's an apple and an orange"? Depending on your answer, chances are you approach problems differently.

The code may use programming techniques we're unfamiliar with (using functions as parameters, patterns, functional programming). Unfortunately, if we're unfamiliar with the technique, we're unlikely to recognize it it the wild, unless the programmer was kind enough to leave comments about it. This is where experience and breadth of knowledge will come handy. Keep up to date with developments in the field.

4. We lose track

Not all code is nicely packaged, modular and cohesive. More often than not, we start reading code in one spot, only to realize we need to find out what a function does in another file or module. We leave the code here, investigate the code there, which takes us to another module,... and by the time we get back to the original spot, we've totally forgotten what we were reading or trying to do.å

Take notes. Draw pictures. Use your IDE to find relations between code, where functions are called from. I find printing code is, unfortunately for the trees, helpful, as I then remember not only the code, but where the code is on the page; and I scribble all over the paper in various colours.

What can we do about it?

Try to find out what the programmer wanted to do

Then see if the code does it

Keep an open mind - don't let your prejudice get in the way

Learn new (to you) techniques and patterns

When you code, try to see more than one way to solve the problem; maybe next time you try to read someone's code, they'll have used your second or third choice, and you'll recognize it more easily

Try to remember code you've written, before you were perfectly fluent in a new language, or when you were too rushed to go back and fix some readability issue. Maybe there's someone reading that code now; treat the code in front of you as you would have others treat yours.

Once came across code where all the variable names were things like "Laredo", "Cowboy" etc. Fortunately the code was easy to understand. However, I was darn curious to know why the programmer had done that. Fortunately it was my college roommate. So I was able to ask him.

"Oh that day I had the song 'Streets of Laredo' running through my mind."

He then related to me one program he had written basically as a Shakespearean play where variables came into the scene, did their thing, exited and so on. The scary thing is, knowing his ability, it probably worked well.

Despite those peculiarities, he's probably still the best programmer I've met.

Don't like the reference to intern code as poor. I'm an intern now and consider that I write pretty legible code. It's all about the standards and styleguides that you are following. Code is read more often than it is written, especially in large companies. So it's important to write code that performs well, but reads well also. That's probably what you were saying in your post, but I skimmed over it instead of reading it, because of that 'intern' reference.

Ah, it's like that part your post: "When we see code like the one above, we laugh, we point, and our opinion of the code (and the programmer(s)) goes down. We start generalizing and thinking the worse. How can code with that in it be any good? And what were they thinking?"

The problem with the intern isn't that the code is bad, but that they are no longer around. You can't go to them ask questions about it. If you'd read the rest, I'm also pointing out that when we try to read code and find it difficult, it's often not the fault of the code or the programmer.

I think the opposite of reading code with disdain is reading it with respect, and attempting to have some faith that the respect is deserved.

Looking at that seemingly-useless code snippet, I was thinking, "Why would I leave something like that in, deliberately?". Maybe because that condition is really important, if not right now, then perhaps soon, when I have time to add some feature, or perhaps while debugging. Yes, it's inefficient, but I might be afraid to delete it and lose that knowledge of its importance, lose the "work done" that it represents. Maybe it would be worth that tradeoff...

Indeed. I think respect may be asking for a lot, depending on the code in question, particularly if it's littered with bits that make no sense at all to the reader. That's why I suggest just an open mind. If you keep an open mind, then maybe you can see that the original author had something specific in mind - future development, or coding bread-crumbs. Then you can move to respect.

Also, as you point out, if you can think of yourself has having written such code, you're less likely to be harsh in your judgement.

Actually I don't think that reading code is hard but the thing is lack of knowledge to it. If we are familiar with the basic, we will definitely catch the things. Referring to the above example, the way of writing the code is weird but still it's understable.