Functional Programming Scala – Why Scala Requires Functions to Have Explicit Return Type

functional programmingscala

I recently began learning to program in Scala, and it's been fun so far. I really like the ability to declare functions within another function which just seems to intuitive thing to do.

One pet peeve I have about Scala is the fact that Scala requires explicit return type in its functions. And I feel like this hinders on expressiveness of the language. Also it's just difficult to program with that requirement. Maybe it's because I come from Javascript and Ruby comfort zone. But for a language like Scala which will have tons of connected functions in an application, I cannot conceive how I brainstorm in my head exactly what type the particular function I am writing should return with recursions after recursions.

This requirement of explicit return type declaration on functions, do not bother me for languages like Java and C++. Recursions in Java and C++, when they did happen, often were dealt with 2 to 3 functions max. Never several functions chained up together like Scala.

So I guess I'm wondering if there is a good reason why Scala should have the requirement of functions having explicit return type?

Best Answer

Scala doesn't require an explicit return type on all functions, just recursive ones. The reason for that is that Scala's type inference algorithm is (something close to) a simple scan from beginning to end that is incapable of lookahead.

This means that a function like this:

def fortuneCookieJoke(message: String) = message + " in bed."

doesn't need a return type, since the Scala compiler can clearly see, without using logic variables or looking at anything other than the method's parameters, that the return type must be String.

On the other hand, a function like this:

def mapInts(f: (Int) => Int, l: List[Int]) = l match {
  case Nil => Nil
  case x :: xs => f(x) :: mapInts(f, xs)
}

will cause a compile-time error, because the Scala compiler cannot see, without using either lookahead or logic variables, exactly what the type of mapInts is. The most it could say, if it were smart enough, is that the return type is a supertype of List[Nothing], since Nil is of that type. That doesn't give it anywhere near enough information to accurately determine the return type of mapInts.

Please note that this is specific to Scala, and that there are other statically typed languages (most of the Miranda/Haskell/Clean family, most of the ML family, and a few scattered others) that use much more comprehensive and capable type inference algorithms than Scala uses. Also, be aware that this is not entirely Scala's fault; nominal subtyping and whole-module type inference are fundamentally at odds with each other, and the designers of Scala chose to favor the former over the latter for the sake of Java compatibility, while the "purer" statically typed functional languages were mostly designed with the opposite choice in mind.

Related Topic