12

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?

2
  • 5
    It doesn't -- and I fail to see why it would be a problem if it did. Oct 3, 2012 at 3:24
  • 1
    I thought it did. Are there cases in Scala where the return type for a function is actually ambiguous? Oct 3, 2012 at 3:37

1 Answer 1

17

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.

2
  • 4
    Actually, the problem is not so much figuring out a more comprehensive type inferencing algorithm. It's figuring out a more comprehensive type inferencing algorithm, while keeping the high quality of error messages in the current Scala compiler. Oct 3, 2012 at 5:21
  • 1
    Wouldn't the correct return for case Nil actually be an empty List[Int]()? In which case a sufficiently smart compiler could figure it out. That's all playing Devil's Advocate though, I suppose.
    – KChaloux
    Dec 12, 2012 at 15:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.