Live data from Hacker News

Yoda Conditions

en.wikipedia.org

51–60 of 83 posts

Re: Yoda Conditions

#51

In PHP I like using Yoda Conditions because there's a common idiom of testing assignment in the conditional: if ($value = getSomeValue()) { // Safely use value } Yoda Conditions defend nicely against accidents when '=' and '==' can be used legally this way and honestly you get used to reading them pretty quick.

Just wrap the condition inside another pair of parentheses; that should get any linter off your back without needing to deal with the annoying flipped conditions – and if someone doesn't know the code base has a 100% coverage of Yoda conditions, they might just think there's a bug on the line when seeing it for the first time (unless you add an explanatory comment each time, at which point the assignment inside the condition has bought you nothing, as you might just lift it on a row of its own before the if statement).

C++, for instance however has language syntax to prevent confusion when using this idiom – declarations inside conditionals:

  if (auto val = getval())
    foo(val); // executed only if getval() returned something that evaluates to true
              // in a boolean context
Considering that PHP already has the useless var keyword, they might just adopt something similar in the future

  if (var $val = getval()) {}

Re: Yoda Conditions

#52
post #47
post #31

Earlier quoted context omitted.

Not sure I like the sound of that. It sounds like the floating point wat of "NaN != NaN".

Making messages to nil be a no-op is certainly an "interesting" feature of Objective-C. It can make some code a lot more convenient to write, but it can also make certain bugs really difficult to track down. After having done Swift for a while, I'm a big fan of using an option type so that "reference to object" is a different static type altogether from "reference to object, or nil."

Yes, I really like Rust and the way its Option> decays to a nullable pointer.

Re: Yoda Conditions

#53
post #50
post #26

Earlier quoted context omitted.

There are useful cases for this. It's much less ambiguous in those cases if your language allows the definition of the variable in the same location, and scopes it. For example, Perl: use strict; use warnings; sub one { 1 } if ( my $one = one() ) { say $one; # prints 1 } say $one; # compilation error, "Global symbol "$one" requires explicit package name" This case is trivial, but when you want a temporary variable an…

Declaration and a (mutating) assignment are different: your example demonstrates that Perl signals the declaration with `my`, and other languages offer similar things like `if let ... = ... { ... }`

> Declaration and a (mutating) assignment are different

Yes, that's what I was trying to get at by saying definition, but not very clearly. It's one of the reasons I prefer languages to require and clearly indicate variable declaration in most cases.

Re: Yoda Conditions

#54
post #8

Earlier quoted context omitted.

While I don't disagree, curious to hear your reasoning for not doing this.

It's unnatural, confusing to read, and won't save you anyway in cases where you're comparing two variables. It's OK if your tools absolutely can't diagnose accidental if(a = b), but it should be the last resort.

how would you write a yoda conditional with two variables? which is the yoda conditional (a == b), or (b == a)?

Re: Yoda Conditions

#55
post #3

Don't do this. In languages where accidental assignment is possible (i.e. writing if(a=b) when you meant if(a==b) ), configure the compiler or linter to emit a warning in this situation. For example in C, GCC will complain about this when compiling with -Wall, which you should be using anyway.

What about PHP? It's in the coding standard in WordPress and Symfony... :(

Re: Yoda Conditions

#56
post #40
post #36

Earlier quoted context omitted.

One of the worst parts of Ruby. I can see the argument that it could be better to have save if valid rather than if valid save end but what I see 9 times out of 10 is things.do each |thing| foo bar baz end if valid or really.long.thing.that.i.try.to.parse.in.my.head if acutally_almost_never_happens which is harder to read since I read top to bottom / left to right, but the flow is bottom to top and right to left

You can write gibberish in any language. You shouldn't kill useful features because they are sometimes misused.

> You shouldn't kill useful features because they are sometimes misused.

That is highly debatable.

Re: Yoda Conditions

#57
post #36
post #22

I would say that the phrase "Yoda conditions" more appropriately describes Ruby's alternative form of if-statements: if x > 0: y += x versus y += x if x > 0

One of the worst parts of Ruby. I can see the argument that it could be better to have save if valid rather than if valid save end but what I see 9 times out of 10 is things.do each |thing| foo bar baz end if valid or really.long.thing.that.i.try.to.parse.in.my.head if acutally_almost_never_happens which is harder to read since I read top to bottom / left to right, but the flow is bottom to top and right to left

This is something Ruby likely got form Perl,but they cribbed it wrong. Perl's post-conditionals only work on single statements, not blocks. You can use them for functional style statements though. I.e.

    # Not allowed
    for ( 1 .. 10 ) {
        say $_;
    } if 1;
    
    # Allowed
    map { say $_ } ( 1 .. 10 ) if 1;
The idea seems to be that a post-conditional should be simple and obvious by the time you've parsed the statement. A block makes it confusing, as does mixing post control structures

Post-loop structures have the same limitation:

    # Not allowed
    { say "foo"; say $_ } for ( 1 .. 10 );
    
    # Allowed
    say $_ for ( 1 .. 10 );
When used correctly, these can become very succinct and clear.

    my %data = get_data_record_hash("foo");
    
    $data{$_} = update_field(data{$_}) for ('field1','field4',other_field');
    
    # Compare to map, which normally you expect to return values
    map { $data{$_} = update_field(data{$_}) } ('field1','field4',other_field');
The single statement limitation keeps you from going wild in ways that are probably not useful to future readers of the code (including you).

Re: Yoda Conditions

#58
post #8

Earlier quoted context omitted.

It's unnatural, confusing to read, and won't save you anyway in cases where you're comparing two variables. It's OK if your tools absolutely can't diagnose accidental if(a = b), but it should be the last resort.

how would you write a yoda conditional with two variables? which is the yoda conditional (a == b), or (b == a)?

You can't if they're both mutable, since the whole idea of a yoda conditional is to put an immutable thing on the left side. What I meant was that you can't use them in that case, so it's a technique you can't use with 100% consistency.

Re: Yoda Conditions

#59

Earlier quoted context omitted.

Eh, I think it is good in Java in cases where Null input is possible.

I never got the Java argument. I would much rather fail early and noisily with an NPE than return false and let my program happily chug along when it wasn't expecting a null. If the value is intended to be nullable, I would use an optional.

Well for 95% of Java's live, there was no such thing as Optional.

So say untrusted user input.. many cases where it could be something or null. Yoda checking it was a nice way to save a null check.

Re: Yoda Conditions

#60
Not worth the effort; modern compilers are very helpful with identifying these kinds of slip ups; and they weren't really that common to begin with, not common enough to warrant the attention and energy sucked into this never ending argument. It's a rule for the sake of having rules, like so many others.
Post reply on HN