There's been a flurry of activity concerning Yoda Notation (also referred to as Yoda Conditions) recently. A conversation at work revealed that this term of art has taken off. More surprising, however, is the misinformation surrounding it.
So, in the public interest, I hope to set the matter straight.
What is Yoda Notation?
|That's not real C!
|Yes, I know, the blue-sky example, as stated, is not proper C, because of the need for something like
strcmp, but ignore that. For you sticklers, just mentally substitute
if(theSky = COLOR_BLUE) and assume we're comparing some non-pointer scalar. The example holds, though, for other languages with built-in string types.
As I've written elsewhere, Yoda Notation, also known as Yoda Conditions in some circles, is the reversal of operands on the equality operator in C (and derivative programming languages.) The example I provided almost a decade ago,
if("blue" == theSky) ...
illustrates this reversal. This is in contrast to the "normal" way of coding conditionals,
if(theSky == "blue") ...
which has certain vulnerabilities, necessitating the reversal.
Why Yoda Notation?
I've seen a few speculative comments on blogs, conjecturing its benefit as offering some optimization of generated code. This is not true. Equality is a commutative operator, meaning that
a == b is the same as
b == a. Given that, the compiler can take your
b == a and treat it as
a == b if it decides that can generate faster code. So performance is not the reason for Yoda Notation.
Instead, the practice of reversing equality operands—which I've been calling Yoda Notation for quite some time now—is to overcome what some (including me) consider a poor design decision in C and derivative languages, where
- The assignment operator is
=, but the equality operator is
- Assignment, being an operator, can occur where an expression is valid, while
- Other (unrelated) languages tend to use
=for equality, and/or contextualize assignment in some way.
The consequence of these factors: it is disturbingly easy to accidentally assign something to something else, rather than compare the two things for equality. In other words,
if(theSky = "blue") ...
is probably not what the programmer intended. The variable
theSky gets assigned the value
"blue" (losing its prior value,) and since that's a non-null value, the condition is always true, making the
if statement pointless (any
else clause will never be reachable.)
Some developers, having been bitten by such a bug—and blowing away many hours of time debugging code that "looks" right but clearly isn't—decided to never let that bug happen to them again, simply by reversing the operands. Voici: Yoda Notation is born. The compiler knows that you can't assign anything to a constant, and promptly generates an error when you use
= where you meant
==. Simple fix.
Where to use Yoda Notation?
The answer is not entirely straightforward.
Some have a keen distaste for Yoda Notation, and would insist that the correct answer is "never". I won't be so cavalier. I have gone on the record as not liking Yoda Notation, but I don't like writing buggy code, either.
That aside, where "should" one use Yoda Notation?
- In any language where assignment is
=and equality is
- where assignment is legal in an expression, and
- where the compiler doesn't warn you of assignments used in expressions.
It means that C# is not a candidate, however. Even though the language has the same
== operators as C, it was specifically designed to not allow assignments within expressions. The compiler will not just treat it as suspicious and warn you: it will outright complain that you can't do that. Still, there are shops that write in both C# and C or C++, and in those places, it's not uncommon for the practice to extend into C# code, simply for the in-house consistency.
Other languages have different operators for assignment and equality, and/or don't allow assignment within expressions.
- Pascal, for example, has
=, and colon-equals is not allowed within an expression.
- Certain flavors of BASIC use the
=for both assignment and equality, but contextualizes the assignment: you can only do that as a separate statement, not within another expression.
In these languages, Yoda Notation is functionally unnecessary, though it might be used for some of the (admittedly subjective) derivative values: consistency with other codebases, or—as one commenter elsewhere put it—to bring the constant to the front of what might be a long other operand.
Also, Yoda Notation is only required around equality, since it "looks" so much like assignment. It is not necessary for any of the inequality operators.
Beware of using Yoda Notation when one (or both) of the operands has a side effect (say, a "non-idempotent" function or one that remembers something internally, in addition to returning a value.) Order of operation is not always what you think.
Finally, Yoda Notation is moot when comparing the equality of two non-constant items, such as two variables. The compiler can offer no protection from abuse there (and after all, which one of two variables is "supposed to" come first?)
Who Invented Yoda Notation?
The syntax? I don't know. It's been around for a good while, and as I don't particularly like it, it's not me.
The term? No, StackOverflow user zneak did not coin Yoda Notation. I've been referring to the reversed equality operands as Yoda Notation for far longer, so I could make a demonstrably superior claim to authorship. But not losing too much sleep over that, I'm glad that the term took first place in the now de-listed top jargon terms on StackOverflow; that's due in part to zneak submitting the term, and the many StackOverflow readers up-voting it.