It can sounds like I’m asking you to walk on one foot, but in fact, I’m more likely to ask you to stop walking on all fours.
I first discovered this rule thanks to PHPMD:
I did not really understand why but I found it fun and started to try. It’s not specific to the language, I will show examples in PHP, but it will be generic enough to work in most other programming languages. Let’s try together and see what difference it makes.
Result is exactly the same. But with the second one, we make a bit more obvious than the method always return a value. Indeed, if we start having nested if-else, the default value can be very nested too.
OK, you think it does not seems revolutionary yet. Then you may think this one is easy but what would happen if I had something to do after the else statement:
Sounds now like I can’t use early return statements and so can’t get rid of else statements.
Yes I can. Here the else rule helps to see I may have given too much responsibility to my function. Beside PHPMD also recommend not to use boolean argument (https://phpmd.org/rules/cleancode.html#booleanargumentflag) like I did with $important for the same reason.
Those both rules are telling me: if you can’t write one function without breaking those rules, then you should split it into smaller ones.
Following the rules leads us to rewrite functions with a clear and more atomic responsibility for each. Now instead of calling getWaterState(40, true or false) we call getWaterState(40) or getImportantWaterState(40)
An other example:
I know we could simply remove the first else by re-use the same variable $degrees, but let’s say we don’t want to mutate function input and would use $celsiusDegrees to make it more explicit that this is the scale we finally use for calculation.
OK so how could we possibly remove the else
if we do not want to too many functions later(getWaterStateFromCelsius, getImportantWaterStateFromCelsius, getWaterStateFromFahrenheit, getImportantWaterStateFromFahrenheit), then 2 options to consider:
The ternary operator:
I know the ternary operator is disliked by many as not very explicit except in some languages like Python or CoffeeScript where you would actually still have “if” and “else” words. And you may think ternary expression is just some short style of if-else, but not exactly. The big difference is the statements if {} else {}
represent 2 different actions (in each block of code), while a ternary is meant to return a value. In the code above, we actually do the same action (assign $celsiusDegrees) in both if
and else
but with a different value. That’s why the ternary operator actually makes sense and why it allows us to simplify the duplicated code $celsiusDegrees =
because we use it as a value selector rather than a operation switcher.
The ternary is never the lonely option. You also can use an intermediate function:
It gives clear name to each operation. Each method proceed its very own specialty and delegate to an other one what doesn’t belong to its role.
Conclusion
I do not say we couldn’t reach this result keeping else
statements. And I do not say we can’t have messy code without them. But following this rule will lead you more easily with a code respecting the principle of single responsibility.
And remember, none of the recommendation any tool can give you can be universal, no-else-rule like many other are just code smell, meaning the tool tell you: “Hum, smell like you had to use else
probably because the function containing it has too much responsibilities.” but the tool does not detect (yet) why you used it exactly, it just points to you things to check. And you never should follow orders of your cleanup tool without questioning the relevance of it in the given situation, like when it warns you have “duplicated code” (see https://www.sandimetz.com/blog/2016/1/20/the-wrong-abstraction).
So my personal recommendation would not be to never use else
but to always try something else first.