4

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.

Daniel Figueroa
  • 494
  • 6
  • 15
  • Readability is a matter of habit, and increased programming safety is surely worth getting into a habit. How big the improvement actually is with modern compilers is arguable, but I've always felt that if A == 2 makes much more sense to someone than 2 == A does, then maybe they don't really get the concept of equality (which is symmetrical by definition). – Kilian Foth Mar 11 '13 at 16:29
  • 1
    Obviously they are both the same thing, it's not about the concept of equality. I mean that it makes sense because when reading the first example it translates seamlessly to how I tend to speak and think. – Daniel Figueroa Mar 11 '13 at 16:36
  • 5
    `2 == myint` is commonly referred as a yoda condition – Simon Bergot Mar 11 '13 at 16:46
  • In Java, it sometimes makes sense to compare `if( CONSTANT.equals(variable) )`, because then you avoid risking a NullPointerException or writing a null check. – ZeroOne Mar 12 '13 at 16:28

4 Answers4

6

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.

Jonathan Rich
  • 2,958
  • 16
  • 14
  • Don't most compilers these days issue a warning if they see an assignment inside a `if()` statement? – Dan Pichelman Mar 11 '13 at 16:20
  • 1
    Yes, and I've worked with a few coding standards that explicitly disallowed it as a convention. It's a dangerous practice, even though it's convenient. – Jonathan Rich Mar 11 '13 at 16:22
  • Wouldn't readonly variables help to alleviate this issue sometimes? –  Mar 11 '13 at 16:39
  • Thank you for your answer, but it doesn't really address my question. – Daniel Figueroa Mar 11 '13 at 16:41
  • Are you being funny, because I don't get it? – Daniel Figueroa Mar 11 '13 at 16:46
  • 1
    `var == const` is the standard, industry wide, regardless of programming language. `const == var` is more safe and also correct, but I've never seen it recommended. – Jonathan Rich Mar 11 '13 at 16:53
  • The original concern is largely a non-issue in modern type-safe languages; you'll get a compiler error if you say something like `if(int = 2)`, and you *shouldn't* be saying things like `if(bool = true)` - you ought to use `if(bool)` or `if(!bool)`. – Tacroy Mar 11 '13 at 17:59
6

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.

KChaloux
  • 5,773
  • 4
  • 35
  • 34
0

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.

Karl Bielefeldt
  • 146,727
  • 38
  • 279
  • 479
0

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.

tdammers
  • 52,406
  • 14
  • 106
  • 154