55

This is one of the things that I hate most when I see it in someone else's code. I know what it means and why some people do it this way ("what if I accidentally put '=' instead?"). For me it's very much like when a child goes down the stairs counting the steps out loud.

Anyway, here are my arguments against it:

  • It disrupts the natural flow of reading the program code. We, humans, say "if value is zero" and not "if zero is value".
  • Modern compilers warn you when you have an assignment in your condition, or actually if your condition consists of just that assignment, which, yes, looks suspicious anyway
  • You shouldn't forget to put double '=' when you are comparing values if you are a programmer. You may as well forget to put "!" when testing non-equality.
mojuba
  • 5,583
  • 2
  • 24
  • 32

10 Answers10

63

Ah, yes, "Yoda conditionals" ("If zero the value is, execute this code you must!"). I always point anyone who claims they're "better" at tools like lint(1). This particular problem has been solved since the late 70s. Most modern languages won't even compile an expression like if(x = 10), as they refuse to coerce the result of the assignment to a boolean.

As others have said, it certainly isn't a problem, but it does provoke a bit of cognitive dissonance.

TMN
  • 11,313
  • 1
  • 21
  • 31
  • 32
    +1 for "Yoda conditionals". I actually LOL'd at that. :) – Bobby Tables Nov 05 '10 at 00:42
  • 3
    While the ordering is fine, I object to comparison to zero instead of plain boolean cast, `if(!value)`. – SF. Jul 28 '11 at 07:22
  • 1
    So you consider assignments inside a conditional an error? –  Nov 10 '11 at 07:05
  • 4
    _"Most modern languages won't even compile this"_ The problem comes when you you're using a language that silently coerces the result of the assignment to a boolean. The most popular language that I can think of that does this would be JavaScript. This is why I always use yoda conditionals even in Java so that I don't forget to do it when I'm writing javascript. I switch between the two often enough that it can (and has) been a problem. – Sam Hasler Dec 01 '11 at 09:47
  • 3
    Does anyone know of a compiler that won't compile `if (0 == x)` ? – Kristopher Ives Oct 09 '18 at 13:47
  • @KristopherIves The refusal to coerce in some modern languages is obnoxious. Simply disallowing an assignment (even compound-assignment if available) as the control-expression is sufficient and safer, without forcing one to pepper ones code with all the `!= 0`, `!= null` and so on. Then you can use extra-braces to circumvent it, like in most modern compilers for C and C++. – Deduplicator Oct 10 '18 at 13:58
  • @Deduplicator Which languages / compilers? I want to run some tests - it doesn't appear to happen with any modern tools I have access to such as clang or GCC. – Kristopher Ives Oct 10 '18 at 14:11
  • Well, Java is most notorious for their love of verbosity. C# doesn't coerce to boolean either. Regarding C and C++, one has to ask for a reasonable level of warnings, or most compilers stay silent. – Deduplicator Oct 10 '18 at 14:16
  • @Deduplicator The issue in disallowing assignment as a control expression is that it's a perfectly valid control, and a sensible flow - if I do `while(val = getIfMoreData()){...}`, then it's pretty obvious what I want to do, and is notably more readable and understandable than `val=getIfMoreData;while(true){... val=getIfMoreData();if(val==null){break}}` – Delioth Oct 10 '18 at 14:59
  • @Delioth But it's rare enough that adding extra-parentheses to confirm it was actually meant is reasonable. Completely disallowing coercion fails to catch assignments which should have been comparisons, and leads to far more verbosity. – Deduplicator Oct 10 '18 at 17:25
61

It is obnoxious because it imposes a small, but noticeable mental tax.

People read left to right in virtually all programming languages (and most natural languages).

If I see 123 == x, the way I mentally parse it is:

  • 123 - so what? incomplete info.
  • == - well, 123 is 123, why test it...
  • x - ok, so that's what we're concerned about. Only now do I have the context.
  • Go back to reconsider 123 and why x is compared to it.

When I see x == 123 mental parsing is:

  • x - Provides context, I know what the condition is about. I may choose to ignore the rest. Based on previous flow I have a good idea why and what's to come (and be surprised if it's different).
  • == - I thought so.
  • 123 - Yup.

The disruption is small (in a simple example), but I always notice it.

Putting the value first may be a good idea if you want to draw attention to it, e.g. if (LAUNCH_NUKES == cmd). Normally this is not the intention.

dbkk
  • 2,106
  • 17
  • 16
  • 5
    Exactly. In natural languages the constant always comes last for the same reason: if the light is red... – mojuba Nov 05 '10 at 08:05
  • 2
    @mojuba True, it's almost universal. Oddly, there are a few natural languages where object comes before the subject (OVS/OSV order), but they're all obscure. – dbkk Nov 05 '10 at 13:42
  • 1
    On the other hand, some of us tend to read the symbols before the variable. They're more eye-catching. So I'll parse out `=` or `==` before `123` or `x`, and end up not even bothering to translate the code to English in my head. – Izkata Jul 09 '12 at 20:16
  • Also, most compilers will warn if prompted properly, unless one uses extra-braces, so it tries to solve a non-problem. – Deduplicator Oct 10 '18 at 14:17
49

Harmful? No. It works either way.

Bad Practice? Debatable, at best. It's simple defensive programming.

Worth losing sleep over? Nah.

Wonko the Sane
  • 3,172
  • 1
  • 24
  • 24
  • 8
    And when I read it, I understand the code immediately which is to me the most important reason to debate a coding style. I totally agree, not worth losing sleep over. – Jeff Siver Nov 05 '10 at 04:04
18

This is basically flaimbait.

No, it doesn't do more harm than good. Simple.

More words?

Compiler argument? Erm, ish, maybe - don't put too much faith in the complier to save you from yourself.

"You shouldn't forget" - well duh - no of course you shouldn't meanwhile I'm tired, I've been coding all day I've had to use two different languages and sometimes, just sometimes, being human I make a mistake.

The point of this sort of behaviour is that its defensive, its not there because you expect to make mistakes any more than you have insurance because you expect to crash... but if you do its nice to be covered.

Hard to read? You're complaining that a decent programmer should have == hardwired (which makes all kind of poor assumptions) but that the self same decent programmer can't read 0 == value ??

Does no harm, has potential benefits, silly question, let others do it if they want and move on.

Murph
  • 7,813
  • 1
  • 28
  • 41
  • 6
    I think 0 == value reads unnatural for those who studied algebra way before they studied programming. – mojuba Nov 04 '10 at 20:32
  • 4
    That's kind of not the point - yes, you're right it doesn't read right but equally a great deal of what we, as programmers, write doesn't exactly stack up as natural language and its a matter of how you interpret what you see – Murph Nov 04 '10 at 22:03
  • 4
    Bravo.. Not to mention the fact that *because* it reads unnaturally you are inclined to pay closer attention to it, hence catching potential mistakes. – mocj Nov 04 '10 at 23:31
  • 8
    @mocj - Therefore, we should all code as obtusely as possible to ensure that people reading our code need to *really* read our code? – Kaz Dragon Nov 05 '10 at 10:06
  • 1
    @Kaz Dragon - 0 == value constructs rank pretty low on the 'obtuse' scale. I've certainly seen 'as obtuse as possible' code come from people who would never consider this particular idiom. – mocj Nov 05 '10 at 14:25
  • 7
    @mocj - I appreciate that, but your argument was that the "brain stutter" as you're reading the Yoda conditional is a good thing. I'm asking the question that, if that is the case, should we aim to write all code so that we cause "brain stutters"? Genuine question. – Kaz Dragon Nov 05 '10 at 14:44
  • @Kaz Dragon - of course you don't write all code like that -- first and foremost code should be clearly written. That being said, I don't consider reversed conditionals unclear and the "stutter" is more of an "inkling". If it happens to identify a programming error sooner rather than later - bonus! Like any tool, you use what works for you... – mocj Nov 05 '10 at 15:09
11

I wouldn't call it harm, but it is obnoxious. So no I wouldn't say it does.

whatsisname
  • 27,463
  • 14
  • 73
  • 93
10

I've never felt that the whole 'what if I forget a =?' ever really held much weight. Yes, you may make a typo, but we all make typos, it seems silly to change your entire coding style because you're afraid of making a mistake. Why not make all of your variables & functions all lowercase with no puncuation, because you might forget to capitalize something or forget an underscore one day?

GSto
  • 8,531
  • 7
  • 39
  • 59
  • 6
    That's not the point of the question, the point is "is it harmful" - and it isn't. A very minor irritation at worst, but not harmful. – Murph Nov 04 '10 at 20:23
  • 1
    In dynamic languages - absolutely, you may mistype a symbol and waste your time later looking for the source of your bug – mojuba Nov 04 '10 at 20:24
  • 3
    with all respect, when you've spent a late night (or two) and find the source (in C++ code) is a = instead of ==, it would carry some weight. – DevSolo Nov 04 '10 at 20:51
  • 4
    @DevSolo: I think that should really happen once or twice in your career, but not more than that – mojuba Nov 04 '10 at 20:56
9

Some people use it to make it clear exactly what a conditional is doing. For instance:

Way 1:

FILE *fp;

fp = fopen("foo.txt", "w+");
if (fp == NULL) {

Way 2:

FILE *fp;

if (NULL == (fp = fopen("foo.txt", "w+"))) {

Some people feel that the second example is more concise, or reversing arguments illustrates the point of a test (conditional) prior to the test itself.

In all actuality, I don't really mind either way. I have my pet peeves about style and the biggest one is inconsistency. So, do it the same way, consistently and I won't mind reading your code.

Mix it up to the point where it looks like six different people with their own distinctive style worked on it at once, I get a little annoyed.

Tim Post
  • 18,757
  • 2
  • 57
  • 101
6

To me, it's simple conditioning. As someone who learned (in the 90's) C and C++, I grew accustomed to it and still use it, even though the reasons are lessoned.

Once you are "conditioned" to look at the left side for the "constant", it becomes second nature.

I also only use it for equivalence (or negated equivalence), not for greater/less than.

I completely agree w/ @Wonko's answer.

DevSolo
  • 2,814
  • 20
  • 23
5

The one case where I find it helpful is where the variable part of the if is quite long and seeing the values makes the code easier to read. The dotted namespace languages have the best examples of this.

For example something I worked on with single sign-on had a situation where you could have two concurrent sessions if a certain type of error happened and was recovered a certain way so I have to add a handler for it that was inside an if that looked something like this:

if (2 <= application.httpcontext.current.session["thenameofmysessiontoken"].items.count())

Admittedly in this example there are other ways to do this, but this would be a case where the number-first version is potentially more readable.

Bill
  • 8,330
  • 24
  • 52
  • 2
    I think the keyword here is "other ways to do this" ;) – mojuba Nov 04 '10 at 21:14
  • in this case yes, but in some cases this is still the most readable outcome. My only point is there are some legitimate reasons for doing this other than to combat language or ide behavior and type-o – Bill Nov 05 '10 at 15:42
  • To be honest, I have difficulties with Yoda conditions for <= and >=. The == sign is a different matter, because in my head I can just switch the symbols around, but in your case I need to remember that count() has to be greater than or equal to 2, and that's rather annoying to derivate from a smaller-or-equal sign. – Alex Sep 20 '18 at 13:52
3

And yet the errors occur. And sometimes you want an assignment in a loop operator where you might otherwise check equality, or at least it is standard practice to use it.

I hold with it somewhat.The advice that I have followed ( possibly from Code Complete ) is to keep what should be the lower value on the left in comparisons. I was discussing this with a colleague earlier and he thought it was kind of crazy but I've got very used to it.

So I would say:

if ( 0 <= value )

But I would also say:

if ( value <= 100 )

Equality I will tend to check with the variable on the left though, it's just more readable.

glenatron
  • 8,729
  • 3
  • 29
  • 43