April 13, 2004
Writing readable code that's easy to debug 101

Multiple return statements in one method are bad, m'kay?

Posted April 13, 2004 11:10 PM in Java
TrackBack URL for this entry: http://www.unix-girl.com/mt/mt-tb.cgi/1197
Comments
On April 13, 2004 11:32 PM Jeremy Zawodny added:

Even when they simplify reading the code?

#
On April 13, 2004 11:37 PM kasia added:

They never simplify debugging code.. and it's a rare case when using multiple return statements in Java simplifies reading code.. That may just be my experience though.

#
On April 14, 2004 12:03 AM George Schlossnagle added:

I'll toss my vote in with Jeremy's. I often find multiple return statements can reduce covoluted ramblings to propogate a return value to the end of a loop, and/or avoid deeply nesting conditionals.

But maybe that's just me.

#
On April 14, 2004 12:04 AM kasia added:

End the loop? Break?

#
On April 14, 2004 02:50 AM Pontus added:

I don't recall having had problems debugging code because of multiple returns, and I think code tends to be somewhat less readable when you try to use one return statement [lots of protective if(EVERYTHINGS_FINE) ...].

To get out of loops, labeled continue/break helps somewhat, but I'm still not really comfortable with them.

#
On April 14, 2004 02:54 AM Charles Miller added:

I'll agree with Jeremy, too.

You can really clean up a method with a well-placed return statement or two. I find it a lot easier to read methods that return as soon as they have reason to, instead of hanging on because they need to reach some single exit-point.

The only disadvantage I see for debugging is that it's slightly harder to log a method's return value inside the method. Kasia: Maybe an example of what specifically annoyed you?

#
On April 14, 2004 03:25 AM Luis added:

Everything used in the smart way its ok, surely there is not difficult to find neat multiple returns and very ugly ones.

BTW I hate even more the evil habit of returning Object in methods that only can return 1 or 2 different object types forcing to cast everywhere to get the same kind of object again and again. Maybe its just me, but it was a nightmare when I was profiling the code of my coworkers.

#
On April 14, 2004 06:26 AM tariq added:

Reminds me of the good ole' days when discussions about coding standards the topic of the day.

Multiple return statements are "neccesary evil", better if they can be avoided, and should not be a practice.

#
On April 14, 2004 07:18 AM Robert Watkins added:

It's not multiple return statements that are the problem: it's convoluted logic.

If you have simple, clean methods, then having three or four different exit points aren't a big deal: especially when most of them are "early-exits" dealing with error handling.

IMHO, 99% of the time that multiple return statements complicate debugging, it's the convoluted logic around the returns that cause problems. Having code that needs to set external "retValue" variables, and break out of (possibly nested) loops is often even harder to read or debug.

#
On April 14, 2004 08:03 AM kasia added:

Anyone who has ever relied on weblogic for testing code should know how hard it is to keep it from core dumping when running in a debugger (seriously, it's a huge problem) and unit tests aren't always practical since the test environment cannot be accurately duplicated (otherwise, you just wrote an EJB server, congrats)... Hence debugging with print statements, while primitive, is very useful.. Now do that effectively when you have multiple return statements.

Well structured code can be readable w/o the use of multiple return statements.. there are ways to avoid nested loops and chains of if/elses. So okay, maybe this is a personal issue, but it's a grating one for me.. everytime I run into this it's convoluted logic and the code is *not* easier to read but harder.

Guys, I'm talking about Java, an object oriented language.. if your code becomes easier to read by creating multiple return points, perhaps it's time to look into restructuring it into methods/object? There's this old adage.. if a method doesn't fit on the screen it's too big.

#
On April 14, 2004 08:08 AM kasia added:

Luis, that's not bad, that's evil..

#
On April 14, 2004 08:45 AM Randy added:

Sorry - I'm fine with multi-returns as well both for me and from students. Especially when dealing with a lengthy run of network related code.

Think of it this way... if I used an if to go into each section of code that passes, rather than using the return to hop out of the loop, and I've got 12 if's to go through, I'll be so indented in the code that I won't be able to read it without horizontally scrolling... instead I code the if's by exception: if the 3rd part of the chain fails, get out of the proc and ignore the other 9... just feels cleaner.

#
On April 14, 2004 08:59 AM kasia added:

Look at it this way.. you're running production code, something goes awry.. so you turn on debug and examine everything.. with multiple returns, you suddenly either (a) never reach the end of the method were all relevant data is dumped out (return value, for instance) or (b) need to put out debug output at each return.. suddenly simplification is no longer a reason.

in case of chained calls like that, Randy.. why not use a case statement?

'kay, so there are as many ways of coding as there are programmers, if you're fiddling with my code though, don't do that, how's that :)

#
On April 14, 2004 09:26 AM Rafael Alvarez added:

Kasia, how are you debugging the weblogic operation?

I tried to debug it remotely (using the JPDA) and it crashed badly sometimes.

What I did is to run it as an application inside my IDE debugger. That way I'm able to put breakpoints at sevlet, POJOs and EJB and it works like magic.

The only caveat is that you can't "step into" a method in an EJB (it crashed my debugger also). Instead you must put a beakpoint in the implementation on the method you need to debug.

#
On April 14, 2004 09:57 AM kasia added:

Rafael, I use a socket connection to the JVM, for various reasons, that's my only choice, and yah, you can't really set breakpoints at methods, need to do it at lines of code.. (did I mention I hate weblogic? JBoss has *none* of these issues and it works at a decent speed in a debugger).

I see I'll have to do an entry tonight on named code blocks in Java :)

#
On April 14, 2004 02:03 PM Tom Copeland added:

PMD can check for this:

http://pmd.sourceforge.net/rules/controversial.html

Note the ruleset name, though - "controversial". It's in there alongside AssignmentInOperandRule and AtLeastOneConstructor.

#
On April 14, 2004 02:08 PM Neil Weber added:

I agree with Roger and Jeremy: multiple returns can definitely make code more readable.

What I've seen in some peoples code that makes debugging hard is huge multi-line conditions or expressions. For debugging purposes, it's beneficial to break the condition or expression in smaller chunks and create a tempory variable for each chunk. That way I can easily dump out the various chunks in a debugger or via a System.out.println() to find out why things are going awry.

#
On April 14, 2004 03:03 PM R.J. added:

It seems unusual to me to write code in a certain way because of debugger limitations.

I personally find multiple return statement algorithms to simply be another tool in a developer's toolset, nothing more, nothing less.

I become very leery of any rule in software development that begins with 'Never...' or 'Always...'.

#
On April 14, 2004 06:47 PM Alan Green added:

In a short method, I find multiple returns OK, but I can understand that they would make it difficult to log or print the method's return value.

I've only ever seen "break" used in the middle of code that is far too complicated, and should be refactored into separate methods anyway.

As for "continue", that only seems to be used in multi-page for loops.

I suppose it's what you're used to.

#
On April 14, 2004 10:32 PM Aristotle Pagaltzis added:

Kasia says: "in case of chained calls like that, Randy.. why not use a case statement?"

He's not talking about chained ifs testing similar conditions -- he's talking about *nested* ifs, each testing for success of the previous section of code. Basically, each if is a checkpoint.

That's something completely different from what case is for.

For checkpoints (or guard statements, or however you might prefer to call them), it is indeed much clearer to return on failure rather than nest down another level on success.

#
On April 14, 2004 10:36 PM kasia added:

yes, you're right.. i misunderstood, but fear not, not only do I understand what case statements do -- I even have an answer to Randy's dillemma in the next entry..

#
On April 15, 2004 03:12 AM Will Sargent added:

I disagree.

#
On April 15, 2004 03:13 AM Will Sargent added:
On April 16, 2004 01:02 AM Maciej Ceglowski added:

There is no excuse for multiple return statements - you can just use a single return statement and put GOTOs in the code where needed.

#
On April 19, 2004 08:06 AM David added:

If you're just debugging with multiple returns statements and can't be bothered with adding multiple debug statements to get the return value (copy and paste anyone?), you could always wrap all the function's code in a try..finally and do the debug in the finally.

Remove the try..finally after your debugging though to avoid the performance hit.

#
Trackbacks