4 ms·
Interesting article and definitely some good advice, but I completely disagree with example 4. Surely I can't be the only person who finds if (foo) {
by MattBearman 8y ago
Interesting article and definitely some good advice, but I completely disagree with example 4.
Surely I can't be the only person who finds
if (foo) {
if (bar) {
return true;
}
}
if (baz) {
return true;
} else {
return false;
}
Much easier to parse than
return foo && bar || baz;
It's a bit better to my eye with parentheses:
return (foo && bar) || baz;
Of course the first version is far from perfect (no need for the nested if, etc.) but I've always found too many comparisons on one line just looks messy.
- tigershark 8y agoI guess it may be because you don’t remember the Boolean operations precedence? For me it’s much, much, much easier to parse the second expression in your post than the first monstrosity. Obviously it depends from the complexity of the expression, just 1-2 weeks ago I refactored an over-complicated Boolean expression to an if-else. But in this case I’m really overwhelming in favour of the extremely simple Boolean expression, and whenever I see an over complicated if I refactor it to a simpler Boolean expression if it’s possible.
- diggan 8y agoAlso, it's not really removing the `if`, it's just making it into `&&` and `||` instead, which are shorthand conditionals anyways. So a bit misleading to call this a anti-if strategy.m
- pure-awesome 8y agoFair point. It's basically syntactic sugar. Hard to say how to properly refactor out the if statements without knowing the problem domain. And I guess that's basically the point - using if statements means that you are writing imperative code rather than modelling the problem. You are specifying to the compiler how you want things done, rather than what it is that you want done.
- pythonaut_16 8y agoIf you have a function that's using if statements to decide which boolean to return, it's almost always better to return the expression directly. `if (foo) { return true } else { return false }` is the same as `return boolean(foo)`
- pure-awesome 8y agoPersonally, I find return (foo && bar) || baz; The most readable. The top version just has too many curly braces and parentheses. I can keep each branch in mind easily, but keeping the whole program flow at once requires me to first parse it and translate it. The last version, I can read as "either baz, or both foo and bar", which is easy to keep in mind at once, and would be much easier to pattern match for errors ("Oh no, I wanted foo and baz, not foo and bar") than the top version, for which I would possibly have to iterate each potential execution path in my mind to spot a mistake. Consider, more concretely, (since I can't think of a better example), knowing whether to give someone an alcoholic drink. Let's go US style. Either they order a soda, or they are old enough and have ID. Three variables: isOver21, isSoda, isIdPresent. (Putting aside the fact that the order here is weird and it could be designed better) we can either go: if (isIdPresent) { if (isOver21) { return true; } } if (isSoda) { return true; } else { return false; } Or we can go: return (isIdPresent && isOver21) || isSoda; Now what if we accidentally swapped two variables: if (isSoda) { if (isIdPresent) { return true; } } if (isOver21) { return true; } else { return false; } vs return (isSoda && isIdPresent) || isOver21; Note how in the first case, if I am tired, I could miss it. Most of the code paths seem correct. If someone is ordering a soda and has an ID they should get the drink. If they are not ordering a soda, and they aren't over 21, they shouldn't get anything. If they are over 21, they should probably get something. In the second case, I can see all the logic in one line, and I can say "hold up, why are we asking for soda and ID, or age? Something seems off." Not that I can't do that with the multi-line if, just that it might take a bit longer. Source: I've been bitten by multi-stage if statements on a few occasions.
- ballenf 8y agoDoesn't the if version also have the possibility of an unintended undefined return value (maybe JS only)? I've been bitten by that before and thinking through all the possibilities when using multiple ifs is harder to me than with a boolean expression where a truth table can be used as a formal proof of validity. The other downside to ifs is that the order of the ifs matters. That makes the code more brittle and requires the reader to parse the code on two levels: thinking about the booleans and keeping their values in mind over multiple lines of code. In a short sequence it's not a big issue, but it can be annoying when a very distant if statement affects your reasoning much later. Of course order matters without ifs, but everything important is on one line. So the boolean version keeps all the relevant reasoning in one place -- no need to scan multiple lines of code (and risk missing an important guard).
- hellofunk 8y agoIt is a fairly well-known fact that -- most of the time -- fewer lines of code translates to fewer bugs and decreased maintainability costs. Moving from 11 lines to 1 line is, for me, vastly superior readability. And anyone who has been programming for a couple years at least would have no problem parsing the order of operations and precedence between && and || (logical 'and' is always higher precedence than logical 'or' in every language I've seen), but parenthesis are a trivial addition if desired.
- deleted 8y ago[deleted]
- majormajor 8y agoI think it depends on what you're trying to do. Is the expression a fundamental business rule? Then splitting it up runs the risk of introducing error/inconsistency, I think. But if you're just trying to condense down separate business rules, where it happens that today that you want the same thing in the case of `baz` as for `(foo && bar)`, then you're setting yourself up for a more painful change when someone comes to you and says "hey actually let's have `baz` do the other thing after all. Yeah, in the trivial case where it's just returning bools, that's not really an issue, but when I see code that looks like the former it's usually more complicated, and the overlap is more often incidental rather than fundamental. So my approach is more "remove nested ifs" than "simplify it into as few cases as possible."
- deleted 8y ago[deleted]