October 2014

Volume 29 Number 10

Cutting Edge : Source Code Readability Tips

Dino Esposito | October 2014

Dino EspositoHave you ever heard of the International Obfuscated C Code Contest? In a nutshell, it’s an open contest that selects a winner from a handful of C programs that solves a problem—any problem—with an extremely obscure and obfuscated C code. You can find the source code of winning programs in previous years at ioccc.org/years.html.

The Obfuscated C Code Contest is a lighthearted way to demonstrate the importance of style and readability in programming. This column will summarize some of the most important practices you’ll want to follow in order to have code that’s easy to read and understand—both for your own sake and that of your colleagues.

Readability as an Attribute

In software development, maintainability is the attribute that refers to the ease with which you can modify existing code to achieve goals such as fixing a bug, housekeeping, implementing a new feature or just refactoring to some patterns. Maintainability is one of the fundamental attributes of software, according to the ISO/IEC 9126 paper. For more information on software attributes, refer to the paper at bit.ly/VCpe9q.

Code maintainability results from a variety of factors, one of which is readability. Code that’s hard to read is also hard to understand. Developers who put their hands on code they don’t clearly know and understand are liable to make the code even worse.

Unfortunately, readability is an extremely subjective matter. Developing an automatic tool to check and report on the readability level of the code is virtually impossible. However, even if automatic readability measurement were possible, any such tools would likely be considered highly unreliable and wouldn’t be trusted by anybody. In the end, readability is a manual attribute that individual developers should check along with the rest of their code. The ability to write code that’s easy to read should be part of the cultural responsibility of individual developers, extending their skill set.

Generally speaking, readability is a code attribute you can and should learn to adopt right at the beginning of your programming career and develop and improve over time. Like style and good design, readability shouldn’t be reserved for experts. More important, it shouldn’t be postponed to when you just have enough time for it.

A Pragmatic Approach to Readability

Producing readable code is a matter of respect for other developers. As a StackOverflow user once posted, “you should always code as if the person who ends up maintaining your code is a violent psychopath who knows where you live.” You should also consider the developer who ends up maintaining your code, one day, might actually be you.

When reading other people’s code, there are a couple of things that can drive you crazy. One aspect that makes it difficult to read code is data structures and algorithms with no clear goals. Another aspect is unclear strategies used in code that are difficult to determine and not well notated through comments. Here’s an example:

// Find the smallest number in a list of integers
private int mininList(params int[] numbers)
  var min = Int32.MaxValue;
  for (var i = 0; i < numbers.length; i++) {
    int number = numbers[i];
    if (number < min)
      min = number;
  return min;

Even though I ported the example in C# for clarity, I have to admit that this is not a piece of code that any C# developer would ever consider writing. The reason is that with C# and the Microsoft .NET Framework, you can achieve many of the same results using LINQ. I encountered similar code in a project, except that it was written in Java. At some point, I was hired to port the codebase to the .NET Framework and C#.

You could also come across code like that in a real .NET project. You can apply some readability considerations without losing your intent. The first thing that doesn’t work in that function is the name. The convention is arguable. The name misses a verb and uses a mixed casing logic. Something like GetMinFromList would’ve probably been a better name. However, the most debatable point of the code is the private qualifier used in the name.

Any casual reader of that code can see that the function serves as a utility. In other words, it represents a potentially reusable piece of code you can call from a variety of places within the rest of the codebase. Therefore, marking it as private doesn’t always make sense. However, developers know the power of the YAGNI rule—You Ain’t Gonna Need It—and, reasonably, tend to not expose code that isn’t strictly needed.

The author of that code could’ve foreseen the function as potentially reusable, but not when it was written. That’s why that function was written to be easily turned into a reusable helper function, but was marked private to be visible only within the host class. This coding strategy might be hard to figure out immediately for external readers. However, it’s just a decision that requires a few lines of comments to explain its motivation. If you don’t add appropriate comments, you aren’t being a good citizen in the coding world. Readers ultimately make sense of it, but it wastes a few minutes and, worse yet, it makes readers somewhat hostile to the author.

Practical Rules of Readability

Code readability is one of those subjects whose importance is widely recognized, but not necessarily formalized. At the same time, without some formalization, code readability is nearly an empty concept. Overall, you can approach readability with the rule of the three C’s: a combined function of comments, consistency and clarity.

IDE tools are much smarter today than just a few years ago. Developers have no strict need to write help files and integrate their custom documentation in Visual Studio projects. Tool tips are everywhere and automatically created from comments. Modern IDEs make it so easy to define institutional comments, all you have to think of is the text and the IDE will do the rest. An institutional comment is the classic comment you add to methods and classes to provide a concise description of the goals. You should write these comments following platform or language standards. You should also consider these comments mandatory for any public piece of code you create.

Banning obvious comments is another fundamental step on the road to improved readability. Obvious comments just add noise and no relevant information. By definition, a comment is any explanatory text for any decision you make in the code that isn’t immediately obvious. A comment should only be an insightful remark about a particular aspect of the code. 

The second “C” is consistency. Every team needs to use the same guidelines for writing code. It’s even better if those guidelines are used on a company-wide basis. When it comes to guidelines, many stop at the point of defining what guidelines should be and stop trying to make sense of what’s right and what’s wrong. I dare say that wrong or right is a secondary point compared to the importance of always doing the same thing in the same way throughout your code.

Suppose for a moment you’re writing a library that does string manipulation. In several places within this library, you’ll likely need to check whether a string contains a given substring. How would you do that? In the .NET Framework, as well as the Java SDK, you have at least two ways of achieving the same result. You could use the Contains or IndexOf method. Those two methods, though, serve different purposes.

The Contains method returns a Boolean answer and just tells you whether the substring is contained within a given string. The IndexOf method returns the 0-based index where the searched string is located. If there’s no substring, IndexOf returns a -1. From a purely functional perspective, therefore, you can use Contains and IndexOf to achieve the same goals.

However, they give a different message to anyone reading the code, and forces the reader to take a second pass on the code to see if there’s a special reason to use IndexOf instead of Contains. A single second-pass reading on a line of code isn’t a problem, of course. But when it happens on an entire codebase of thousands of lines of code, it does have an impact on time and, subsequently, costs. That’s the direct cost of not having highly readable code.

A sense of code consistency should be part of your innate responsibility. As a developer, you should aim to write clean code the first time without hoping to have enough time to clean it up later. As a team leader, you should enforce code consistency guidelines through check-in policies. Ideally, you shouldn’t allow check-in of any code that doesn’t pass a consistency test.

The latest version of ReSharper can be a considerable help in making this idea concrete. You can use these free command-line tools—a standalone set of tools—to integrate forms of code-quality analysis right into your continuous integration (CI) or version control system. These command-line tools can perform offline code inspections. This is the same set of code inspections you can perform live within Visual Studio with ReSharper installed to catch duplicates in your code. Depending on your CI customization features, you might need to wrap up command-line tools in an ad hoc component. For more information on ReSharper, check out bit.ly/1avsZ2R.

The third and final “C” of code readability is clarity. Your code is clear if you style it in a way that it reads well and easily. This includes appropriate grouping and nesting. In general, IF statements add a lot of noise to the code. Sometimes you can’t avoid conditional statements—a pillar of programming languages—but trying to limit the number of IF statements keeps nesting under control and makes code easier to read. You could also use an IF… ELSE … IF … ELSE structure instead of nested IF statements.

Some tasks may require a few lines of code and it might be hard or just inappropriate to do an “Extract Method” refactoring. In this case, it’s good to keep these lines in blocks separated by blank lines. It doesn’t change the code substance, but keeps it easier to read. Finally, if you’re looking for inspiration on how to style your source code, have a look at some open source projects.

Short Is Better

Longer lines make it hard for human eyes to read. That’s why newspapers and magazines print their text in columns. When it comes to your code, you should do the same and limit both the horizontal length of lines and the vertical scrolling of the methods. What’s the ideal length of a method’s body? Generally, 30 lines should be a maximum level that triggers an alarm bell and suggests you consider refactoring. Finally, a good organization of project folders and matching between folders and namespaces often reflects a good organization of individual code elements.

When you raise the theme of readability and clean code, you’re often exposed to one common objection—writing clean code is hard and takes a lot of time. You should try to neutralize this viewpoint and there are two ways you can. One is to use a code assistant tool that helps write clean code by suggesting refactorings, inspecting your code for bad patterns, and checking for dead or duplicated code. If you can make all these features accessible, you really have no more excuses for not writing cleaner and readable code. Code assistant tools are offered from major vendors. Pick any, but pick one.

The other is to emphasize self-improvement and the attitude of your individual developers to write cleaner code as a matter of general practice. Experienced developers do this well. The ability to know roughly how far away you are from the final version of your code, and then truly clean it up, is a key characteristic that separates experienced developers from the less experienced.

Dino Esposito is the co-author of “Microsoft .NET: Architecting Applications for the Enterprise” (Microsoft Press, 2014) and “Programming ASP.NET MVC 5” (Microsoft Press, 2014). A technical evangelist for the .NET Framework and Android platforms at JetBrains and frequent speaker at industry events worldwide, Esposito shares his vision of software at software2cents.wordpress.com and on Twitter at twitter.com/despos.

Thanks to the following Microsoft technical expert for reviewing this article: James McCaffrey