> Every added level of nesting is another piece of context that your brain has to keep track of.
I disagree entirely. Nesting manifests the conditional-evaluation context in the presentation of the code. Without nesting, the context shifts must be held purely in the mind of the programmer (instead of offloading that storage to the layout of the code.) In dynamic languages especially, I've also found that early returns lead to more test failing while refactoring (or more bugs if the code has low test coverage.)
The issue I have with named functions (as shown in the article) is that context for inner blocks must be passed through the outer blocks, which means your intermediate function signatures have some irrelevant (to the local scope) cruft. There are some rough corner-cases where nested code is far less complicated than juggling context batons.
With early returns, there are no context shifts. You're just getting rid of contexts as and when they are looked at. So there's no question of keeping a stack of context in mind.
What you say works well when you can physically see the structure in the code. With deep nesting in large functions, you can't - it's easy to get lost in it.
That said, I can understand what people say about multiple returns leading to bugs in refactoring - personally, I always prefer early and multiple returns to nested code, and I've developed the habit of checking the full function for any exit points whenever I refactor it.
There is actual evidence to back up his original statement, and even to say that nesting increases defects. It's called cyclomatic complexity, and can be tested for quite easily.
It's a compromise. The end point is to improve readability and understand-ability of your code. Sometimes nesting play well. I think the author took a very simple example just for the sake of it. The reality is when you don't have alternatives, you end up with spaghetti code.
I disagree entirely. Nesting manifests the conditional-evaluation context in the presentation of the code. Without nesting, the context shifts must be held purely in the mind of the programmer (instead of offloading that storage to the layout of the code.) In dynamic languages especially, I've also found that early returns lead to more test failing while refactoring (or more bugs if the code has low test coverage.)
The issue I have with named functions (as shown in the article) is that context for inner blocks must be passed through the outer blocks, which means your intermediate function signatures have some irrelevant (to the local scope) cruft. There are some rough corner-cases where nested code is far less complicated than juggling context batons.