55

Lately, I've been working a lot in PHP and specifically within the WordPress framework. I'm noticing a lot of code in the form of:

if ( 1 == $options['postlink'] )

Where I would have expected to see:

if ( $options['postlink'] == 1 )

Is this a convention found in certain languages / frameworks? Is there any reason the former approach is preferable to the latter (from a processing perspective, or a parsing perspective or even a human perspective?)

Or is it merely a matter of taste? I have always thought it better when performing a test, that the variable item being tested against some constant is on the left. It seems to map better to the way we would ask the question in natural language: "if the cake is chocolate" rather than "if chocolate is the cake".

gnat
  • 21,442
  • 29
  • 112
  • 288
Tom Auger
  • 847
  • 1
  • 7
  • 10
  • 1
    I never ever write code like that but to be fair "if chocolate is the flavor of the cake" does sound natural. Natural language is more flexible. – Rick Sladkey May 05 '11 at 23:17
  • 4
    @Rick It might sound natural in language, but you can't deny that when you see code like that, you have to stop first (maybe only for a second) to think what is it that it's trying to do. – Edgar Gonzalez May 06 '11 at 01:45
  • 4
    @Edgar Gonzalez: Agreed, I am firmly against it in code. – Rick Sladkey May 06 '11 at 01:52
  • 5
    Chapter 19 of [Code Complete 2nd Edition](http://is.gd/1jQisD) (under the section "Boolean Expressions: Common Problems With Boolean Expressions") actually recommends this practise for the exact reason stated in many of the answers here: to prevent assignment in C-derived languages when comparison was meant. – CraigTP May 06 '11 at 10:09
  • @CraigTP, interesting. – Tom Auger May 06 '11 at 14:22
  • Related http://programmers.stackexchange.com/questions/16908/doesnt-if-0-value-do-more-harm-than-good and http://programmers.stackexchange.com/questions/118901/which-one-is-better-ifx-3-or-if3-x – ChrisF Sep 12 '12 at 19:53
  • AKA joda conditions: http://www.codinghorror.com/blog/2012/07/new-programming-jargon.html – m0sa Sep 12 '12 at 20:28
  • 6
    I've often seen these referred to as "Yoda Conditions" – Brian Sep 12 '12 at 20:58
  • 1
    See: [Doesn't “if (0 == value) …” do more harm than good?](http://programmers.stackexchange.com/q/16908/12917) – Martin York Sep 12 '12 at 23:24
  • 1
    @CraigTP: That is long outdated advice (for C like languages). The compiler is more than able to prevent this: see [In C and C++, what methods can prevent accidental use of the assignment(=) where equivalence(==) is needed?](http://programmers.stackexchange.com/q/162256/12917) – Martin York Sep 12 '12 at 23:27
  • @LokiAstari Fair enough. Code Complete 2nd Edition *is* now 8 years old, and the original 1st edition is almost 20 years old! I'm sure there have been a ton of compiler (and other general) improvements in those intervening years. – CraigTP Sep 13 '12 at 08:13
  • 1
    Update: since I started working on WordPress core and using their http://codex.wordpress.org/WordPress_Coding_Standards I _have_ been getting used to it. One thing that IS nice, is if you're using string literals as your test, for example, it slightly improves readability: `if ( 'published' == $post_status ){ ... }` – Tom Auger Sep 19 '12 at 17:03
  • This question shows how the rules for SoftwareEngineering SE are imperfect. The accepted answer is valid, but so is "Readability is most important" which would have the opposite answer. – Kind Contributor Mar 17 '21 at 05:39

5 Answers5

93

The main reason to do this (so-called "Yoda conditional") is to prevent accidents whereby you accidentally use an assignment operator (=) instead of the equal comparison operator (==).

That is, if you made the mistake of doing:

$foo = 5;
if ($foo = 1) {
  // Stuff
}

The statement will evaluate to true (or, in the case of some languages—like PHP—a truthy value) and you'll have a hard-to-find bug.

But if you did:

$foo = 5;
if (1 = $foo) {
  // Stuff
}

You'll receive a fatal error because you can't assign $foo to an integer.

But as you pointed out, reversing the order generally makes things less readable. So, many coding standards (but not all, including WordPress) suggest or require $foo == 1 despite the bug hunting benefits of 1 == $foo.

Generally, my advice is to follow whatever established coding standard there is, if there is one: for WordPress, that means using Yoda conditionals.

When there isn't, and it's impossible to establish one through consensus with your peers, it's dealer's choice.

Glorfindel
  • 3,137
  • 6
  • 25
  • 33
  • 4
    I remember when designing a language (long time ago) that we specifically made `:=` be the assignment operator (with `==` for equality test) in order to avoid this sort of trouble. – Donal Fellows May 05 '11 at 23:37
  • I know a few C++ developers who write in this order, too. @DonalFellows - you didn't work on Pascal, did you? I remember that assignment operator from my Delphi days :) – HorusKol May 05 '11 at 23:52
  • 7
    I have written many, many, lines of code, and I have *never* accidentally typed `=` instead of `==`. The difference is so accentuated everywhere that i've just never got them confused. On the other hand, I have read many pieces of code that are confusing or otherwise hard to understand. As such, I would put the priorities on the readability :). Regardless, good answer. – crazy2be May 06 '11 at 00:22
  • 7
    Yet another good reason to use `-Wall -Werror` or your compiler/interpreter's equivalent. There are very few situations where an assignment inside a condition is correct, let alone more readable. A lot of languages don't even allow it. – Karl Bielefeldt May 06 '11 at 03:21
  • 8
    Pedantic: While `if($foo = 1)` evaluates to `true` in some languages, in PHP it evaluates to 1 instead; `if($foo = 20)` evaluates to 20; `if($foo = 0)` evaluates to 0, which unlike the others is false. This can add a whole 'nother layer of complexity to the bug. – Charles May 06 '11 at 05:00
  • +1 that I've learn that it can be used defensively, though `if 1 == $foo` looks awkward for me. – OnesimusUnbound May 06 '11 at 09:42
  • @HorusKol No, but my boss at the time had worked quite a bit on Ada. – Donal Fellows Sep 13 '12 at 09:12
  • 3
    Actually, the WordPress Coding Standards DOES call for Yoda Conditionals: http://codex.wordpress.org/WordPress_Coding_Standards#Yoda_Conditions – Tom Auger Sep 18 '12 at 14:46
  • @TomAuger It seems you're right: judging by the revision history, [it was added in December 2010](http://codex.wordpress.org/index.php?title=WordPress_Coding_Standards&diff=prev&oldid=96962). Not sure why nobody caught that until now, but I fixed my answer. –  Sep 18 '12 at 15:56
  • @crazy2be: Speak for yourself. CppCheck currently warns against this kind of errors and saved my neck a couple times. If you mean assignment, it suggests extra pair of parentheses, `if((q=!p))` goes without warning. – SF. Jan 09 '13 at 13:13
  • Actually it *does* look more readable, if the dynamic part of the condition is significantly longer than the static part. `if (false !== strpos(ucfirst('the fox jumped over the hedge'), 'fox') {..}` This allows to immediately see the toplevel comparison operator. The length of the dynamic part could be due to long variable names, or to expressions. – donquixote Feb 11 '16 at 07:51
  • It can also increase readability in some kind of switch implemented as if/else. `if ('red' === $color) {..} elseif ('blue' === $color) {..} elseif ('green' === $color) {..} else {..}`. Here the string literals have the higher information value for a reader. – donquixote Feb 11 '16 at 07:53
  • Japanese people read many things in reverse, so the "Yoda condition" might be more readable to them. Besides I've read in some rationale that putting the const first makes it more easily to find the correct branch in a series of `if () else if () else if ()...` – phuclv Jan 24 '20 at 23:53
14

It's a defensive coding mechanism meant to prevent an accidental use of the assignment operator.

Consider a misuse/error of the assignment operator in place of the equality operator

if ( $options['postlink'] = 1  )

The above conditional would always return true, but that's probably not what the original programmer had in mind. Consider, in it's place, this

if( 1 = $options['postlink'])

Here, PHP (and most other languages) would refuse to run, as it's impossible to assign anything to the fixed value of 1. By coding up all the conditional statements this way, you automatically ensure no accidental usage of an assignment operator in a conditional.

Alana Storm
  • 301
  • 1
  • 7
10

I like using that convention in java to remove the possibility of a null pointer exception. So something like this won't cause you any problems or need any extra code:

String foo = null;

if ("bar".equals(foo))
{
    //Do something
}
Ben Newman
  • 101
  • 2
  • 3
    I like this, but I hate the general idiom. – Thomas Eding May 06 '11 at 03:35
  • 3
    If a null value is not valid by that point in code you should have already checked for it anyway or designed your code in such a way that a null value would be impossible. – Ed S. May 07 '11 at 20:03
  • 6
    this seems like an easy way to mask problems. Dusts aren't cleaned by shrugging them inside the carpet. – Lie Ryan Jul 13 '11 at 15:53
1

In practice, many compilers will give you a warning if you write "if (x = 1)" instead of "if (x == 1)" because it is most likely a mistake.

With Clang, you can avoid the warning by effectively telling the compiler "I mean it, and I know what I'm doing", and this is done by writing "if ((x = 1))". Note the extra parentheses. That works in other situations as well. if (false) statement; may give you a warning that the statement is never executed; if ((false)) statement; doesn't give that warning.

PS. Many languages nowadays require that the expression in an "if" statement is boolean, without any automatic conversion. In "if (x = 1)" the expression has type "int" so it won't be accepted, except for the rare case "if (bool1 = bool2)".

gnasher729
  • 42,090
  • 4
  • 59
  • 119
  • I like that a lot! I avoid the following, completely legit idiom in PHP because I always get warnings in my IDE: `if ($array = getSomething()){ // ..so something with $array }` – Tom Auger May 22 '19 at 13:57
-1

if ($variable == 'constant')

Because you spend more time reading code than writing it (see https://www.goodreads.com/quotes/835238-indeed-the-ratio-of-time-spent-reading-versus-writing-is), and this form is easier to read.

Although User8 has a valid argument to have the constant first; that's reasoning about what to do from the code writer's perspective. Normally, there are less experienced coders reading code, and they need all the help they can get in matching the natural order that would have the constant laste. (And of course, good language design and compiler checks overcome the stated problem).

Kind Contributor
  • 802
  • 4
  • 12
  • *good language design and compiler checks overcome the stated problem* Except when they don't. The entire purpose of Yoda conditions is to act as just one tool to ***prevent*** the creation of bugs, not merely hope they are discovered by something before causing problems. – Andrew Henle Mar 17 '21 at 10:30
  • @AndrewHenle That was in brackets, because that isn't my answer, but food for thought. Different people have different circumstances and are quite free to apply accordingly. – Kind Contributor Mar 18 '21 at 00:04
  • -1 for: reviving a very old question, adding nothing new to the pool of knowledge, and generally coming across as arrogant and superior. That's not really the culture here. You can do better. – Tom Auger Mar 26 '21 at 17:58
  • @TomAuger I'm a humble answerer, with no world-domination ambitions. Kindly point out which section of my answer is at fault and I will endeavor to improve it for the community. – Kind Contributor Apr 04 '21 at 12:09