LeverLabs

Do not Overuse the Else Statement

written by Onne Gorter on 2015/11/16

I've been known to say that writing an else statement is like writing a bug. When I do, it usually results in funny looks and shaking heads. But I am quite serious. And I avoid else statements in my code, in favor of early returns and default values and various other techniques.

Now it is not a holy thing, and short if/else's are fine. But I just get extra suspicious when the condition is complex, or the branches long. First thing I look for, how many bits of information go into the condition.

if (a && b) { ... } else { ... }

Here the else block covers three out of four cases. Are all three cases similar? And when this code evolves into a && b && c. Are we still sure the else can deal with all 7 other cases equally? Tests staying green might be attributed to the fact that edge cases are hard to test.

Second thing I look for, how many lines of code are in either. If it is unbalanced, that is usually not a good sign. Are we sure the else statement requires less initialization or less cleanup? And when both sides tend to get long, likely some duplication creeps in, not a good sign either.

And it is easy to express such code differently. When the else statement can be broad, the code can likely be expressed using early returns or defaults. And when the blocks are unbalanced, likely we can do the same. When they share a lot of code, likely that code can be extracted as a function, with parameters controlling the difference, leading to situation number one.

This tends to lead to clearer, more linear code. More robust to changes over time.

Nodejs is only 15% Else.

Not convinced by my arguments? Check the nodejs/lib sources. How many else statements can we find. Grep tells me: 2683 if statements vs 408 else statements, that is 15% (all else if are ignored). And when we look at them. Most have single bit conditionals. And most even have only one line of code on both sides. I wish a had a better tool to analyze the usages in more details.

I really like this presentation from Avdi Grimm on this subject:

His example does not contain a single if/else statement. But he shows how to avoid this problem from a much bigger perspective. Notice how he removes all conditionals from the main code he is working on.

I'll leave you with an example of early returns of the code shown in the beginning, for those who have never seen that before:

if (a) return
if (b) return
...

And an example of default initialization:

var foo = 0
var bar = ""
if (a && b) {
    foo = ...
    bar = ...
}
use(foo, bar)
Submit to Hacker News