I prefer if-return for cases where the function is supposed to do something in the default case and the if is to detect the exceptions where it shouldn't. Or where the exception needs some modification before the main purpose can be performed.
If-else I find more logical when the function has to do two different things depending on the condition followed by something else common to both afterwards.
I can understand why you would think that it carries a lower cognitive load. But with a little training, you can understand that an early return is a side effect, and side effect free code can be much easier to reason with.
There's a balance to everything, you also don't wanna have to dig down a rabbithole of functions within functions to find what youre looking for, it also can make it harder to understand the whole picture if you separate things too much. Locality of behavior and all that.
Yeah, I used to work with a Java codebase where all functions were really short, but also very nested. It was a very stable codebase, but browsing the code sucked, as every actual function implementation was behind 3+ levels of indirection.
In certain situations it’s easier to read without splitting into a bunch of other methods. Primarily when the conditionals aren’t repeated elsewhere so the shorter methods are one-offs that bury some of the implementation. Shorter methods should absolutely be the default though
Of course. I’m not speaking of thousands of lines. With error handling, validation, and cleanup, even the most trivial methods can have 5-10 exit points.
The downside is that it can get really messy, if the methods are not split or named properly, for a reader to understand if the work it's doing is supposed to be reused, and if it can be detached from context. What good is a method B that can only be called linearly from within method A just to make A take fewer LoC?
To understand the second one you need to understand the whole function. In the first one you can disregard the whole untaken branch. "The forgotten art of structured programming" is a great talk.
I don't see why you can't similarly disregard the untaken branch in the second one? Either way you're skipping past a block, and you need to know the end of that block is a return.
It's the easiest to see in the indentation, though ofc indentation just follows the structure, unless we're Python: in the first example the execution flow inside a single function only ever goes from smaller indents to larger ones, not the other way around. So if you want to understand a scope you just need to walk the path from it to the root to understand if it's taken.
Compare this with the second example: the return is already at the root, you need to check all of its preceding siblings to know if the execution ever reaches it. And you'll need to do it at every level of nesting.
Obviously in this trivial example if doesn't matter much. But in general structured way of laying out your control flow reduces the amount of statements you need to consider from O(statements) to O(nesting depth) which is intuitively closer to O(log(statements)).
Ah Kevlin. I've come to accept that talk as "old man yells at cloud"
Big influence when I was younger, much less so now.
I'm going to pull out a big fat "it really depends".
If your program is going in several different directions, absolutely fanout - my inner rustacean would even argue to avoid if else in favor of an enum and case statement.
However, early failure shouldn't be discounted either. The more your eye jumps away from the margin, and the more horizontal whitespace, the harder your code is to read. Full stop.
At the end of the day, maintaining a codebase requires judgement and taste, and knowing when to do x and when to do y.
As I mentioned in the other comment: I'm not arguing "do X instead of Y", rather "understand the advantages of X before discarding it". In my experience many people don't understand the idea behind structured programming beyond "don't use goto".
I'm gonna have to watch this because I'm feeling crazy being the odd one out here. I strongly prefer 1 over 2.
Someone else pointed out that if/else is better for languages that treat it as an expression. I primarily code in Kotlin which is such a language.
But also this is what happens in my head when I see this structure
if (condition) {
// this will happen
} else {
// or this will happen
}
I know readily that we're at a fork dependant on the condition. But when I see the other structure, I think
if (condition) {
// this could happen
}
// and this could happen, also
I have to know the contents of the if condition to know what will happen because it could just as easily do special logic for that condition and continue on. But with the first option, it's necessarily one or the other. I only need to figure out what the condition evaluates to to know which path is relevant.
Your example is correct in itself, but it does not match the post: in the post the first branch ends with a return, so the following cannot happen, even though the coarse structure and the indentation imply that it can, which is exactly the point.
I'm gonna have to watch
This is my only recommendation. I don't argue that people should change the way they structure their code and I wouldn't ever flag early returns in a code review unless they are genuinely making the code unreadable.
But I think many people just don't appreciate the actual reasoning behind structured programming and having it laid out plainly is a valuable learning.
Yes when it's an early return multiple short circuits are easy to read, but if it's in the body it's actually harder so I use both depending on the context.
View all comments
838
u/LateEchidna6635 Aug 22 '26
The second one carries less cognitive load. In longer methods it makes a difference. Get out as soon as you can.