A significant portion of a programmer’s time is spent reading code, not writing it. I mean, most of my time isn’t spent typing, so even though I advocate for learning touch typing skills, I don’t think it is 100% a necessary skill. Useful, yes; necessary, no. I mean, most of my time is spent thinking about a particular problem I’m trying to solve with the code — whether that problem is a bug I’m trying to fix, or a feature I’m trying to implement.

And a chunk of think-time is, by necessity, spent reading code. That means, for instance, looking at existing implementations of functionality to understand how to slot in the new functionality you need to implement, or reading how particular tests are written to understand the scenarios being exercised and how they relate to the bug you’re trying to fix.

We’ve all been told to “write readable code” — but what does that mean, really? When talking about prose and the written word, there’s an objective way to assess readability, such as through such measures as the Flesh-Kincaid readability tests. I’m not sure the industry at-large has ever converged on a similar model or test, although I’ve seen some research in that direction (like this one).

In fact, a lot of advice online about writing readable code does correlate strongly with my experience and what I intuit to be “readable code”, so maybe there’s some signal there?

What do I think is “readable code” then?

First and foremost, I think, is coding style. Although arguably a bike shed topic, coding style is an important consideration when reading code. To be honest, it doesn’t matter to me which style you’re using, just pick one and adhere to it consistently throughout the project. Of course, unless you code in a language like Python or Go, where there’s more or less just a single coding style – then, of course, just stick to the one naturally used by the language and don’t invent new styles just to be different. I cannot stress how annoying it is to read source that is in such a disarray from being written in a patchwork of coding styles.

A significant chunk of my career so far has been writing code in Python and Java, so I’m familiar with the styles in those languages; admittedly, early on, I didn’t really think it was such a big deal, and I’ve written a lot of code in my own style, instead of conforming to the style of the project at large, or more importantly using a coding style common across other projects.

In Java, I prefer using the Sun Java style, with the caveat that I also prefer spaces over tabs – no mixing of the two. We can debate all day about spaces versus tabs some other time: if you prefer tabs over spaces, that’s fine too: just as long as everything is consistent.

Of course in Python, PEP 8 is king, and I don’t think that’s a controversial position, to be honest.

Once your team has agreed on a coding style, everything else starts to become a little more iffy, a little more subjective. Again: agree with your team what the parameters are. I agree with the usual prescriptions on using descriptive variable names and other identifiers, or short function and method bodies: those aren’t too controversial in my opinion.

I also think that, even if we live in a time of high-resolution displays and graphical interfaces, wrapping source code at 80 (or maybe 100) columns is a must, for the same reason that newspaper columns are readable: it makes it easier to physically read through the text.

It’s also possible to write concise yet expressive code, but it’s arguably only readable if the reader of the code understands some of the more advanced (some may even argue esoteric) features of the language that might be used. In Java 8, for instance, lambda expressions were added to the language, as well as more functional interfaces and APIs such as the collection streams API. I’ve had the opportunity to use that in a project recently, and to be honest, I debate whether this:

    return transactions.stream()
        .map(t -> t.getValue())
        .reduce((a, b) -> a.add(b))
		.orElse(BigDecimal.ZERO);

is more readable than this:

    BigDecimal total = BigDecimal.ZERO;
    for (Transaction t: transactions) {
        total = total.add(t.getValue());
    }
    return total;

or this:

    BigDecimal total = BigDecimal.ZERO;
    for (int i = 0; i < transactions.size(); i++) {
        Transaction t = transactions.get(i);
        total = total.add(t.getValue());
    }
    return total;

A reader would need to understand a) the streams API, and b) lambda expressions to get the former snippet of code, while any junior developer would probably understand the latter two snippets. However, I’d think that the first bit is more concise, and given the earlier caveat, expresses exactly the intent of the code, instead of the mechanics of the intent – the why and not the how per se.

In the same way that you have to calibrate your writing to your audience for it to be readable, choosing vocabulary that is apt for the task and audience at hand, I think it’s also important to do the same with code. You wouldn’t necessarily need to write an entire technical paper in the language and style of Dr Seuss, as that would be unwieldy (to say the least). Similarly, there may be certain parts of the software you are writing that demand you use certain more advanced features of the language: akin to using jargon and technical language, it expresses the idea a little easier, at the cost, maybe, of some readability. When used sparingly, I think such conciseness is warranted.

At the end of the day though, the whole point of readable anything is getting an idea across: if you can’t express something in prose or code, and have your audience understand you, then you’ve failed.

And remember, in the case of source code, your audience may be your own future self.

Previously: Cringeworthy