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
}
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 '='
}
and finally, if you go all in and use strict comparison, this:
<?php
if ('Luke Skywalker' === $name) {
}
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()) {
}
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) {
}
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.
Top comments (24)
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.
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
isnull
in your first example you catch it immediately, because it throws aNullPointerException
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 withnull
?Now there's
Objects.equals(variable, "value")
as well... although it looks sloppy at first it's very useful for lambdasTIL. That's a good usage of Yoda conditions.
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.
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:
Woah! Neat!
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.
'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
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.
Nice story, didn't know that one, but it's definitely similar!
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.
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.
What do you mean by that exactly?
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.
Rewrite the whole post in Yoda I definitely should. On the head, the nail would be hit.
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.
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/
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!
And I'm glad to see I'm not alone! Thanks!
Silence is golden :)
Golden, silence is.
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...