"Never use early exits" is exceedingly bad advice, in my experience. What has led up to your claim that early exits are bad? As I've gained experience, I find myself writing code like this more and more:
if (UnexpectedOrUnhandledCondition(x)) {
...
return false;
}
if (OtherError(y)) {
return false;
}
and so on. Serial code like that is trivially easy to understand when reading; more importantly, six months later, it's far more explicit and easier to comprehend than the comparable single-exit version.
The alternative to early exits is nesting, and nesting is the readability killer. My experience has apparently been just the opposite of yours: that avoiding early exits is a sign of a junior programmer, and returning early whenever possible is a sign of an experienced programmer who knows that understands code maintenance.
I agree. The alternative as you state is nested conditionals. Yuck! An alternative construct I have seen and used is to wrap code in a do {} unless(0) block and break to a single failure return or complete the block to a single success return.
The alternative to early exits is nesting, and nesting is the readability killer. My experience has apparently been just the opposite of yours: that avoiding early exits is a sign of a junior programmer, and returning early whenever possible is a sign of an experienced programmer who knows that understands code maintenance.