Fairly often I find myself writing complex boolean expressions. For example, let’s say I’m writing a function in a controller that renders a page, and I want to check whether the current user is authorized to view that page. Here’s some code:
if ((!($a || $b)) && $c != $d) || !$e) {
// Do something.
}
Aside from the variable names, that’s real code. There are two things about that code that to me greatly hinder readability. I rewrote it as essentially the following:
if ($x != $y || !$z || !$w) {
// Do something.
}
The second code has two advantages. First, no internal parentheses are needed, and second, there’s no mixture of “and” and “or”. Whenever I can, I like to use only one boolean operator in a complex boolean expression, because sorting out different operators can be confusing. In the second example, I know that if any of the expressions evaluates as true, then the code in the block will be invoked. When you mix operators, things aren’t so straightforward. And not requiring parentheses is related. When you mix operators, precedence comes into play, and you can use parentheses to manage precedence. So as soon as you bring either of them to the party, you can no longer read your expressions from right to left.
This just occurred to me so there’s probably something I’m missing, but for the time being, I’m going to try to be disciplined about sticking to one boolean operator at a time in cases like this. (And yes, I’m not counting the “nots”.)
Mike Hoye digs into the history of zero-indexed arrays in Citation Needed. Fantastic walk through the history of computing, and a fun reminder of how comfortable it is to leave our beliefs unexamined.