
Yoda conditions - tosh
https://en.wikipedia.org/wiki/Yoda_conditions
======
jedisct1
All linters and C compilers emit a warning when an assignment is made in a
condition.

There are zero reasons to use that ugly and unnatural Yoda notation in 2019.

~~~
beatgammit
I think this is reasonable readable:

    
    
        while ((status = systemcall(...)) != SUCCESS) {
            do something with status;
        }
    

Leave a comment there explaining the assignment.

Likewise:

    
    
        if ((status = systemcall(...)) != SUCCESS) goto error;
    

Or something like that. I don't understand the hate, just make sure it's
obvious what you're doing.

~~~
Sahhaese
This would achieve the same but is far more readable:

    
    
       while(status != SUCCESS) {
          status = syscall(...);
          // do something with status
       }

~~~
taneq
Only if status is initialised to something other than SUCCESS.

~~~
blktiger
So use a do-while instead.

~~~
Izkata
And this introduces another bug: it'll run the loop body even if syscall fails
the first time it's run.

~~~
dpzmick
I've been going with this style for things like reading files (with retries)
or any sort of loop that feels awkward.

    
    
      while (1) {
        int ret = ...;
        if (ret == ...) break;
        if (ret == some_other_condition) break;
        // additional termination conditions....
        // do exactly one thing
      }

------
kemiller2002
I know I'm in the minority, but I honestly never really understood why people
get so up in arms about this. People keep saying it's so difficult to read,
and I just don't understand why. I know that linters and such can catch this
most of the time, but a lot of places I've seen don't use them. (I don't know
why, that's a whole other discussion.) It just seems to me that it's something
that keeps you from wasting time on silly mistakes should be common place. I
really don't understand.

~~~
carapace
You must be young, friend. The holy wars that used to rage over just where to
put curly brackets...

(And then Python came along and was like, "U wot mate?", and there were had
little wars over "syntactically-significant indentation" and tabs vs. spaces,
and _how many spaces_... And on, and on...)

~~~
kemiller2002
Oh no, I'm not young. I just find this particular argument makes less sense
than all the other types of arguments like this. Bracket placement in some
languages is necessary to not have unintended effect. Tabs vs spaces can cause
problems with certain ides/editors. I can somewhat understand most
justifications as to why people have a certain reason for formatting code in
their particular way. You want me to indent 3 spaces instead of 2 in Delphi,
because that's the way you've done it, fine. I don't care. But this particular
one, I don't get it. I never have. The amount of time that this one particular
trick saved me in terms of time and frustration is huge. When you spend 45
minutes tracking down a problem because you assigned 5 (or something) to
variable by accident, it almost always leads to a mouse throwing event. When
someone comes back and says that seeing 42 == x is too difficult to read even
though it can save countless hours, I just don't understand. (not every
project has the benefit of having a linter or a compiler that will catch
things like this.)

~~~
carapace
I see what you're saying, in this case there's real benefit to doing it one
way rather than the other. But if that was enough to get people to change we
would all be using better languages and tools, eh?

I got lucky I think. The first time I saw "yoda" conditions I had an
abreaction. But then I realized the programmer who wrote it was "a foreigner,
with ways different than our own." That somehow made it alright again.

Virginia Satir said that people would choose the familiar even over death. She
said the strongest human drive is for the familiar.

Jef Raskin pointed out that the way we use the word "intuitive" it really
means "familiar". The first time he handed a mouse to someone to try, who
hadn't previously seen it in use, she turned it over and used it like a little
trackball.

I'm pretty sure the only reason we don't all use Lisp is just human drive for
what's already familiar.

------
canacrypto
I've found it's better to write normal conditions that are easier to read and
leave it to your linter to catch unintended assignments.

~~~
thomasahle
Are they really easier to read though? A lot of the time which variable being
tested is obvious, so it makes sense to put the important information - the
value - first.

~~~
jonny_eh
> so it makes sense to put the important information

Both sides of the equality check are equally important.

~~~
TheSoftwareGuy
I think he should have written "it makes sense to put the non-obvious
information first" as it contrasts better with the first part of the sentence

------
arpa
Am I sure pretty any that linter warning a throw can of instead breaking flow
the both of reading writing and.

~~~
jerf
Despite the name, it isn't referring to Yoda's grammar form, it's just
reversing things around "and" and "or". If you really have a problem telling
that "x == y" is the same as "y == x" I suggest coming to a deeper, more
complete understanding of the equality operator as a commutative operator
where the order doesn't matter rather than thinking of it as "variable is?
value", as so many students clearly pick up accidentally.

I've actually noticed one thing about Common Core is that they do try much
harder than when I was a kid to not accidentally create that impression; my
kid's homework is full of "4 + 3 = ___" followed immediately by "____ = 8 +
2". Still kind of glossing over "=" as a "simplify" operator, but it's still
an improvement over when I was a kid when it was really easy to pick up the
idea that the "=" operator was actually a function meaning "take the
expression on the left and simplify it". (I mean, there's a sense where such
students aren't even wrong; it is the rational conclusion from the evidence
presented.)

~~~
jameshart
There are two perfectly valid ways of reading

    
    
       x == y
    

aloud as an English statement:

> X equals Y

> X and Y are equal

The first sentence uses active voice - the second passive. Active voice
ascribes agency to X; It makes a subject/object distinction between X and Y.
Passive voice makes them both objects.

When reading code, it makes more sense to ascribe agency to variables than to
constants, which is why people are more comfortable reading x == 0 than 0 ==
x. Zero can’t change, so it can’t do anything to make itself equal something.
X can change, so it is capable of equaling things.

If you’re equally comfortable with either formulation, maybe you just prefer
the passive reading of the sentence.

But I do wonder if you’d be equally happy if I went through your codebase and
replaced every for loop condition from i < length to length > i...

~~~
jerf
This is _exactly_ the point I'm making; if we must ascribe agency at all (I'm
thinking that's a category error here, but human thought is fuzzy and I'll
roll with it for now), it would belong to the "==". Don't read it as English
at all; read it natively. There is a reason we call these programming
_languages_ , no joke, no pun.

"But I do wonder if you’d be equally happy if I went through your codebase and
replaced every for loop condition from i < length to length > i..."

You'd have a hard time of it; I'm a vigorous believer in doing whatever you
can in the language you're in to avoid the old 3-element-style C-style for
loops in favor of "for ... in ..." or local equivalent. I'm pretty sure you'd
get single digit hits for C-style for loops with multiple clauses in the
condition.

------
memorysafety
So I'm writing a unit test. I bet everyone here can correctly guess the
language.

    
    
        assert ('Content-Type', 'text/plain') in dupefail.headers
        assert b"registration denied" in dupefail.body
        assert "403 Forbidden" == dupefail.status
    

I also happen to pay attention to the linter fart^Woutput:

    
    
        C: 61,11: Comparison should be dupefail.status == '403 Forbidden' (misplaced-comparison-constant)
    

I totally admit my thorough hate of pylint, it hasn't really ever helped me
once -- mostly led to more `#pylint: disable=…` garbage in the source. I still
force myself to use it, as a duty by fellow... other engineers. But that's an
aside.

Please, tell me how much more "natural" and "un-ugly" the 3-line snippet would
read to you had it the third line assert flipped away from Yoda style, just as
pylint suggests. I'm eager to hear you.

~~~
yegle
That's why normally you do self.assertEqual() instead of assert.

To properly support assert with good error reporting, pytest has to rewrite
the byte code. See [http://doc.pytest.org/en/latest/assert.html#assert-
details](http://doc.pytest.org/en/latest/assert.html#assert-details)

~~~
memorysafety
Look, I'm trying to humanly argue _against_ the statement "Yoda conditions are
unnatural". Nature has no boolean conditions. That statement should instead
say "Yoda conditions are unfamiliar (to me)" \-- at which point it's way
easier to see the statement's applicability limits, and dramatically narrow
down its consequences.

On the contrary; there're many common contexts where Yoda comparisons looks
more "natural", meaning they avoid breaking the surrounding code flow, and
bring the important part (the constant) up-front. I even brought up a real-
world example. Having read `assert "403 Forbidden" == ` and remembering the
context, can't you already guess the RHS (and just skim over it)? Sure you
can. Non-yoda loses here.

Be aware: you don't have to take a "for/against" side in this debate, as our
buggy brains try to in every flame war. Both sides have a point. Familiarize
yourself, and decide on case-by-case basis.

While we're at it: self.assertEqual() is super-ugly and unnatural, in my
judgement. Why am I forced to use _thrice_ as much words to express the simple
single-word concept of an assert? Why can't I spare the extra pair of parens,
and spell == directly? I see nothing wrong with bytecode rewriting; it's
amazing they can do it, and I appreciate the effort.

------
reallydontask
Interestingly enough they are needed when comparing to $null in Powershell

[https://rencore.com/blog/powershell-null-
comparison/](https://rencore.com/blog/powershell-null-comparison/)

~~~
larntz
I was going to post this too. I ran into this a year or so ago and now always
put $null on the left of a comparison.

------
frou_dh
Treating the symptom: Pollute the codebase with warped code.

Treating the cause: Use static analysis.

~~~
crdrost
Treating the cause's cause: use a programming language which makes a
distinction between actions and values, so that an action-which-produces-a-
boolean is not valid where a boolean is expected.

Treating the cause's cause's cause: design your own programming language to be
a strongly typed functional or logic programming language that is a descendant
of the ideas in XSLT, where the attitude was “the most common thing you do in
programming is to map one data structure into another, so let’s build the
whole language around making those mappings easy first.” There can now be no
confusion.

Probably treating the cause's cause's cause's cause is something like “just
use Excel for everything, why are you using these other languages?”

~~~
peterwwillis
> Probably treating the cause's cause's cause's cause is something like “just
> use Excel for everything, why are you using these other languages?”

It's be harder to get things done, but we'd be more certain about them

------
logfromblammo
I once worked for a place that explicitly told me not to do this. They also
told me to test booleans with

    
    
      if( booleanVariable == true ) ...
    

This was also the place that ordered me not to use LINQ statements because,
and I quote, "you need to write code that someone fresh out of high school
could understand". I don't work there any more.

~~~
lnanek2
We actually have to write boolean checks like that in Kotlin nowadays in
modern Android development. If your variable type is Boolean? instead of
Boolean, it is needed to both check if it is non-null and true.

~~~
logfromblammo
I was also not allowed to use the C# ?? null-coalesce operator. So something
like

    
    
      if( nullableBooleanVariable ?? false )
    

was also forbidden.

------
tasubotadas
Ahh... The good 'ol technique for avoiding NPEs in Java.

~~~
neatcoder
For those who are wondering what this refers to, it is writing code like this:

    
    
        "foo".equals(myVar)
    

instead of writing:

    
    
        myVar.equals("foo")
    

which could can cause NullPointerException if myVar is null.

~~~
delinka
you've missed a closing " which makes this read differently than intended

~~~
neatcoder
Thanks. Fixed now.

------
logicallee
only tangentially related, but one of the things I miss so much about Perl is
that, as in English, you can add an "if" or "unless" clause as an
afterthought.

$x++ if (!condition);

like if you start to increment $x++ and then you realize wait a second I only
mean if....

"unless" likewise functions as an "if not".

This is such a "natural" way to write.

Let's compare what happens if you have the thought to add a "statement
modifier" in any other programmer language.

you're written your statement, and now you have to go back to the beginning of
your line, write your condition, open a brace, go back to the end of the line,
and close your brace. Or maybe begin an entire code block, since you can't
have it on one line anymore.

it is so much less natural. why can't other programming languages have that?

~~~
marcinzm
The greatest difficulty with code is not in writing it but in reading it.

~~~
dragonwriter
<result> if/unless <condition> is pretty common in natural language for good
reason. I find it far more readable than prefix, block-form if for the simple
case of one-line results with no alternative branch.,

~~~
matthewmacleod
Agreed. Particularly useful for for constructs like:

    
    
      def do_stuff()
        return unless stuff_enabled?
    
        ...
      end

------
pgt
When your only hammer is C, everything looks like a toe.

Is there a shorter way of saying, "the wrong solution to the right problem"?

------
kstenerud
It should be noted that Yoda conditions originated at a time when compilers
didn't warn about accidental assignment, and linters weren't that great or had
poor compatibility.

More often than not, the first solution to a problem isn't the best, but the
best solution would take a lot of tooling fixes.

The Yoda condition trick is a relic of the past, well past its usefulness and
best left in its grave alongside Hungarian notation, macros for "inlining",
#include "blah.c", goto, etc.

~~~
human20190310
Style lives on, even after the practical purpose for it is no longer relevant.
People keep wearing denim, even if they're not working in a mine.

------
lukecameron
Previous discussion:
[https://news.ycombinator.com/item?id=13668792](https://news.ycombinator.com/item?id=13668792)

------
FPurchess
Not to mention 'Pokémon exceptions' (catch all)...

~~~
thomascgalvin
In Java at least, you almost can't get away from Pokemoning because of the
split between checked and unchecked exceptions. About half of libraries throw
checked, and the other half throw unchecked.

------
keymone
solution: don't have assignment operator.

~~~
imglorp
Or even use plain old := for assignment to help avoid confusion with ==. I
wonder if K & R wanted to save a character for terseness. I mean, these are
the guys who said, if they were writing Unix again, would "spell creat with an
e."

[https://en.wikiquote.org/wiki/Ken_Thompson](https://en.wikiquote.org/wiki/Ken_Thompson)

~~~
frou_dh
T&R are the originators of Unix and C. Kernighan seems to often unwittingly be
given Thompson's achievements!

------
OliverJones
Yeah. when hacking C and C++ into this habit I got. It was hard to break when
using other languages.

I've had a lot of feedback from colleagues that it's harder to read because
it's rare. If my colleagues say it's hard to read, that's good enough for me.

------
epx
I liked Pascal's := attribution. I miss it in almost every language.

------
johnnylambada
I use Yoda style string comparations in java all the time since they are null
safe. But other than that I wouldn't have much use for them because they're
more difficult to read

------
busterarm
Yoda conditionals are still very popular in the PHP/Wordpress space. I never
got used to using them personally.

~~~
csixty4
They're required per the WordPress PHP Coding Standards and flagged by the
WordPress rules for PHPLint. Lots of WordPress developers stick to those
standards, so that's why you see it everywhere.

~~~
busterarm
I'm aware of this.

------
sleavey
One example of a large code base that uses this is WordPress (PHP).

~~~
memorysafety
Good job duplicating that _second paragraph_ of the linked article.

~~~
sleavey
Argh, sorry I missed that, I skipped over the intro and looked at the
examples.

EDIT: to be fair, this sentence was added today [1]. Not sure if it would have
been there when I opened the tab earlier.

[1]
[https://en.wikipedia.org/w/index.php?title=Yoda_conditions&t...](https://en.wikipedia.org/w/index.php?title=Yoda_conditions&type=revision&diff=910934321&oldid=910931930)

------
jshowa3
Of course WordPress uses this in their style guide... if modern compilers
catch this, it's a waste of time to use this convention.

------
timinman
Thanks for that!

