Wednesday, February 15, 2012

Functions with Multiple Exits

Dr Bob suggests that multiple exit points make a function harder to maintain.

With respect this is one of the few times when I completely disagree.

For any function call the best practice is to validate all inputs, do some calculations, and then do the main event. At each step in the process we have a potential for an exit.

Is the input invalid? Exit
Is the calculation out of range? Exit.
Is there a trivial answer? Exit.

The goal of an early exit is to make code run faster. Test for the simplest possible answer and take that exit if you can. When I teach this I always tell people the first and most important question we ask ourselves all the time is "Are we done yet?"

Some people like to set a flag in the code. Loosely pseudocoded as:
if (some dumb stuff) then
Error:=1;
End if;
More code
if (Some more dumb stuff) then
Error := 2;
end if;
More code
if (error > 0) Then
result := Error;
else
result:= myResult;
end if;
Return result;
End function;

Some how this is said to be less clear than
if (some dumb stuff) then
Exit(1);
End if;
More code
if (Some more dumb stuff) then
Exit(2);
end if;
More code
Return myResult;
End function;

Well, I think the answer is clear just from the pseudocode. But the discipline to code that way takes some practice. In this example it isnt really all that bad, but in practice all those ifs get pretty crazy. We end up deep inside a loop or some calculation, find an error somewhere in left field and then have to code a bunch of flags from deep deep. The flags usually end up making a mess of the code, and so instead programmers throw lots of exceptions when they should just return a valid value. I cant remember how often in code reviews I have punted a function definition because it needed to return zero or something as a valid result instead of throwing an exception. I am a sticker for results and wonky function results are not acceptable even if the pain of making them is quite large. Now we have a language construct to help us. Will it get abused? Ofcourse. But it will also make code clearer when it is applied well. At least the intention is clear with Exit(x); There is no where else to go but out of the function call. If we need to play with variables, flags and conditionals to force execution stoppage that will definitely add to the fray.

Now I need to figure out what happens in a try .. finally block that has an exit. I hope the cleanup code runs. Pretty sure it will.


No comments:

About Me

Winnipeg, Manitoba, Canada
Messianic Jewish adherant Software architect music enthusiast