Aug 13, 2013
The trouble with 'readability'

We programmers love to talk about the value of readability in software. But all our rhetoric, even if it were practiced with diligence, suffers from a giant blind spot.

Exhibit A

Here's Douglas Crockford on programming style. For the first half he explains why readability is important: because our brains do far more subconsciously than we tend to realize. The anecdotes are interesting and the presentation is engaging, but the premise is basically preaching to the choir. Of course I want my code to be readable. Sensei, show me how!

But when he gets to ‘how’, here is what we get: good names, comments and consistent indentation. Wait, what?! After all that discussion about how complex programs are, and how hard to understand, do we really expect to make a dent on global complexity with a few blunt, local rules? Does something not seem off?

Exhibit B

Here's a paean to the software quality of Doom 3. It starts out with this utterly promising ideal:

Local code should explain, or at least hint at, the overall system design.

Unfortunately we never hear about the 'overall system design' ever again. Instead we get.. good names, comments and indentation, culminating in the author's ideal of beauty:

The two biggest things, for me at least, are stylistic indenting and maximum const-ness.

I think the fundamental reasons for the quality of Doom 3 have been missed. Observing superficial small-scale features will only take you so far in appreciating the large-scale beauty of a program.

Exhibit C

Kernighan and Pike's classic Practice of Programming takes mostly the code writer's part. For reading you're left again with guidelines in the small: names, comments and indentation.


I could go on and on. Everytime the discussion turns to readability we skip almost unconsciously to style guides and whatnot. Local rules for a fundamentally global problem.

This blind spot is baked into the very phrase ‘readable code’. ‘Code’ isn't an amorphous thing that you manage by the pound. You can't make software clean simply by making all the ‘code’ in it more clean. What we really ought to be thinking about is readable programs. Functions aren't readable in isolation, at least not in the most important way. The biggest aid to a function's readability is to convey where it fits in the larger program.

Nowhere is this more apparent than with names. All the above articles and more emphasize the value of names. But they all focus on naming conventions and rules of thumb to evaluate the quality of a single name in isolation. In practice, a series of locally well-chosen names gradually end up in overall cacophony. A program with a small harmonious vocabulary of names consistently used is hugely effective regardless of whether its types and variables are visibly distinguished. To put it another way, the readability of a program can be hugely enhanced by the names it doesn't use.

Part of the problem is that talking about local features is easy. It's easy to teach the difference between a good name and a bad name. Once taught, the reader has the satisfaction of going off to judge names all around him. It's far harder to show a globally coherent design without losing the reader.

Simple superficial rules can be applied to any program, but to learn from a well-designed program we must focus on what's unique to it, and not easily transferred to other programs in disparate domains. That again increases the odds of losing the reader.

But the largest problem is that we programmers are often looking at the world from a parochial perspective: “I built this awesome program, I understand everything about it, and people keep bugging me to accept their crappy changes.” Style guides and conventions are basically tools for the insiders of a software project. If you already understand the global picture it makes sense to focus on the local irritations. But you won't be around forever. Eventually one of these newcomers will take charge of this project, and they'll make a mess if you didn't talk to them enough about the big picture.

Lots of thought has gone into the small-scale best practices to help maintainers merge changes from others, but there's been no attempt at learning to communicate large-scale organization to newcomers. Perhaps this is a different skill entirely; if so, it needs a different name than ‘readability’.


  • Mark Ruzon, 2013-08-14: Communicating the meaning of large amounts of code can't be done in the code itself. It requires thorough documentation that has to be kept up to date as pieces change. There is no substitute for discipline and diligence.

    And I'm very parochial when it comes to my code. I admit it. To me the art and/or science of programming is as important as producing a great result.   

    • Kartik Agaram, 2013-08-14: "I'm very parochial when it comes to my code. I admit it. To me the art and/or science of programming is as important as producing a great result."

      Hmm, perhaps I came off harsher than I intended. Caring about the art of programming isn't parochial. It's what I'm doing here as well, I hope.

      I meant that it's counter-productive to focus on the creator's role and ignore that of future contributors. Surely the science of programming should care about the entire life cycle of a codebase rather than just who happens to be running the show at the moment?   

    • Kartik Agaram, 2013-08-14: "There is no substitute for discipline and diligence."

      I'm not trying to replace discipline and diligence (hence my use of the word at the start of the article). I'm arguing that we've been aiming for the wrong (incomplete) goal all along. Perhaps this explains why our results are so abysmal regardless of how hard we try.

  • Anonymous, 2013-08-31: I like the "readable programs not code" focus. But can we do even better? Computers are interactive. Why can't we ask useful questions about our programs, and get useful explanations? Why can't we obtain information about how a function is actually used? Why can't we animate its execution and how it touches objects or globals?

    I wonder if conversational programming or live programming might offer a better basis for understanding our code.

    But we may also need to simplify our languages. Use of callbacks, call/cc, shared state, etc. don't do much to enhance grokkability of our programs.   

    • Kartik Agaram, 2013-08-31: Thanks David! The solution I've been working on does indeed use interactivity. I hope to post it in the next couple of days.

      I fear, though, that you will be disappointed by my direction. I don't know how to automate the visualization of arbitrary programs like Bret Victor wants; the high-level concepts they need to operate with seem always to be quite domain-specific. So my approach is a baby step compared to RDP.   

      • Anonymous, 2021-03-17: How can I see your solution?
  • Kartik Agaram, 2014-06-17: "Ironically, the aspect of writing that gets the most attention is the one that is least important to good style, and that is the rules of correct usage. Can you split an infinitive? Can you use the so-called fused participle? There are literally (yes, "literally") hundreds of traditional usage issues like these, and many are worth following. But many are not, and in general they are not the first things to concentrate on when we think about how to improve writing. The first thing to do in writing well—before worrying about split infinitives—is what kind of situation you imagine yourself to be in. What are you simulating when you write? That stance is the main thing that distinguishes clear vigorous writing from the mush we see in academese and medicalese and bureaucratese and corporatese." -- Steven Pinker,   
  • Kartik Agaram, 2016-09-19: Richard Gabriel puts it better than I ever could:

Comments gratefully appreciated. Please send them to me by any method of your choice and I'll include them here.

RSS (?)
twtxt (?)
Station (?)