I’m a strong proponent of writing if statements like this:
variable == constant
Because to me it just makes sense, it is more readable than the inverted:
constant == variable
Which seems to be used a lot by C-programmers. And I see the use, namely that the interpreter or compiler will throw an error and let you know if you’re not doing a comparison. But still it is less readable, and for that reason alone I don’t think comparisons should be written in the manner of the second example.
The actual question is:
Does it exist a general best practice for this, or is it different depending on language/religion/age/etc..?
I’m happy that so many seem to understand why you’d want to do as in the latter example, but that is not what I’m asking about.
4
The second method you list (constant == variable) is done to be safe, and to make the intent clear. That way, if you see:
if(variable = constant)
In the code, you know it was intentional and not a typo.
That said, I’ve never seen:
if(constant == variable)
In any textbook or advocated in any style guide. There are static analysis tools that can detect assignment in conditionals and throw notices or errors.
7
If you’re working in a language or environment that either warns or produces an error on variable = constant
, I would suggest sticking with the variable-on-the-left standard that you already use.
Technically, both are equivalent. I’d argue that the former better expresses how we tend to think about truth values, however. For example, taking variable == constant
and constant == variable
and replacing them with some values:
if (boolResult == True) { ... } // variable == constant
or
if (True == boolResult) { ... } // constant == variable
These are both valid comparisons, but we generally don’t think in terms of the constant value (True) as being the thing tested. It’s less obvious when using literals like 34
or "string"
but I think the concept still holds. In English, at least, we express this kind of statement where the variable, the thing to be tested, is the subject.
"If The-Weather is Nice, I'll talk a walk"
Granted, this may not be true for all natural languages, and it’s getting a bit nit-picky to argue over this for too long.
It’s more important to be consistent about how you approach your conditional checks. This is true for most aspects of programming. Pick the method that makes more sense to you, and stick with it.
if (a = 2)
will get caught the first time the programmer tests with a value other than 2
, and no one can claim to be programming “safely” who didn’t perform that test at least once. In other words, it only increases safety if you’re already programming somewhat recklessly, so most people go with the version that is more readable. In English, that’s variable == constant
. That might be different in other languages, or in very specific domains, but in general most people expect to see conditions written in that order.
This approach is also known as “Yoda conditions” (“if true the condition is”), and its purpose is to catch the common error in C-like languages, where you accidentally use a single =
when you mean ==
, causing an assignment. Because the return value of such an assignment is the newly assigned value, such a bug can go unnoticed, and surface only much later in the code, at a seemingly unrelated location, and seemingly at-random. Such bugs are obviously the worst kind you can have, and so the “Yoda” convention reverses the operands – a constant is not an lvalue, and accidentally putting one on the left side of an assignment causes a compiler error, which is good because it means the error surfaces early on, in an easy-to-debug way.
However, the Yoda convention has some significant downsides:
- It comes at the cost of readability. “If the number of items is 4” is easier to read than “If 4 is the number of items”, and this is also true for code.
- It relies solely on convention; there is nothing stopping a programmer from forgetting the convention, and you’re back to square one. In other words, the convention cannot be enforced, and so you still don’t have any guarantees.
- It only works for comparing against non-lvalues. If you compare two variables, both sides are lvalues, and you’re not winning anything.
At the same time, compilers have advanced, in such a way that they are now able to detect what is probably an unintended assignment in a condition – quite simply, if you use =
inside an if
condition, the compiler will throw a warning. This check is easy to automate and enforce: just turn on the relevant compiler flags in your build script to treat this as a fatal error. This, of course, works for any kind of equals-comparison, regardless of lvalues, and it doesn’t compromise readability in any way.
You are most likely to find Yoda conventions used in older projects, and when it is in place, it’s probably better to stick with it, but I would not recommend using it in new projects – the benefit today is practically zero, and it’s not worth the sacrifice in readability.