Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Prefer Yoda Conditionals #163

Closed
Blacksmoke16 opened this issue Aug 7, 2020 · 12 comments · Fixed by #303
Closed

Prefer Yoda Conditionals #163

Blacksmoke16 opened this issue Aug 7, 2020 · 12 comments · Fixed by #303
Assignees
Labels
Milestone

Comments

@Blacksmoke16
Copy link
Contributor

https://en.wikipedia.org/wiki/Yoda_conditions

var = 1

puts "foo" if var = 1 # => foo

This compiles (and works), but is most likely a typo. If yoda conditionals were prefered this would turn into a compile time error.

var = 1

puts "foo" if 1 = var # => Error: unexpected token: =
@Sija
Copy link
Member

Sija commented Dec 6, 2021

I strongly disagree with the whole yoda notation style.

Its origin reads like a joke (after wickedpedia):

The name for this programming style is derived from the Star Wars character Yoda, who speaks English with a non-standard syntax[3] (e.g., “When nine hundred years old you reach, look as good you will not."[4][5]). Thomas M. Tuerke claims to have coined the term Yoda notation and first published it online in 2006.[6] According to him, the term Yoda condition was later popularized by Félix Cloutier in 2010.

Yoda conditions are part of the coding standards for Symfony[1] and WordPress.[2]

These are also an indication that this particular style hasn't been used widely within any community, except the two, from which the WordPress should be treated IMO as an anti-advertisement - as the code quality there was always disastrous.

Also, see the Criticism section on the above mention page.

@straight-shoota
Copy link
Contributor

straight-shoota commented Dec 6, 2021

The criticism section is incredibly thin. There is an unverified claim to be "widely criticized". It only references three random blog posts that may proof that some random people advise against using it. One of those doesn't give any reasoning, the others make their arguments on questionable assumptions and generalizations and in the scope of specific programming environments.

Rest of the section talks about specifics of some programming languages and I understand it mostly as removing some of the reasons for Yoda notation in these languages.

I don't see anything near a convincing argument that Yoda notation is bad.

That's just an observation of the Wikipedia reference. Maybe there are convincing arguments, but they're not convincingly expressed in that article nor is it backed by substantial evidence.

@straight-shoota
Copy link
Contributor

I have my own argument that Yode notation can be benefital in some cases.

if LibFoo.generate_foo_bar_baz(foo, pointerof(bar).as(Void*), baz.to_slice, LibFoo::FooTypes::BAR_BAZ, LibFoo.some_other_thing) == 0

if 0 == LibFoo.generate_foo_bar_baz(foo, pointerof(bar).as(Void*), baz.to_slice, LibFoo::FooTypes::BAR_BAZ, LibFoo.some_other_thing)

I believe the Yoda style actually reduces cognitive load here. Of course, this can be written differently. Long method calls could be split over multiple lines. That doesn't make a difference. Yoda notation is IMO also better than a ) == 0 a couple lines after the conditional keyword.

if LibFoo.generate_foo_bar_baz(
     foo,
     pointerof(bar).as(Void*),
     baz.to_slice,
     LibFoo::FooTypes::BAR_BAZ,
     LibFoo.some_other_thing
   ) == 0

if 0 == LibFoo.generate_foo_bar_baz(
     foo,
     pointerof(bar).as(Void*),
     baz.to_slice,
     LibFoo::FooTypes::BAR_BAZ,
     LibFoo.some_other_thing
   )

Yoda definitely reads better here.

Sure you could store the return value in a local variable and use that like if ret == 0 (or if ret.zero? if you like). But I'd argue that leads to less concise code, and maybe even more cognitive load.

@Sija
Copy link
Member

Sija commented Dec 6, 2021

The criticism section is incredibly thin. There is an unverified claim to be "widely criticized". It only references three random blog posts that may proof that some random people advise against using it. One of those doesn't give any reasoning, the others make their arguments on questionable assumptions and generalizations and in the scope of specific programming environments.

Rest of the section talks about specifics of some programming languages and I understand it mostly as removing some of the reasons for Yoda notation in these languages.

I don't see anything near a convincing argument that Yoda notation is bad.

@straight-shoota I don't see any convincing argument it's actually beneficial, sorry. This only argument being accidental assignment avoidance is incredibly thin, using your words - throughout multiple yrs I could count perhaps a dozen of such cases, in my code or in others'.

That's just an observation of the Wikipedia reference. Maybe there are convincing arguments, but they're not convincingly expressed in that article nor is it backed by substantial evidence.

I'm sorry but, where is substantial evidence that using yoda notation does actually any good? We have none, yet. That should be included by the OP in the first place.

I believe the Yoda style actually reduces cognitive load here. Of course, this can be written differently. Long method calls could be split over multiple lines. That doesn't make a difference. Yoda notation is IMO also better than a ) == 0 a couple lines after the conditional keyword.

Your argument is based on the fact that the line is long enough you won't scan the ending of it, but as you already noticed the 1st and foremost issue here is the line/expression length.

Sure you could store the return value in a local variable and use that like if ret == 0 (or if ret.zero? if you like). But I'd argue that leads to less concise code, and maybe even more cognitive load.

I'm not sure what cognitive load you have in mind while talking about ret.zero? - I'd call it way more expressive than having yoda + multiple line call.

@Blacksmoke16
Copy link
Contributor Author

Blacksmoke16 commented Dec 6, 2021

TBH I think you're exaggerating how big of a deal this is. I don't see how if 1 == foo is any more challenging to read than if foo == 1. Even if the benefit is small, there's still a benefit.

If this ever gets implemented, just make it disabled by default and let the user decide for themselves versus trying to shut it down just because you disagree with the style/its benefit.

@Sija
Copy link
Member

Sija commented Dec 7, 2021

TBH I think you're exaggerating how big of a deal this is. I don't see how if 1 == foo is any more challenging to read than if foo == 1. Even if the benefit is small, there's still a benefit.

@Blacksmoke16 It's written backward - that's more challenging. If you want the same argument from elsewhere - quoting the wickedpedia page:

In programming jargon, Yoda conditions (also called Yoda notation) is a programming style where the two parts of an expression are reversed from the typical order in a conditional statement.

in re:

If this ever gets implemented, just make it disabled by default and let the user decide for themselves versus trying to shut it down just because you disagree with the style/its benefit.

That's cool with me, although I wouldn't like to have it enabled by default, nor promoted in any way.

@straight-shoota
Copy link
Contributor

straight-shoota commented Dec 7, 2021

I'm not sure what cognitive load you have in mind while talking about ret.zero? - I'd call it way more expressive than having yoda + multiple line call.

It's similar to the multi-line expression with == 0. You assign the result to a variable in line x. Then there are n consecutive lines of continuation. And only in line x + n + 1 or later there is a reference to the variable again, comparing it against some literal constant. Compare that to having the latter in the first line, directly together with the name of the method that returns the value. Then everything else that follows, the entire bunch of arguments, is just an appendix to the method call.
It avoids bracketing where a part after the arguments refers back to the start.

@Sija
Copy link
Member

Sija commented Dec 7, 2021

@straight-shoota When you have a line that long, you have more serious problems than whether to write it yoda-style or not and doin' so won't fix 'em, anyway so that's a moot point for me.

@straight-shoota
Copy link
Contributor

I'm not talking about a long line, but a long expression over multiple lines.

@Sija
Copy link
Member

Sija commented Dec 8, 2021

It's an edge-case to see multi-line expression with equality check, so doesn't seem like a convincing argument either.

@Sija Sija added rule and removed feature labels Oct 30, 2022
@Sija
Copy link
Member

Sija commented Oct 31, 2022

I'm closing this issue, since there's no consensus over the validity of such rule.

@Sija Sija closed this as not planned Won't fix, can't repro, duplicate, stale Oct 31, 2022
@straight-shoota
Copy link
Contributor

straight-shoota commented Nov 5, 2022

Just my 2 cents: I personally wouldn't use this rule, but there is at least some interest in it. So it might make sense as an optional? Would still need somebody to implement it, of course.
Just closing this issue indicates it's not an immediate goal of this project (which makes sense) but it doesn't clarify whether such a contribution would be accepted.

However, I also have a superior proposal for avoiding unintended assignments in #294.

@Sija Sija added this to the 1.4.0 milestone Nov 17, 2022
@Sija Sija reopened this Nov 17, 2022
@Sija Sija linked a pull request Nov 17, 2022 that will close this issue
@Sija Sija closed this as completed Nov 17, 2022
@Sija Sija self-assigned this Dec 22, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants