Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Should I use returns in multiline Scala methods?

Perhaps this is just my background in more imperative programming, but I like having return statements in my code.

I understand that in Scala, returns are not necessary in many methods, because whatever the last computed value is is returned by default. I understand that this makes perfect sense for a "one-liner", e.g.

def square(x) = x * x

I also understand the definitive case for using explicit returns (when you have several branches your code could take, and you want to break out of the method for different branches, e.g. if an error occurs). But what about multiline functions? Wouldn't it be more readable and make more sense if there was an explicit return, e.g.

def average(x: List[Int]) : Float = {
  var sum = 0
  x.foreach(sum += _)
  return sum / x.length.toFloat
}
like image 208
Rafe Kettler Avatar asked Nov 27 '22 22:11

Rafe Kettler


2 Answers

def average(x: List[Int]) : Float = 
  x.foldLeft(0)(_ + _) / x.length.toFloat

UPDATE: While I was aiming to show how an iterative code can be made into a functional expression, @soc rightly commented that an even shorter version is x.sum / x.length.toFloat

I usually find that in Scala I have less need to "return in the middle". Furthermore, a large function is broken into smaller expressions that are clearer to reason. So instead of

var x = ...
if (some condition) x = ...
else x = ...

I would write if (some condition) ... else ....

Similar thing happens using match expressions. And you can always have helper nested classes.

Once you are comfortable with many forms of expressions that evaluate to a result (e.g., 'if') without a return statement, then having one in your methods looks out of place.

At one place of work we had a rule of not having 'return' in the middle of a method since it is easy for a reader of your code to miss it. If 'return' is only at the last line, what's the point of having it at all?

like image 157
IttayD Avatar answered Dec 10 '22 22:12

IttayD


The return doesn't tell you anything extra, so I find it actually clutters my understanding of what goes on. Of course it returns; there are no other statements!

And it's also a good idea to get away from the habit of using return because it's really unclear where you are returning to when you're using heavily functional code:

def manyFutures = xs.map(x => Futures.future { if (x<5) return Nil else x :: Nil })

Where should the return leave execution? Outside of manyFutures? Just the inner block?

So although you can use explicit returns (at least if you annotate the return type explicitly), I suggest that you try to get used to the last-statement-is-the-return-value custom instead.

like image 20
Rex Kerr Avatar answered Dec 10 '22 22:12

Rex Kerr