aspose file tools*
The moose likes Beginning Java and the fly likes single return statement: yes / no? Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Java » Beginning Java
Bookmark "single return statement: yes / no?" Watch "single return statement: yes / no?" New topic
Author

single return statement: yes / no?

M Easter
Ranch Hand

Joined: Feb 11, 2007
Posts: 133
Folks,

A friend and moderator has assured me that this topic might be of interest to this forum. It is simple enough to understand that it can easily fit in the beginner's area.

I'm curious if anyone insists on using a single return statement in a Java method. I believe it is a "best practice" -- a old, timeless technique from languages gone by. Others believe that a single return is an anachronism; there is even a refactoring pattern these days called "guard clause" which explicitly returns early (see http://tinyurl.com/2d6msh)

What do you think?

Mike

ps. I have blogged on this fairly extensively and there is some debate there (see http://codetojoy.blogspot.com). I have dubbed the issue as an "alligators versus crocodiles" because people tend to fall in one camp or the other (and yet it is more substantive than the "religious wars" of trivial things like brace placement).


M Easter
Software Composer - http://codetojoy.blogspot.com
Jeanne Boyarsky
internet detective
Marshal

Joined: May 26, 2003
Posts: 30324
    
150

Mike,
Definitely an interesting topic.

What about a third choice of "no more than two return statements" ? I'm in that camp. Having two makes sense - a guard and the "real" one. More than that tends to result in code that is too difficult to refactor because returns are strewn throughout.


[Blog] [JavaRanch FAQ] [How To Ask Questions The Smart Way] [Book Promos]
Blogging on Certs: SCEA Part 1, Part 2 & 3, Core Spring 3, OCAJP, OCPJP beta, TOGAF part 1 and part 2
Bear Bibeault
Author and ninkuma
Marshal

Joined: Jan 10, 2002
Posts: 61010
    
  65

I'm an old and seasoned graduate of the School of Structure Programming. My first real language (I don't count BASIC) was FORTRAN. So by nature I tend to have one return statement per method, just out of habit if nothing else.

But no hard religion. I don't consider multi-returners blasphemers, and I never try to tell anyone that single-return is the one true way to light and goodness. And if it makes sense for a method to have multiple returns, I'll code it that way without feeling that I need to shower afterwards.

But ask me my opinion of scriplets in JSPs...


[Asking smart questions] [Bear's FrontMan] [About Bear] [Books by Bear]
M Easter
Ranch Hand

Joined: Feb 11, 2007
Posts: 133
Originally posted by Jeanne Boyarsky:

What about a third choice of "no more than two return statements" ? I'm in that camp. Having two makes sense - a guard and the "real" one. More than that tends to result in code that is too difficult to refactor because returns are strewn throughout.


Jeanne,

IMHO, once there is more than one, then the bubble bursts. Here are some thoughts (all IMHO):

(a) In the Pragmatic Programmer, Dave Thomas talks about the "Broken Windows" theory. (See http://tinyurl.com/6cy39) With that in mind, my concern is that once > 1 return occurs, others are likely to follow. Perhaps not by you or me but by that intern.

(b) Maybe it's me but when I'm debugging or reading code and see more than one return, my brain feels a need to go into "parallel" mode. I know that multiple returns does not equate to multiple threads, but still....

(c) It just seems so much easier! One sets the default value for the result and then only change it as necessary.

(d) This idea _is_ old, and is usurped by AOP: using a convention allows one to do neat things with the codebase via scripting languages. e.g. if you want to add timers/log statements to a set of methods (in an automated way), then at least it is tractable by using a convention. With multiple returns, it's not tractable.
Henry Wong
author
Sheriff

Joined: Sep 28, 2004
Posts: 18724
    
  40

But no hard religion. I don't consider multi-returners blasphemers, and I never try to tell anyone that single-return is the one true way to light and goodness. And if it makes sense for a method to have multiple returns, I'll code it that way without feeling that I need to shower afterwards.


In total agreement. Maybe it is because I deal with a lot of client code, some really horrible, that multiple returns don't bother me.

I have seen some bad code with single returns per method. I have seen some really good code with multiple returns. Personally, I like having a single return, but in the end, if it make sense to have multiple, so be it.


As an anecdote, my first professional language was x86 assembly (I don't count the half dozen or so languages that I learned in school). With assembly, you must have only one return, and at the end.

The reason is because a return doesn't undo the stuff you put on the stack. By guaranteeing that the return is always at the end, it is easier to ensure all the push onto the stack is matched with a pop off of the stack. Of course, now you have a bunch of jumps (gotos) to the pop and return code...

Henry


Books: Java Threads, 3rd Edition, Jini in a Nutshell, and Java Gems (contributor)
Stan James
(instanceof Sidekick)
Ranch Hand

Joined: Jan 29, 2003
Posts: 8791
I don't mind multiple returns. The least offensive are "guard clauses" (I think I'm using the name right) like a string manipulation method that says if the input is null, return null. I'd rather not put the whole method inside an "if not null" test just to get one return.

Even so, if a method is more than a few lines long, multiple returns can be a Very Bad Thing. But I rather think any time somebody complains that some practice makes it hard to follow a complex method, the method length is more likely the problem.


A good question is never answered. It is not a bolt to be tightened into place but a seed to be planted and to bear more seed toward the hope of greening the landscape of the idea. John Ciardi
Jesper de Jong
Java Cowboy
Saloon Keeper

Joined: Aug 16, 2005
Posts: 14111
    
  16

I prefer a single return statement but I'm not very "fundamental" about it. However, I did find a bug recently in the software that I'm currently developing that was caused exactly because there was an extra return statement, it looked like this:

The problem was that the extra code below the loop, which was added to the method later, wasn't executed when the condition in the if-statement was true, so that the method returned from the loop immediately. Ofcourse this bug would have been prevented if I wouldn't have allowed multiple return statements.


Java Beginners FAQ - JavaRanch SCJP FAQ - The Java Tutorial - Java SE 7 API documentation
Scala Notes - My blog about Scala
Ilja Preuss
author
Sheriff

Joined: Jul 11, 2001
Posts: 14112
Originally posted by Jesper Young:
I prefer a single return statement but I'm not very "fundamental" about it. However, I did find a bug recently in the software that I'm currently developing that was caused exactly because there was an extra return statement, it looked like this:

The problem was that the extra code below the loop, which was added to the method later, wasn't executed when the condition in the if-statement was true, so that the method returned from the loop immediately. Ofcourse this bug would have been prevented if I wouldn't have allowed multiple return statements.


Interesting example. Yes, disallowing multiple returns would have prevented that bug, but it looks to me like it wouldn't have made the code simpler. And the true problem to me is that the method looks too complex, which concealed the bug. So my preferred way of preventing that bug would have been to make the method easier to understand, for example by introducing an abstraction.


The soul is dyed the color of its thoughts. Think only on those things that are in line with your principles and can bear the light of day. The content of your character is your choice. Day by day, what you do is who you become. Your integrity is your destiny - it is the light that guides your way. - Heraclitus
M Easter
Ranch Hand

Joined: Feb 11, 2007
Posts: 133
A colleague of mine had a rule: in addition to a single return, also no break or continue statements. They cause bugs.

Often a while loop can simplify things. Consider this (think of a state machine):



One might argue that the while loop can cause an infinite loop if the person forgets the "i++;" but that will fail very quickly and be discovered during testing.

Yes, the same thing can be done with a for statement and multiple predicates, but to me this is the most elegant.
[ May 02, 2007: Message edited by: M Easter ]
Ernest Friedman-Hill
author and iconoclast
Marshal

Joined: Jul 08, 2003
Posts: 24183
    
  34

I'm also in the "prefer one return, but multiple ones are OK if needed" camp. But actually, it's the kind of code you've just shown here that makes my skin crawl. I can't stand control flags. Variables that represent real decisions previously made are OK, but variables that exist merely to direct control flow bother me a great deal -- too much like assembly, I guess. I would be very quick to rewrite this code to simply return from the loop.


[Jess in Action][AskingGoodQuestions]
Ilja Preuss
author
Sheriff

Joined: Jul 11, 2001
Posts: 14112
Originally posted by M Easter:
A colleague of mine had a rule: in addition to a single return, also no break or continue statements. They cause bugs.


That's a very strong statement that I can't subscribe to.

What I'd agree with is that break and continue statements are a code smell, in the sense that they often hint at code that is doing more in one place than is good for its complexity, and that would benefit from the extraction of a method.





That's a perfect example! Take a look at this refactored version, which I consider to be even more elegant:



Very often I actually find that a good next step is to move the ok method to a different class, because it smells of Feature Envy.
Henry Wong
author
Sheriff

Joined: Sep 28, 2004
Posts: 18724
    
  40

Would this make your "skin crawl"?...



Henry
[ May 02, 2007: Message edited by: Henry Wong ]
Roseanne Zhang
Ranch Hand

Joined: Nov 14, 2000
Posts: 1953
If you ever coded in functional language, such as ruby, you will not argue on such topic!!!

Multi-returns are fine to me!
Roseanne Zhang
Ranch Hand

Joined: Nov 14, 2000
Posts: 1953
Even you don't see a single return inside the following code, but there can be thousands equivalent. What a beautiful elegant concise code to all possible interpretations of a piece of Morse code.
http://pastie.caboo.se/55742

[ May 02, 2007: Message edited by: Roseanne Zhang ]
Joe Wolfe
Ranch Hand

Joined: Apr 25, 2007
Posts: 87
It is a complex question without a simple answer. If the mutiple returns make the code hard to follow then use one. If it helps use several. This is my opinion.

With plenty of inexperienced ptrogrammers around an insistance on one return only helps keep the code easy to read. So I like that idea but multiple returns in one method by an experenced programmer is not grounds for dismissal. Forcing them to use one forces good programming pracitices on them so I vote one for the record. But allow two when one makes it too complicated.

Short methods help too. No 300 line methods please.


If not now then never.
Ilja Preuss
author
Sheriff

Joined: Jul 11, 2001
Posts: 14112
Originally posted by Joe Wolfe:

With plenty of inexperienced ptrogrammers around an insistance on one return only helps keep the code easy to read.


How does it do that?
Jesper de Jong
Java Cowboy
Saloon Keeper

Joined: Aug 16, 2005
Posts: 14111
    
  16

Originally posted by Henry Wong:
Would this make your "skin crawl"?...

Yes, that would make my skin crawl, you're abusing the exception handling mechanism here!

This kind of coding could easily introduce another bug: if you throw an exception inside the try { ... } block that you want thrown out of the method, then the code in the finally { ... } block would be executed even if you don't want that.

So that doesn't look like a good solution.
Jim Yingst
Wanderer
Sheriff

Joined: Jan 30, 2000
Posts: 18671
Jesper: really? Using finally is abusing exception handling? I really can't agree with that. No exceptions needs to be thrown, and the path through the code is linear. The try/catch/finally blocks do add a bit of visual clutter which I dislike, but otherwise, I don't see a problem.

Well, there is one: if an exception is thrown for any reason from within the finally block, it causes the JVM to lose the stack trace of any previously-thrown exception. That gives a good motivation to try to use finally only for short, "safe" operations. Or to use another try/catch within the finally, which adds to visual clutter...

[Jesper]: This kind of coding could easily introduce another bug: if you throw an exception inside the try { ... } block that you want thrown out of the method, then the code in the finally { ... } block would be executed even if you don't want that.

Hm, I rather thought that was part of the point, that the programmer does want the code executed even if an exception was thrown. Certainly, if they don't, they shouldn't code this way. But if they do, they should.

As for the original question, my response is pretty much exactly the same as Stan's above. I'm very religious about keeping methods short. Many other problems are non-issues if you keep your methods short. And if a method is shorter with multiple returns than with a boolean control variable, that's usually more readable to me. Ilja's earlier example is exactly the sort of thing I would try to do, and the ok() method looks very readable to me.

The main reason I sometimes have to avoid multiple returns is when I want to do something like log a return value before returning. It's nice to only need to do that in one place. And you can't log a return value from a finally block, because there's no way to access the value of an earlier return. So the moment I want to log a return value, I'll refactor to a single return. But again, with short methods, this isn't much of a problem, and I don't see a need to preemptively require single returns everywhere just because I might want to log a return value later.


"I'm not back." - Bill Harding, Twister
Jeanne Boyarsky
internet detective
Marshal

Joined: May 26, 2003
Posts: 30324
    
150

Originally posted by M Easter:
IMHO, once there is more than one, then the bubble bursts. ...
the "Broken Windows" theory. ... my concern is that once > 1 return occurs, others are likely to follow. Perhaps not by you or me but by that intern.

I subscribe to the "Broken Windows" theory, but I disagree with the applicability of the analogy here. The Broken Windows theory has to do with abandonment. If a policy says two return statements (but not more) are allowed, having two doesn't abandon things to get worse. There is still a policy which is addressed when someone decides to add a third. And "that intern" needs to be trained before coding. Otherwise he/she could do all sorts of things to the code base. For example, writing a 300 line method, writing string1 == string2 or writing generally buggy code. We reviewed all the code our summer intern wrote. It was very good (and I only did cursory glances at the end), but you don't want a bug to slip through due to inexperience.


(b) Maybe it's me but when I'm debugging or reading code and see more than one return, my brain feels a need to go into "parallel" mode. I know that multiple returns does not equate to multiple threads, but still....

It depends on how it is used. When the return statements are all over the place or in a long method, I agree. In a 10 line (or 5 line) method, this doesn't seem like a big issue.


(c) It just seems so much easier! One sets the default value for the result and then only change it as necessary.

Sometimes. I find the guard clause to be easier to read. I also find a linear search method to be simpler with two return statements - forgot to mention this one earlier.
Ricky Clarkson
Ranch Hand

Joined: Jul 27, 2006
Posts: 131
There is no good reason to delay returns in Java. Resource cleanup should be done in finally blocks, so that reason is moot. Delaying returns obfuscates code.

If you find that you don't notice returns inside nested loops, etc., then you should read the code more slowly. Perhaps try a bigger font, or get your IDE to make the return keyword a strange colour.

If that fails, try to make the code more readable to yourself in some way. Many for loops with returns are searches - you might be better off writing a general search method that takes a predicate.
Daniel Platon
Ranch Hand

Joined: Oct 10, 2005
Posts: 42
Hello all,
There's definitely a great conversation here. Up till now I never felt the need to more than one return statement. Event when I put two return statements, I fell I could've gotten around with just one.

What attracted me was the tiny piece of code

now suppose X is a very large number and you have some more work to do in an iteration. Wouldn't be a less burden to do something like this ? -

because ok could become true in the first 10 iterations out of a hundred for example, so the code executes 90 times for nothing.

Thanks a lot,
Dan
Joanne Neal
Rancher

Joined: Aug 05, 2005
Posts: 3446
    
  12
The while loop is checking the value of ok, so it will exit when it is set to false.


Joanne
Daniel Platon
Ranch Hand

Joined: Oct 10, 2005
Posts: 42
Ouuups ! Must be tired ! I was thinking about a "for" loop. The solution given by Ilja Preuss is actually ok, but why wouldn't one use "break" (hope i'm not too offtopic here)

Thanks,
Dan
Ilja Preuss
author
Sheriff

Joined: Jul 11, 2001
Posts: 14112
Originally posted by Daniel Platon:
why wouldn't one use "break"


I find the refactored version with the two methods to be easier to understand.
Jim Yingst
Wanderer
Sheriff

Joined: Jan 30, 2000
Posts: 18671
The other issue is that break is generally disliked by the same people who dislike multiple returns. (Except within switch statements, where break is an unfortunate necessity.) It you're working under a coding standard that forbids multiple returns, it probably also forbid break (outside a switch) and continue as well. At least, that's my experience.

Looking at Ilja's refactored ok() method:

This could've used a break instead:

That has only one return, but requires two more lines than the original did, and to my mind it's a little less clear. However if I wanted to insert a log statement before the return, this is probably the form I'd use.

And yes, you can avoid the break by putting the ok inside the loop condition:

The problem there is that it's easy for people to miss that nonstandard loop condition, as Daniel just illustrated. I think that using either break or return jumps out at people more than that "ok &&" does. As usual, others may disagree.
[ May 04, 2007: Message edited by: Jim Yingst ]
Jesper de Jong
Java Cowboy
Saloon Keeper

Joined: Aug 16, 2005
Posts: 14111
    
  16

Jesper: really? Using finally is abusing exception handling? I really can't agree with that. No exceptions needs to be thrown, and the path through the code is linear. The try/catch/finally blocks do add a bit of visual clutter which I dislike, but otherwise, I don't see a problem.

No, ofcourse using 'finally' is not abusing exception handling. But using a try / finally block to avoid a bug caused by an early 'return' statement as I demonstrated in my post above is, in my opinion.

I'll try to explain it again. Suppose you have this:

Now I'm going to add some code after the for-loop.

Suppose that the programmer wanted to have that extra code executed before the method returns. In this case it goes wrong because there is an early return in the loop. When the method returns from the loop, the extra code is not executed. Ofcourse this is easy to fix, by removing the early return, like this:

Note that if we would fix this with a try-finally block, the code in the finally would be executed even if doSomething(...) throws an exception, and that is not what we want.
Jim Yingst
Wanderer
Sheriff

Joined: Jan 30, 2000
Posts: 18671
Jesper, your previous post was clear enough the first time. We're just looking at Henry's example code with different assumptions about what the intent was. As I said earlier:
Hm, I rather thought that was part of the point, that the programmer does want the code executed even if an exception was thrown. Certainly, if they don't, they shouldn't code this way. But if they do, they should.

Considering the original code called "doSomething()" in the finally block, we can't really tell whether the "something" is something that should also be done in the case of an exception, or not. For some situations it's a buggy solution, while for others it's the preferred solution. I certainly wouldn't say it "makes my skin crawl" in general, but it may be wrong for a more specific example.
[ May 05, 2007: Message edited by: Jim Yingst ]
Nicholas Jordan
Ranch Hand

Joined: Sep 17, 2006
Posts: 1282
Originally posted by Henry Wong:
Would this make your "skin crawl"?...


Oh, I love your code ! Makes mine crawl, but then I know to look for exactly the type of code that makes my skin crawl.

I originally started coding my project in C++, writing massive switches (where useful) on the assumption that some coder, someday, would try to do things to me like what your snippet does, along with probably several other " hidden gotchas " that were waiting, undiscovered .... making the decision early and clean that I would write whatever code it took, myself, or decline the business.

By now, I template any and all func()'s as int retVal = 0; near the beginning, then place the return retVal; near the closing brace, even going so far as to place an explict return on a void even if the linguistic does not require it.

Occasaionally, there are the unavoidable constraints, but the only solution I have found is to tediously walk through everything. Anything else is going to get you someone elses' malarky assigned to your reputation.

I have been through this so many times, I now laugh at people when I see it coming.

[edit: Sunday, May 20, 2007]:
I have given this additional thought, I always template a func() thus:

With matching elses and do cleanup before vars go out of scope. I am giving consideration at exactly this moment whether to leave by exception in all elses so that the return is only done on successful func() completion.
[ May 20, 2007: Message edited by: Nicholas Jordan ]

"The differential equations that describe dynamic interactions of power generators are similar to that of the gravitational interplay among celestial bodies, which is chaotic in nature."
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: single return statement: yes / no?