Thursday, September 27, 2012

Simplify ternary operators

One of my pet peeves in Java/C/C++/C# programming is the use of the ternary operator ?: with boolean values. It's almost always redundant, makes code harder to read and can be easily replaced by a simpler boolean expression that also has the advantage of being "branch-free" in some languages, that is, do not require the CPU to select a path of execution based on a condition, which can be very expensive. The best compilers will optimize them away in a manner similar to what I describe below, but they still don't improve code readability.

From this point onward I'll be using the Java/C/C++/C# code syntax. A boolean expression is any valid expression that results in a boolean value. This may be anything from the constants true and false all the way to complex expressions such as x == 1 && (y > 3 || z <= 1.25) && !checkSomething(x, y, z) (assuming checkSomething(...) returns a boolean).

Say you have the condition c and the boolean expressions p and q. The following table contains all possible conversions from a ternary expression to an equivalent boolean expression:

#Ternary Expressionif-then-else ExpressionEquivalent to
1c ? p : qif (c) p else q(c && p) || (!c && q)
2c ? p : trueif (c) p else true!c || p
3c ? p : falseif (c) p else falsec && p
4c ? true : pif (c) true else pc || p
5c ? false : pif (c) false else p!c && p
6c ? true : falseif (c) true else falsec
7c ? false : trueif (c) false else true!c
8c ? true : trueif (c) true else truetrue
9c ? false : falseif (c) false else falsefalse

Note that #1 may or may not result in more readable code; it is probably better to use the ternary operator in that case. #6 through #9 are poor coding practices and should be replaced as soon as possible by their equivalent boolean expressions. #2 through #5 require attention and almost certainly will result in better, cleaner code.

Also note that c ? p : q is equivalent to if (c) b=p else b=q. In other words, if any boolean variables are assigned a value that depends on the condition of an if-then-else clause, then that value can be simplified according to the equivalence table above, as long as there are no unintended side-effects.

Let's try this with an example:

boolean b = i > 5 ? j == 3 : false

or, as an if-then-else clause:

boolean b;
if (i > 5) b = j == 3; else b = false;

Looking at the above table, this matches expression #3, with:

c = i > 5
p = j == 3

The equivalent expression would be:

boolean b = i > 5 && j == 3

which is slightly shorter and certainly less confusing than the above ternary or if-then-else statements.

1 comment:

  1. I never really used Ternary Expressions but you got a fair point.