4 ms·
I've seen a lot of heavy nesting caused by the belief that functions should only have one return statement. Ex: // Original function render() { $
by bwh2 14y ago
I've seen a lot of heavy nesting caused by the belief that functions should only have one return statement. Ex:
// Original
function render() {
$return = null;
if($condition1) {
if($condition2) {
$return = 2;
} else {
$return = 1;
}
} elseif($condition3) {
$return = 3;
} else {
$return = 4;
}
return $return;
}
But I'd rather read:
// Refactored
function render() {
if($condition1 && $condition2) return 2;
if($condition1) return 1;
if($condition3) return 3;
return = 4;
}
- ehsanu1 14y agoYes, the factored version is much clearer. Though you want to make sure the refactored version is equivalent, which it isn't in your case due to a change of order.
- bwh2 14y agoSorry, should be fixed now.
- vonmoltke 14y agoI worked on a program where the management had near-religious devotion to the one return statement paradigm. It made for a bunch of unnecessary nesting and locals just to comply. Even worse was strong resistance to using continue and break (outside of switch statements), which lead to unnecessary flagging variables on top of that.
- btilly 14y agoI would show them http://www.cis.temple.edu/~giorgio/cis71/software/roberts/documents/loopexit.txt http://www.cis.temple.edu/~giorgio/cis71/software/roberts/do... and hope it changed some minds.
- SideburnsOfDoom 14y agoIn which language was this rule enforced? See http://anthonysteele.co.uk/the-single-exit-point-law http://anthonysteele.co.uk/the-single-exit-point-law and http://anthonysteele.co.uk/returning-to-multiple-exit-points http://anthonysteele.co.uk/returning-to-multiple-exit-points
- whileonebegin 14y agoMaybe so, but what happens when you need to do something before returning the value, say like closing a connection? You'd have to make the change in 4 spots (and hope you don't miss one), as opposed to the first example where you'd only have to make the change in 1 spot. It's all about minimizing errors later on.
- MBlume 14y agoWrap in another function. ETA: I'm amused by how easily the LISP philosophy applies here: any problem can be solved with enough lambdas.
- fferen 14y agoI know, right? I was writing this complex OO solution to a problem in Python, then I realized I could just do it with a function returning a closure.
- bwh2 14y agoThen do something like hxa's example. Maintaining a return variable isn't always bad, it's just weird to think of it as functionally better than multiple returns. I tend to find a lot of errors and bugs in heavily nested code because it involves tracking a lot of variable state.
- SideburnsOfDoom 14y ago> Maybe so, but what happens when you need to do something before returning the value, say like closing a connection? Then your choices include a try...finally block, a "using" statement if you're in c#, or ... limiting yourself to only 1 return. Multiple returns don't fix the problems in all cases, just most of them. I'm assuming that this is on a language that has automatic garbage collection. The 1-return rule came about in C, which does not and so has a lot more cases where manual clean-up is required.
- hxa7241 14y agoAt least have an honest comparison: function render() { $return = null; if($condition1 && $condition2) $return = 2; elseif($condition1) $return = 1; elseif($condition3) $return = 3; else $return = 4; return $return }
- bwh2 14y agoI was comparing what I frequently see vs what I'd like to see. Your example code is pretty rare in my experience. So I think the comparison is pretty fair.
- VMG 14y agoAnother example r = 0; outer: { foreach (x in a) { foreach (y in b) { if (condition(a, b)) { r = 1; break outer; } } } return r; instead of foreach (x in a) { foreach (y in b) { if (condition(a, b)) { return 1; } } } return 0;
- deleted 14y ago[deleted]