Here’s a simple tip! I can’t begin to count how many potential code bugs this has eliminated. It takes some getting used to but once you make it automatic it’s a real help in keeping code and your thinking correct.
The tip is this: when you write relational expressions, always use less-than, never use greater-than. (Less-than-or-equal is okay, too.)
In other words, always write B < A
, not A > B
.
Make Less Not More
Write your relational expressions to use less-than and so that a true evaluation puts the lesser quantities on the left of the greater quantities. In rare cases a language doesn’t allow the appropriate syntax, but in most cases you can write the less-than version of any expression. This is especially important when testing a value range (for example, between ‘A’ and ‘Z’).
By the way, I admit to assuming the Euro-American left-to-right bias here. In cultures with strong right-to-left orientation, I hope my logic works in mirror reverse. The point is to use instinctive mathematical less-to-greater orientation in relational expressions to help avoid logic errors.
The intent is to apply the left-to-right orientation of the number line to relational expressions. On the (Euro-American) number line, values run from lesser on the left to greater on the right. If you pick a number, L, from the line and pick another number, R, to the right of it, the relation (L < R) is always true and (L > R) is always false.
If the expression logic follows number-line logic, the expression logic makes more sense. For example, if we want to test that x is in the [A–Z] range, one way to write the expression is:
(‘A’ <= x) AND (x <= ‘Z’)
The test value, x, visually falls between the ‘A’ and the ‘Z’. In this form, the expression resembles a common mathematical form:
(‘A’ <= x <= ‘Z’)
Most computer languages do not allow the above syntax, but nearly all allow the first one, which comes very close. Compare this to a common alternative, that places the variable first:
(x >= ‘A’) AND (x <= ‘Z’)
In a complex expression, following mathematical number-line logic can make an expression more clear and help highlight logical errors. For example, consider this (not atypical code):
((‘A’ <= x) AND (x <= ‘Z’)) OR ((‘a’ <= x) AND (x <= ‘z’)) OR ((’0' <= x) AND (x <= ’9'))
And compare it to this:
((x >= ‘A’) AND (x <= ‘Z’)) OR ((x <= ‘a’) AND (x <= ‘z’)) OR ((x >= ’0') AND (x <= ’9'))
I think it’s easier to use the first one. In fact, did you spot the error in the second version? The first version is easier to debug, because you know all the arrows have to point to the left.
Note that this follows the standard looping conventions:
{J=0; J < N; next J} {J=1; J <= N; next J}
It takes a while to train yourself to use less-than strictly, but once you do, your coding skills will be stronger. After a few months, it becomes natural. You may even find yourself going back and “correcting” old code. It will start to look “wrong” to you!
Color me interested. I do like the consistency, and most ordered collections I am familiar with require a less-than operator (but not a greater-than operator). I think it makes sense to keep smaller things on the left.
The only reason I cannot jump 100% on board overnight is the fact that not every expression is so “mathematical” in nature.
if (cost > 0) { … }
The emphasis here is on cost, not on whether it is greater or less than something else.
if (0 < cost) { … }
I'm sure I could eventually get used to patterns like this, but it stings at first. I think this pattern is best when used in ranges as you demonstrated in your post.
Yes, I agree; using this to test whether a thing is greater than zero does sting at first (and to be honest in some ways still feels vaguely weird). A common place I hit that is:
Although many languages do allow:
Which doesn’t sting at all.
No doubt you can argue this two ways, depending on your inner coder. Absolutely consistency saves you from those times you’re not fully paying attention. Absolute consistency dulls the mind and is boring. I went with absolute consistency in order to train myself to use less-than, but at this point having done so I can relax the reins. Especially when an exception improves clarity, which I consider the Prime Directive.
(Also: Welcome! You’re the first person to comment here.)
There are not enough code blogs (particularly these more philosophical/theoretical types) in the world. =]
I’m hoping the reason for that doesn’t turn out to be, “Because nobody reads them!” 🙂