I think the bigger problem you may be experiencing, if I had to guess, code structure.
If people tend to write:
function foo(x) {
if (x == null) {
return null;
}
// do some stuff to the code
for(a reason) {
// do some more stuff
if(some detailed reason) {
return null;
}
// more things
return 7;
}
Then the shape of the code and the "pattern" of early returns gets broken.
If you read code where all of the short-circuit, early-return logic is at the start of the function, and then all of the work is done, do you still have this opinion?
E.g.
function foo(x) {
if(x == 1) { return null; }
if(x == 2) { return null; }
if(x > 7) { return null; }
// do things with x
return 7;
}
?
The problem is definitely much worse when returns are scattered throughout the function instead of grouped at the top, but I still prefer them to be "elsed" together (or in a switch/cond/match statement or whatever). Worth noting that in Lisp - one of the classical languages where early-returning is popular - there isn't a problem because it is done as I describe:
If you want elses everywhere, how do you protect yourself from nesting hell? I find nesting hell to be far, far, faaaar worse for readability than any of the alternatives, and will move to the early return model to escape all that nesting.
I dunno, I just rarely ever find myself nesting more than two or three levels of conditionals even in extreme cases. If my logic really is that complicated, it's probably a sign it needs to be broken up anyway. And if I did need that much branching, I would want to be more explicit about it, not less.
Also - at the very least - you can mimick the "flat" early-return style and just stick some else's in there and call it a day. That's my main point; less so the actual deeper nesting
If people tend to write:
Then the shape of the code and the "pattern" of early returns gets broken.If you read code where all of the short-circuit, early-return logic is at the start of the function, and then all of the work is done, do you still have this opinion?
E.g.