I’ve gotten into several heated discussions recently (I wouldn’t call them arguments or fights as no blows were exchanged and we departed as friends) about whether an if-statement should always include a balancing
else clause in languages where it is not mandated by a ternary if form.
My feeling is a firm “no”.
Let me attempt to represent the opposing viewpoint. As far as I can tell, the “yes” faction believes that as proper diligence, an else clause should always be added to address both truth scenarios, even if the clause is populated with nothing other than a comment saying “this clause intentionally left blank”. It promotes a consistent inspection of all possible cases, on par with a
switch statement requiring full coverage.
I firmly disagree. In my opinion, if-statements boil down to three scenarios:
- Special Casing: Action that applies solely to certain logic conditions, where the absence of those conditions has no effect in the logic. In such case, I recommend to skip the
else. There’s no point to it as the flow of execution continues past the additional steps introduced by the if-statement. Adding an else statement removes the clarity of the step-by-step logic and reduces the weight of the special casing in understanding the code.
- Either-Or: Separate actions of approximately equal weight that apply to both outcomes. If statements are naturally biased towards the positive clause. If both statements are weighted the same, consider refactoring to
switch. Even if the
switchis ordered (as it must be in some fasion), a
switch-statement reduces the emphasis given to either outcome. If both cases are quite large, consider breaking out functionality to dedicated methods. Further, if the logic overlaps between both cases, consider localizing the conditions closer to the differences, even if the test may be applied several times.
- One case complex, one case simple: Actions that are of disparate impact or weight, where one clause greatly exceeds the complexity of the other, I always place the more complex clause first when used in an if-statement to emphasize the positive path. At the same time, if the simple case is non-trivial, this is an opportunity to consider whether the logic should be broken up or refactored in some way. If an if-clause is so significantly big that it takes up the majority of a method implementation, perhaps you should be using early return for the lighter condition and promoting the more complex logic to the main method body. To me, a heavy complex if-clause usually signifies an opportunity to refactor.
Given these styles, I don’t see any reason, whether from code-reading clarity or a strict adherence to potential future expansion, to automatically include
else-clauses as a mandatory part of a coding style. They add heaviness without real functionality and speak to a philosophy of form weighed over functionality. Code should be light, clear, and direct. Mandatory-
else is none of those things.
Am I wrong? Go ahead, convince me otherwise. I’m listening.