Should I use return in multi-line Scala methods?

Perhaps this is just my experience in more pressing programming, but I like to have return statements in my code.

I understand that in Scala no return is required in many methods, because any last calculated value is returned by default. I understand that this makes sense for a "one line", for example,

def square(x) = x * x 

I also understand the final example of using explicit returns (when you have several branches that your code can take and you want to break out of the method for different branches, for example, when an error occurs). But what about multi-line functions? Wouldn't that be more readable and would make more sense if there was an explicit comeback, for example.

 def average(x: List[Int]) : Float = { var sum = 0 x.foreach(sum += _) return sum / x.length.toFloat } 
+4
source share
5 answers
 def average(x: List[Int]) : Float = x.foldLeft(0)(_ + _) / x.length.toFloat 

UPDATE: while I was trying to show how iterative code can be turned into a functional expression, @soc rightly commented on an even shorter version of x.sum / x.length.toFloat

Usually I find that in Scala I need less to "go back in the middle." In addition, a large function is divided into smaller expressions that are clearer to reason. Therefore, instead of

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

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

A similar thing happens with matching expressions. And you can always have helper nested classes.

As soon as you are comfortable with many forms of expressions that evaluate the result (for example, "if") without a return statement, the presence of one of your methods looks inappropriate.

In one place of work, we had a rule not to have a β€œreturn” in the middle of the method, since it is easy for the reader of your code to skip it. If "return" is only on the last line, what's the point of having it at all?

+11
source

return does not tell you anything superfluous, so I find that it actually interferes with my understanding of what is happening. Of course he is returning; There are no other statements!

And it’s also nice to get away from the habit of using return , because it’s really not clear where you return when using highly functional code:

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

Where should the return be returned? Beyond manyFutures ? Only the indoor unit?

So, although you can use explicit returns (at least if you explicitly annotate the type of return value), I suggest you use the habit of last-statement-is-the-return-value instead.

+10
source

Your understanding that the return version is more readable is probably a sign that you still consider yourself imperative rather than declarative. Try to think about your function in terms of what it is (that is, how it is defined), and not what it does (for example, how it is calculated).

Take a look at your average example and pretend that the standard library does not have functions that make it elegant single-line. Now in English, we would say that the average number of lists of numbers is the sum of the numbers in the list divided by the length.

 def average(xs: List[Int]): Float = { var sum = 0 xs.foreach(sum += _) sum / xs.length.toFloat } 

This description is pretty close to the English version, ignoring the first two lines of the function. We can expand the sum function to get a more declarative description:

 def average(xs: List[Int]): Float = { def sum(xs: List[Int]): Int = // ... sum(xs) / xs.length.toFloat } 

In a declarative definition, the return reads completely unnaturally because it clearly focuses on doing something.

+3
source

I did not miss the return-statement at the end of the method because it is not needed. In addition, in Scala, each method returns methods with even values ​​that should not return anything. Instead of void , the returned type of Unit appears:

 def x { println("hello") } 

can be written as:

 def x { println("hello"); return Unit } 

But println already returns a Unit type - so when you explicitly want to use a return-statement, you should use it in methods that return Unit . Otherwise, you do not have a constant, identical inline code.

But Scala has the ability to break your code with many small methods:

 def x(...): ReturnType = { def func1 = ... // use funcX def func2 = ... // use funcX def func3 = ... // use funcX funcX } 

The explicitly used return-statement does not help to better understand the code.

Scala also has a powerful core library that allows you to solve many problems with less code:

 def average(x: List[Int]): Float = x.sum.toFloat / x.length 
+2
source

I believe that you should not use return , I think that this somehow contradicts the elegant concept that in Scala it is all an expression that evaluates something.

Like your average method: it's just an expression that evaluates to Float , you don't need to return anything to make this work.

0
source

Source: https://habr.com/ru/post/1332722/


All Articles