DEV Community

Grégoire Paris
Grégoire Paris

Posted on • Updated on

Why using Yoda conditions you should probably not be

I had been using Yoda conditions for some time before I stumbled upon this now deleted Stack Overflow Question, later backed up in this blog post. I remember thinking "This could have saved me a lot of time!". Indeed, who can claim they have never written code like this:



<?php
if ($name = 'Luke Skywalker') {
   // this piece of code will always be executed
}


Enter fullscreen mode Exit fullscreen mode

So how do Yoda conditions work? Well it is basically a knee-jerk reaction you have to develop: whenever you write a condition, put the operand that cannot be assigned on the left. This should give you an error message if you make an assignment when you actually meant to make a comparison.

In our case, this gives the following:



<?php
if ('Luke Skywalker' = $name) { // Parse error: syntax error, unexpected '='
}


Enter fullscreen mode Exit fullscreen mode

and finally, if you go all in and use strict comparison, this:



<?php
if ('Luke Skywalker' === $name) {
}


Enter fullscreen mode Exit fullscreen mode

In english, this translates to "If Luke Skywalker is the name", which should feel very familiar if you are from Dagobah or whichever planet Yoda actually came from, but is just cognitive load if you are used to english syntax, which you should if you are writing programs.

I believe it has to become a knee-jerk reaction because if it does not, there is no point to it: if you can think of using Yoda conditions, then for sure you can think of checking if you really mean to write an assignment here or not. You have to use them without thinking.

So let us say that you develop the knee-jerk reaction. You might end up with code like this:



<?php
if ('Luke Skywalker' === $this->getName()) {
}


Enter fullscreen mode Exit fullscreen mode

Do you see the issue here? Neither operands can be assigned, so there is no benefit, but the downside is still there.

Soon enough, the disease spreads to inequalities, even in the documentation of my favorite framework, and you end up with needlessly convoluted code like this:



<?php
if (42 < $force) {
}


Enter fullscreen mode Exit fullscreen mode

There are a few things to ponder before picking Yoda.

First, the only person who benefits from Yoda conditions, is you, the writer. It just makes life slightly harder for the people that read your code, which includes code reviewers, coworkers, or potential contributors.

Also, if you test every code path, you should be able to spot the problem before it reaches the next step of your development pipeline. Tests can help with that, especially if you write them before writing the actual code, in a healthy red-green-refactor cycle

Next, code review (including and especially self code-review) should catch the mistake if tests fail to do that.

And finally, if you are not feeling a strong need for assignments in conditions anyway, you may as well use a static analyzer to enforce a rule that forbids them. If you still would like to be able to use them you can also prevent Yoda conditions and only them.

So go ahead, get rid of Yoda conditions today, and death to the Jedi.

see your enemy

Image by Daryl Mandryk

Top comments (24)

Collapse
 
andrewmcguinness profile image
Andrew McGuinness

In some languages (like java) yoda-conditions also give you null handling:

if (variable.equals("value")) ...

throws an exception if variable is null

if ("value".equals(variable)) ...

will work correctly

if ((variable != null) && variable.equals("value")) ...

is more work and potentially error-prone.

Collapse
 
maxart2501 profile image
Massimo Artizzu • Edited

Can you really call it a "Yoda condition"?

Yoda conditions have been born to avoid hard-to-catch mistakes, like an assignment in a condition statement. If variable is null in your first example you catch it immediately, because it throws a NullPointerException as you mentioned.

So it doesn't save you from a mistake; it saves you from checking if the value is null or not. And honestly I'm not sure it's what I'd want: if I expect a string there, why am I dealing with null?

Collapse
 
dean profile image
dean

Now there's Objects.equals(variable, "value") as well... although it looks sloppy at first it's very useful for lambdas

Collapse
 
greg0ire profile image
Grégoire Paris

TIL. That's a good usage of Yoda conditions.

Collapse
 
maxart2501 profile image
Massimo Artizzu

Linters

That's all we need. Linters can easily catch problems like this one. And many others, of course.

So let's forget about Yoda conditions, like we forgot about the Hungarian notation and other hard-to-read conventions.

Collapse
 
palle profile image
Palle

Or languages designed with code safety in mind, which prohibit these kinds of expressions.

For example in Swift (and other type safe programming languages), the following expression results in a compile time error:

if name = "Luke Skywalker" { // error: use of '=' in a boolean context, did you mean '=='?
    // ...
}
Collapse
 
greg0ire profile image
Grégoire Paris

Woah! Neat!

Collapse
 
greg0ire profile image
Grégoire Paris • Edited

Yoda conditions are a lot like the Hungarian notation: it's a "clever" trick that help you catch mistakes for every gazillion time you use it. Just not worth it.

Collapse
 
soullivaneuh profile image
Sullivan SENECHAL

'Luke Skywalker' === $this->getName() is not relevant, indeed. This why you should not use it for this and only for this.

AFAIK, Symfony rules require yoda condition only if useful.

P.S.: I'm already far far away ! <3

Collapse
 
4wdcoder profile image
John McDaniel

I think this is a lot like the story where a daughter asks her mom why she cuts the ends off the roast before she cooks it. Her mom says that grandma used to do it that way, so she did as well. When grandma is asked by the daughter, she says that she did it because the roast was too big for her small pan...

Honestly, this style of programming came out of necessity. We used it back in the old C/C++ days because the tooling and testing support just wasn't mature compared to today. I remember the first time we upgraded the compiler to a version that would detect this condition. We had all sorts of hidden bugs instantly visible.

I think the reason this style has persisted so long, is that older developers have passed it down due to the development scars we carry from years ago. I do find myself writing this type of code, for the very reason that it's just the way I have always done it. It is good to see these beliefs being questioned, and it will probably change the way I code from here on, just due to it being pointed out. It you have the tooling and testing support, there is just no valid reason to drop in a Yoda condition anymore.

Collapse
 
greg0ire profile image
Grégoire Paris

Nice story, didn't know that one, but it's definitely similar!

Collapse
 
dragonbe profile image
Michelangelo van Dam

I see your point and I agree to some extent. But the main reason you apply Yoda conditions is to fail first.

Basically it's the same reason why you have declare(strict_types=1); on the first line of your code.

Yes, readability is somewhat shattered but you gain better control over your code flow. Especially when you're developing for resilience. In huge codebases normal condition statements are overlooked and tests don't cover these conditions. Especially when dealing with legacy code.

Collapse
 
greg0ire profile image
Grégoire Paris

You can still use code review and linters with legacy code though. And unit tests, if you can decouple new code you introduce from the legacy code.

but you gain better control over your code flow.

What do you mean by that exactly?

Collapse
 
dwd profile image
Dave Cridland

Agree do I. Yoda conditions I used as well. Better tools we now have, catch errors they will. Useful some cases remain, as comments say, but needed simple cases no longer are. Writing like Yoda difficult is, and reading like Yoda hard is too.

Collapse
 
greg0ire profile image
Grégoire Paris

Rewrite the whole post in Yoda I definitely should. On the head, the nail would be hit.

Collapse
 
jake profile image
Jake Casto

Sounds like something a sith would say 🤔.

All jokes aside great article, I don’t program much in PHP anymore but when I did “Yoda Statements” on occasion a yoga statement would pop up in my code, and it frustrated my co workers and anyone reviewing my code; You don’t see anyone addressing them often, I’m glad you wrote this article.

Collapse
 
greg0ire profile image
Grégoire Paris

Thanks a lot! It has been bothering me for a while, and I needed a reference to avoid repeating myself :)

What's wrong with the Sith anyway? reddit.com/r/EmpireDidNothingWrong/

Collapse
 
joshbrw profile image
Josh Brown

I'm so glad you wrote about this! Writing Yoda if-statements just to avoid potential typos just seems backwards, your automated test suite should catch them issues!

Collapse
 
greg0ire profile image
Grégoire Paris

And I'm glad to see I'm not alone! Thanks!

Collapse
 
azeemhassni profile image
Azeem Hassni

Silence is golden :)

Collapse
 
aidantwoods profile image
Aidan Woods

Golden, silence is.

Collapse
 
greg0ire profile image
Grégoire Paris

If the parameter list is so long that you need to scroll, you need to use some linebreaks. See my other post, dev.to/greg0ire/why-i-keep-pesteri...