“Yoda Conditions” (from: stackoverflow – New programming jargon you coined?)
Posted by jpluimers on 2010/05/25
Having done quite a bit of C and C++ work in the past, I often still use “Yoda Conditions”, especially in environments where you have both = and == as an operator.
So, in a boolean expression, I often put the constant to test in front of the test.
I recently learned at stackoverflow that quite a few people call these “Yoda Conditions”:
“Yoda Conditions”— the act of using if(constant == variable) instead of if(variable == constant), like if(4 == foo). Because it’s like saying “if blue is the sky” or “if tall is the man”.
Thanks to dreamlax for helping me find that.
This is a problem in languages that have both the = and == operators, and the result of an assignment itself is also a value (i.e. allowing a = b = true).
In C# this still can go wrong with booleans.
Chuck Jazdzewski wrote a posting “zero the value is not” back in 2008, and Dan commented that C# still can fail with booleans.
For instance, in C#, consider this code:
bool a; if (a = true) // Warning: "Assignment in conditional expression is always constant; did you mean to use == instead of = ?" Console.WriteLine(a); bool b; if (a = b = true) // No Warning! Console.WriteLine(a);
Both if statements will happily hop into the “then”, and write true to the console.
The first statement will get you a compiler warning, but the second won’t!
Code inspection, pair programming, turning on warnings, etc will help you prevent these problems.
But using Yoda Conditions will generate a compiler error in stead of a warning.
Looking at the comments on stackoverflow, lots of people seem to object to Yoda Conditions.
But there are other situations where the order of things is ‘constant value, expression to test’ too.
For instance:
- Unit testing: for instance JUnit, NUnit, DUnit and their father SUnit all have an Assert class that has assertEquals methods with parameters in the order “expected, actual”
- When testing reference.Equals(constant) and the reference can be null, it is wiser to turn it into constant.Equals(rerference)
So are Yoda Conditions really thad bad?
I don’t think so. And reading the Yoda Conditions post by Clark Grub, he doesn’t either. He even adds a few more languages in his list (like JavaScript and Ruby).
What’s your take on this?
–jeroen
PS: Since I use many languages and environments (always pick the best tool for a job!), I tend to:
- Use Yoda Conditions in other languages too
- Always have parentheses around boolean expressions
The reason is that languages do differ in what they allow and require. Finding a common denominator that works in most languages saves a lot of energy.
Things I tripped over when implementing the “Elf proef”: digit check for Dutch bank account numbers and social security numbers (bankrekeningnummer, BSN/Sofinummer) « The Wiert Corner – irregular stream of Wiert stuff said
[…] Comments jpluimers on “Yoda Conditions” …auto Approve directo… on “Yoda Conditions” …Skydvrz on Crap: VersionInfo […]
auto Approve directories said
Have you ever thought about including a little bit more than just your articles?
I mean, what you say is important and all. However think of if you added some great graphics or videos to give your
posts more, “pop”! Your content is excellent but with images and video clips, this blog could definitely be one of the greatest
in its niche. Awesome blog!
jpluimers said
Not sure about this yet. It sounds compelling, but getting the info out already takes quite a bit of time.
Jon Jagger said
Surely if you’re aware enough of the problem to reverse the operands you’re aware enough of the problem to check you’ve written == instead of =
jpluimers said
The thing is: I’m not always aware of the exact writing of the operands. Which has to do with switching between many languages, and a mild form of dyslexia. So defensive programming helps.
Of course YMMV (:
Oh BTW: any new annotated C# reference in the pipeline? I absolutely loved the first edition (http://www.amazon.com/exec/obidos/ASIN/0123725119) and your hyperlinked C# 1.0 specs.
–jeroen
if disscution - SitePoint Forums said
[…] Here's a nice overview with a few links to other articles… __________________ @AnthonySterling: A PHP […]
Bob said
In C and C++:
NEVER EVER compare anything against “true” or “TRUE”. NEVER NEVER NEVER.
Do NOT write
if ( bValue == true )
{
…
}
If you can’t code
if ( bValue )
{
…
}
then at least code
if ( false != bValue )
{
…
}
“false” and “FALSE” have a defined value, zero (0). “true” and “TRUE” are ANY OTHER VALUE.
DO NOT COMPARE AGAINST “true” or “TRUE”!
Please forgive the shouting. I’ve coded in C since 1978. It’s like a knife; people really should earn their totin’ chips before they are allowed to use it.
Yoda Conditions « sigillum said
[…] malheureuse dans les conditions… ce que je ne savais pas c'est que cela avait un petit nom : Yoda Conditions […]
Positive Comments on Every Programming Language I’ve Ever Learned | Flyover Country said
[…] this idiom deep into my brain:Â if (0 == someFunctionCall) { /* Apparently people call these “Yoda Conditions” */ […]
Trillian said
Please, I understand why you can feel the need to do this in C++, but don’t do this in C#. Using “== true” or “== false” is idiot anyways, so there’s really no problem here. The only edge case is when you do “if (a == b)” where a and b are booleans, but that alone doesn’t justify making all your conditionals mental speedbumps.
jpluimers said
I used “true” and “false” for simplification: any boolean constant or other form of read-only boolean would do.
My statement still holds: when regularly switching programming languages, it pays off having a defensive coding standard.
If people are being bumped by this kind of comparison order, they will have immense trouble doing generics, yielding from iterators, lambda expressions, etc, won’t they?
–jeroen
Trillian said
There’s a difference between having trouble understanding a concept and having a second of “huh?” every time you see an unintuitive construct like if (null == foo). I’m not alone in this situation, just see the comments on stackoverflow. I’m totally for defensive programming and I get your point, but C# and Java were designed so the probability of problematically interverting = and == operators is virtually inexistant, so I feel that using yoda conditions in those languages is being overcautious at the expense of readability.
jpluimers said
I do understand, but C# did not eliminate the probability for boolean values.
I have been bitten by this quite a few times already, so I have continued the yoda-style from other environments I have been active in, and I don’t have this “huh” any more.
Of course this is a matter of style and taste, so please disagree :-)
–jeroen
Guy Gordon said
I use them in a single case: when a simple constant is being compared to the return value of a function. e.g.
if (mrYes = MessageDlg(UserMsg.Message,mtConfirmation, [mbYes, mbNo], 0)) then begin…
This improves readability over the standard, making it easier to see what condition will execute the ‘then block’, because the constant is not swimming out at the end of a long line.
I also always put boolean expressions in parens.
Jim McKeeth said
How about if you just used Equals(ArgA, ArgB) instead of the == operator? Then in languages that don’t support Equals you can write your own.
Dan Downs said
Seems like complete overkill to have to implement an Equals() function for all the various base types and insert a function call wherever you just needed == and let the compiler do its job.
jpluimers said
Equals opens up a complete new can of worms. See also this posting: .NET comparison is a 101, or isn’t it?.
–jeroen
Mason Wheeler said
Personally, I find Yoda Conditions ugly and difficult to read because they go against they way you think. They’re only used because the designers of the C language committed the massive wall-banger of formalizing in the language standard that anything can be a boolean, which is directly responsible for a great deal of syntactical ugliness and confusing-ness in C and the languages which descended from it.
jpluimers said
Personally, you got the whole point about these things :-)
–jeroen
Warren said
I would be in favor of removing the ability to use assignment in a boolean expression completely from the C language. Except, wait, you would then be unable to write
a for loop. And there are lots of other cases where the sad little decisions they made, have doomed users of C to a lifetime of wrestling issues like this.
W
jpluimers said
Luckily not only C, or C-influenced languages that have oddities :-)
–jeroen
Dan Downs said
But readability is what you just gained, it makes you not gloss over the common mistake and it includes intent. Doesn’t solve the “if Var1 = Var2” issue but its a step in the right direction.
Reminds me of prefixing string vars with us/s/ds/js/etc… for unsafe/safe/DBsafe/JSONsafe whatever the intent is so when reading the code
dsFirstName := usGetRequestField(‘FirstName’);
looks wrong because a “us” string shouldn’t be assigned to a “ds” string.