Scala Best Practices: SAY NO TO RETURN

“Any fool can write code that a computer can understand. Good programmers write code that humans can understand.” – Martin Fowler

Writing readable and understandable code is often overrated. I feel it’s not big a deal. One should just start following the code conventions right from the start of their career. They’re simple rules just like good habits.

Talking about Scala coding conventions, the most basic practice we often come across is: MUST NOT USE RETURN. But rarely they tell you WHY NOT! So, let’s dig into the world of RETURN and find out why not to use them.

Putting in simple words, return basically transfers the control back to the function. It gives back the result and no statement after the return statement gets executed in that particular function. In scala, the return isn’t required to be written with the resultant value. It evaluates that itself. You must’ve tried writing return explicitly to see if it gives you any error or something. Yes, it wouldn’t flag any error but it has the power to change the intended flow of the program.

Where are we actually returning to

Consider a play method for example

Without return:

Output: Action(Ok(toJson(Feature.find)))

 With return:

Output: Gives type error

In the first scenario Ok(toJson(Feature.find) is evaluated from the if-else block and since it is wrapped inside Action{} block, hence the method gives up the output asAction(Ok(toJson(Feature.find)))

Now in the second scenario when we write return Ok(toJson(Feature.find)) it is expected to return the value of Ok(toJson(Feature.find)). But as it is going to interrupt the flow of the method it is going to skip the Action{} block and return Ok(toJson(Feature.find))as the output of our save method which is not the expected return type of our method. Hence type error.

We can say that return statement does not return you from the enclosing block or anonymous function but it returns you from enclosing method(def).

Return type ‘Not’ inferred

Another drawback is that the return type can’t be inferred. You have to explicitly write the return type for any method. This is one of the advantages of Scala that it infers the return type of the methods. But with return, it doesn’t work.

Output: compiling error
Output: some string

Non-LocalReturnControl

When we use the return statement inside anonymous functions its implementation is done by throwing and catching (Although it not true always) an object of NonLocalReturnControl which is a child of Throwable and also inherits NoStackTrace(wonder from where you got the error). Hence it has some kind of overhead over the normal flow. It does not usually create problems. But there’s always a chance that if we are handling our errors we may catch this exception too in our stack trace. So better to leave out the return when using error handling.

A code sample just to test return in anonymous function

In Scala:

Decompiled Version:

Here in the decompiled version, we can see that the implementation of the return statement is actually done by catching the NonLocalReturnControl exception.

Return is not referentially transparent

An expression is said to be referentially transparent if it can be replaced with its corresponding value without changing the program’s behavior. As a result, evaluating a referentially transparent function gives the same value for same arguments. And Return is not so. Let’s see this through code:

Simple return:

Perfectly works

Referenced return:

Doesn’t execute anything after 2nd statement (as the flow breaks with return)

Type of Return Expression

We know that the returned value should conform to the expected type mentioned in the method declaration. But what’s the type of the return statement? Let’s explore it by trying it with different types.

1.Trying Int:

It perfectly works!

Safe to assume that the type of return statements may be the type of the returning value.

2. Trying String:

No issues

So works with string too!!!

3. Trying Nothing:

By this point, it is not a surprise anymore.

And if you use IntelliJ to auto check for the return type it gives ‘Nothing’. So the type of return statement is Nothing.

Still need it? No, you don’t 😀

Well, after mentioning the worse it could do to your code if you still feel that you need to use it. PLEASE THINK AGAIN. You can easily change the way of your computations.

It might take your time and efforts to get used to this good practice, but it’s always good to write computations that terminate properly than to reason out things that went wrong.

Follow best practices! Happy coding 🙂

References:

https://tpolecat.github.io/2014/05/09/return.html


knoldus-advt-sticker


Written by 

Ramandeep Kaur is a Software Consultant, having experience of more than 1.5 years. She is a Java enthusiast and has knowledge of languages like C, C++, C#, and Scala. She is familiar with Object Oriented Programming Paradigms and also has a great interest in relational database technologies. Her hobbies include reading novels and listening music.

1 thought on “Scala Best Practices: SAY NO TO RETURN

Leave a Reply

%d bloggers like this: