What To Tidy

In The Life Changing Magic of Tidying Up Code, I described a piecemeal, daily approach to code hygiene. Code is going to get messy. There is no shame in that. Seeing code as messy is a sign that you have learned something. Tidying is doing a little something about messy code.

TLCMOTUC describes the tidying process: make things a little better, stay safe, celebrate progress. What I didn’t describe there is what to tidy. Here are some tidyings:

Names

Names and meaning can drift apart over time. The vocabulary used by a team evolves. Yesterday’s words may not be today’s words.

Tidy names one at a time. Make things a little easier for the next reader. You will have time to tidy that other name later.

Conditionals

Conditional logic tidies nicely. You would like the reader to look at a condition and understand immediately what is going on. Some uses of conditionals obscure the programmers’ intent.

One way conditionals go wrong is when they conceal the simple case. Turn this:

if (condition) {
 …many lines…
} else {
 …one line…
}

into:

if (!condition) {
 …one line…
} else {
 … many lines…
}

(You get bonus points if the condition was already negated and you can remove the negation.)

A conditional ought to say, “There are two possible paths of computation here.” Sometimes, however, the programmers want to say, “Here is a precondition. If it isn’t met, then this computation isn’t valid/necessary.” For example, a value needn’t be computed if it is cached.

if (cache) {
 return cache;
} else {
 …compute the cached value…
 return cache;
}

This snippet of code doesn’t really have two equally balanced alternatives, it has a precondition and then a computation. Tidy up to use a Guard Clause instead.

if (cache) return cache;
…compute cached value…
return cache;

The next reader will thank you.

Finally, sometimes what the programmers meant was “compute a value one of two ways”, not “follow one of these two paths of execution”. Tidy up this:

if (condition) {
 temp := …something…
} else {
 temp := …something else…
}

To use the ternary operator:

temp := condition
 ? …something…
 : …something else…

Redundancy

As code evolves, locally-optimized programming decisions can leave messes where there is a shorter, clearer alternative. Tidy up by fixing these spots one at a time. Replace “if (flag == true)” with “if (flag)” (assuming your programming language supports this). Replace “collection.size == 0” with “collection.isEmpty”.

The idea with this tidying is to find a dominating way of expressing a bit of computation. The tidy way of speaking is just shorter, clearer, and in all ways better.

A more extreme example is when exception handling is used where return values would work just fine. Don’t use a bigger stick than necessary.

Extraction

Expressions can start simple and then grow. At each step it is easier to add to the expression than to factor out parts. That’s where tidying comes in.

Tidy expressions by extracting parts and giving the temporary variable a suggestive name. Turn this:

return new Point(…long expression to compute x…, …long expression to compute y, which is interesting for different reasons than x…)

into:

x := expression to compute x;
y := expression to compute y;
return new Point(x, y);

When tidying it is perfectly okay to extract a single Explaining Variable and commit. There will be time to tidy the rest of the expression later.

Extracting a routine can also be tidying. All humane IDEs now have support for automatically extracting functions. When tidying, feel free to extract a function and commit. There will be time to call your new helper function later.

A more ambitious (perhaps I should say “courageous”) tidying is extracting a Method Object. See (link) for details. Method Objects often enable dramatic subsequent cleanup, but if you’re tidying, just extracting the new object and invoking it is plenty of work for one commit.

Reordering

The last tidying is to order the elements in a file in the order a reader would like to encounter them. Depending on your reader, you might put all the helpers first and the main logic flows at the end or you might have the main flow first and the helpers after.

input() {
 …stuff…
}
process() {
 …stuff…
}
output() {
 …stuff…
}
main() {
 input()
 process()
 output()
}

or:

main() {
 input()
 process()
 output()
}
input() {
 …stuff…
}
process() {
 …stuff…
}
output() {
 …stuff…
}

As you are reordering you may see the possibility for other tidyings. Those will have to wait for the next diff. Get the reordering done and out there and then tidy some more.

Enough

I surprised myself while writing this essay. I kept saying, “Keep tidying diffs small, because there will be time for more tidying later.” That attitude that there will be plenty of time later is the polar opposite of what I usually here. “We have to clean up now because we will never have another chance.”

I invite you to turn your inner dialog around. How would you behave if you had enough time? Try that for a while. Perhaps the additional energy, creativity, and tidiness will enable you to get more done, not less. How cool would that be?

However, tidying is not a substitute for adding new logic to a program. It is a productive fidget spinner. When you know what you want to write, then write it. Tidy later.

Later will come.