I prefer the first approach, it's ensures all cases are covered, and is more extensible IMO.
I also prefer a single return per function, excluding sometimes null / wrong validations, as this code tends to be easier to read and debug. In your example, I would use the first method, but assign the return value to a variable, and return it after the statements.
Every 'if' statement has a matching 'else' (exception: simple error
checks for a client API call)
Things that may seem obvious are commented explicitly
We call this style 'space shuttle style'. Space shuttle style is meant to
ensure that every branch and condition is considered and accounted for -
the same way code is written at NASA for applications like the space
shuttle.
TIL about "space shuttle style", very interesting.
I'm not sure if the Kubernetes controller source is meant to be used as an example though. Otherwise there would be no comment to warn people from simplifying the code.
In this case, both examples are the exact same of course.
This is somewhat related to a single return statement in a function, but the syntax of an if/else if/else is more explicit than the various conditions are related to each other.
With few if statements each statement is independent from the others (unless you return in the previous cases, like in your example), therefore more than one of them can be triggered.
Overall, while there aren't many arguments for any of these approach in your specific scenario, I feel like it's a better practice to have a single style of conditions for your whole codebase. As the first approach is more flexible, I strongly prefer using it everywhere!
Consistency is definitely most important. I just did a search through an API that I built recently, and I only have 3 else statements which I can probably refactor out. So, I think it's definitely possible to go all-in on early returns.
In other languages such as Scala and Rust there is a "match" statement and a compiler that looks at the types can tell you if all cases are matched. In Scala you can compose/chain together sets of partial methods that match a set of related cases and the compiler will tell you if the combination will do an exhaustive match. So what the Kubernetes example you post is pointing out is that the devs are having to work around a missing feature in the language they are using. Once you have used a language that has an exhaustive match you never want to go back. This is because it is very much easier to write code that you know won't just fall through to some wrong default case when someone adds a new type of input.
For further actions, you may consider blocking this person and/or reporting abuse
We're a place where coders share, stay up-to-date and grow their careers.
I prefer the first approach, it's ensures all cases are covered, and is more extensible IMO.
I also prefer a single
return
per function, excluding sometimes null / wrong validations, as this code tends to be easier to read and debug. In your example, I would use the first method, but assign the return value to a variable, and return it after the statements.This made me thing of this post on hackernews: Please do not attempt to simplify this code
TIL about "space shuttle style", very interesting.
I'm not sure if the Kubernetes controller source is meant to be used as an example though. Otherwise there would be no comment to warn people from simplifying the code.
Can you elaborate on the "cases are covered" point? In my mind both snippets covered all cases, but I'm open to hearing otherwise.
In this case, both examples are the exact same of course.
This is somewhat related to a single return statement in a function, but the syntax of an
if/else if/else
is more explicit than the various conditions are related to each other.With few
if
statements each statement is independent from the others (unless you return in the previous cases, like in your example), therefore more than one of them can be triggered.Overall, while there aren't many arguments for any of these approach in your specific scenario, I feel like it's a better practice to have a single style of conditions for your whole codebase. As the first approach is more flexible, I strongly prefer using it everywhere!
Consistency is definitely most important. I just did a search through an API that I built recently, and I only have 3
else
statements which I can probably refactor out. So, I think it's definitely possible to go all-in on early returns.In other languages such as Scala and Rust there is a "match" statement and a compiler that looks at the types can tell you if all cases are matched. In Scala you can compose/chain together sets of partial methods that match a set of related cases and the compiler will tell you if the combination will do an exhaustive match. So what the Kubernetes example you post is pointing out is that the devs are having to work around a missing feature in the language they are using. Once you have used a language that has an exhaustive match you never want to go back. This is because it is very much easier to write code that you know won't just fall through to some wrong default case when someone adds a new type of input.