The Art of Readable Code: Takeaways

Cesar Aguirre - Jan 11 '22 - - Dev Community

I originally posted an extended version of this post on my blog a couple of weeks ago.

The Art of Readable Code is the perfect companion for the Clean Code. It contains simple and practical tips to improve your code at the function level. It isn't as dogmatic and strict as Clean Code. But, it still deserves to be read.

These are some of my notes from the chapter "Surface-level improvements."

1. Package info into names

If it something is critical to understand, put it in a name

Choose specific words for your method names. For example, does def GetPage(url) get the page from the network, a cache or a database? Use FetchPage(url) or DownloadPage(url) instead.

Avoid empty names like retval, tmp, foo. Instead, use a variable name that describes the value. In the next code sample, use sum_squares instead of retval.

function norm(v) {
    var retval = 0;
    for (var i = 0; i < v.length; i++) {
        retval += v[i] *v [i]; // Prefer, sum_squares = v[i] * v[i];
    }
    return retval;
}
Enter fullscreen mode Exit fullscreen mode

Variables i, j, k don't always work for loop indices. Prefer more concrete names. Indices could be misused or interchanged.

Use concrete over abstract names. Instead of --run-locally, use --extra-logging or --use-local-database.

Attach extra information to your names. For example, encode units. Prefer delay_secs over delay. Also, encode extra information. Prefer plaintext_password over password.

Do not include needless words in your names. Instead of ConvertToString, use ToString.

2. Write Names that can't be misconstructed

Make your names resistant to misinterpretation

Does a method on arrays named filter() pick or get rid of elements? If it picks elements, use select(). And, if it gets rid of elements, use exclude().

// Does results have elements that satisfy the condition?
// Or elements that don't?
results = Database.all_objects.filter("year <= 2011")
Enter fullscreen mode Exit fullscreen mode

Use Min and Max for inclusive limits. Put "min" or "max" in front of the thing being limited. For example,

if shopping_cart.num_items() > MAX_ITEMS_IN_CART:
    Error()
Enter fullscreen mode Exit fullscreen mode

Use First and Last for inclusive limits. What's the result of print integer_range(start=2, stop=4)? Is it [2,3] or [2,3,4]? Prefer, print integer_range(first=2, last=4) to mean [2,3,4].

For booleans variables, make clear what true or false means. Use is, has, can, should, need as prefixes. For example, SpaceLeft() or HasSpaceLeft().

Avoid negated booleans. For example, instead of disable_ssl = false, use use_ssl = true.

Don't create false expectation. With these two names GetSize() and ComputeSize(), we expect GetSize() to be a lightweight operation.

What name would you put in that sign? Photo by Austin Kirk on Unsplash

3. Aesthetics

Similar code should look similar. Pick a meaningful order and maintain it. If the code mentions A, B, and C, don't say B, C, and A in other places.

For example, don't do,

details = request.POST.get('details')
location = request.POST.get('location')
phone = request.POST.get('phone')

if phone: rec.phone = phone
if location: rec.location = location
if details: rec.details = details
Enter fullscreen mode Exit fullscreen mode

4. Know what to comment

Good Code > Bad Code + Comments

Don't comment what can be derived from code.

Comment the why's behind a decision. Anticipate likely questions and comment the big picture. Comment why you choose a particular value or what it's a valid range. For example,

public const int MAX_THREADS = 8; // Up to 2*num of procs
Enter fullscreen mode Exit fullscreen mode

5. Make comments precise and compact

Use comments to show examples of input and output values.

// Strip("ab", "a") == "b"
String Strip(String str, String chars)
Enter fullscreen mode Exit fullscreen mode
// CategoryType -> (score, weight)
typdef hash_map<int, pair<float, float>>
Enter fullscreen mode Exit fullscreen mode

Use named parameters or use comments to make the same effect. Prefer connect(timeout: 10, use_ssl: false) over connect(10, false).

In languages without named parameters, use comments to emulate named parameters. Like this,

connect(/*timeout_ms=*/10, /*use_ssl=*/false)
Enter fullscreen mode Exit fullscreen mode

Voilà! Writing compact and descriptive names is a recurring tip when writing clean/readable code. The Art of Readable Code is a good starting point to introduce the concept of readability and clean code to your team. Give it a try! I found it easier to read than the Clean Code. Both of them are complimentary reads.


Hey, there! I'm Cesar, a software engineer and lifelong learner. Visit my Gumroad page to download my ebooks and check my courses.

Happy reading!

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .