3 ms·
The error checking example conflates two different things: • Early returns vs. single return. • Excessive nesting vs. simpler flatter if/else. The real probl
by Stratoscope 11y ago
The error checking example conflates two different things:
• Early returns vs. single return.
• Excessive nesting vs. simpler flatter if/else.
The real problem with the "before" example is the excessive nesting. I do prefer early returns myself, but even if you wanted to use the single-return style, you could simply un-nest the whole thing:
public string Execute( int integer, string str, bool boolean ) {
string result;
if( integer <= 42 ) {
result = "Error: Integer is too small";
} else if( string.IsNullOrWhiteSpace(str) ) {
result = "Error: String is null or empty";
} else if( ! boolean ) {
result = "Error: Incorrect boolean";
} else {
result = "Success";
}
return result;
}
It's a bit ironic that this is C# code, because ReSharper would offer to un-nest the code for you.
Also, this really has nothing to do with tail call optimization.
- barrkel 11y agoFrequently the checking is dependent on passing the previous clause. Something like: if (x == null) return "x is required"; if (x.length < 3) return "too few elements in x"; if (x[0] == null) return "first element missing"; The point here being that each successive check is testing something that is only valid if the previous check passed. This can't be so easily converted to your if/else pattern without re-encoding the early exit in the form of a complex boolean (&& and || have early exit built in). The concept's applicability to tail call optimization is only by analogy with the mental stack; just as tail call optimization sets up the call such that the current stack frame no longer exists, early exit sets you up to remainder the rest of the code without regard to any potential alternate code paths (i.e. a potential else branch on an early if statement) later; the mental frame of a long if statement no longer exists. The analogy is a little bit stretched; of course it is not a technical isomorphism, but nobody ever said it was.
- Stratoscope 11y agoAs I mentioned, I prefer early returns as well, and I wasn't recommending the if/else structure as an alternative to early returns. My only point in showing that code was to illustrate what I see as the bigger problem in the example: the use of nested if and else statements when non-nested ones could be used instead. Personally I would get rid of the nesting by using early returns, but for someone who objects to that for any reason, the non-nested if/else chain is a nice alternative. Also, the series of returns you show here could easily be written as a chain of if/else for those who prefer that style. I'm not sure why you said it requires a complex boolean expression; this code is equivalent to the series of returns: string result; if( x == null ) { result = "x is required"; } else if( x.length < 3 ) { result = "too few elements in x"; } else if( x[0] == null ) { result = "first element missing"; } else { result = "the real result"; } return result; Again, I don't particularly like this style, although it is better than the deeply nested if/else. I prefer the series of returns that you listed in your comment.