Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to extend the Scala compiler to infer return types of recursive methods?

Tags:

scala

The Scala compiler currently cannot infer return types of recursive methods as in the following code

def foo(i:Int) = if (i > 0) foo (i-1) else 0

Is there any ambuigity in the above statement? (i.e., is any type other than Int possible?)

I can imagine that in more complex example, it will be difficult to infer the type.

Is it possible to further characterize the cases of recursive methods where we can(not) infer the types?

[EDIT:] The compiler is intelligent enough to figure out that String is incorrect.

scala> def foo(i:Int):String = if (i > 0) foo (i-1) else 0
<console>:5: error: type mismatch;
found   : Int(0)
required: String
like image 312
Jus12 Avatar asked Oct 11 '11 18:10

Jus12


People also ask

How do you improve recursion performance?

Bottom-up. Sometimes the best way to improve the efficiency of a recursive algorithm is to not use recursion at all. In the case of generating Fibonacci numbers, an iterative technique called the bottom-up approach can save us both time and space.

Can a recursive function run forever?

In most programming environments, a program with an infinite recursion will not really run forever. Eventually, something will break and the program will report an error. Infinite recursion is the first example we have seen of a run-time error (an error that does not appear until you run the program).

How does recursion work in Scala?

Recursion refers to a general method that involves defining a solution or object in terms of itself. Recursive functions refer to a kind of function where the definition of a function includes calling the function itself.

Does Scala support tail call recursion?

Tail Recursion in Scala In Scala, only directly recursive calls to the current function are optimized. One can require that a function is tail-recursive using a @tailrec annotation: @tailrec def gcd(a: Int, b: Int): Int = …


2 Answers

If your recursive call is always in the last position, i.e. its value is never used and only returned, it should be possible to determine the type as the common supertype of all other branches.

However, in a situation like

def foo(i: Int) = if (i > 0) foo(i - 1) + 1 else 0

you would not know the type of foo(i - 1) + 1 (or understand the operation + because it is actually a method on foo – things are getting more complicated in the presence of objects) without knowing what foo is. So, again you’re moving around in circles.

like image 54
Debilski Avatar answered Nov 15 '22 17:11

Debilski


You'd need an unification algorithm much more powerful than what Scala provides. Scala does type checking left to right, top to bottom. So the inference would go somewhat like this:

What is the type of expression "if (i > 0) foo(i - 1) + 1 else 0"?
Unify "foo(i - 1) + 1" and "0"
What is the type of "foo(i - 1) + 1"?
What is the type of "foo(i - 1)"
What is "foo"?
foo is the current definition, so we don't know it's type
error

if you did the if the other way around you'd have:

What is the type of expression "if (i <= 0) 0 else foo(i - 1) + 1 "?
Unify "0" and "foo(i - 1) + 1"
What is the type of "0"?
"0" <: Int >: Nothing
What is the type of "foo(i - 1) + 1"?
What is the type of "foo(i - 1)"
What is "foo"?
foo is the current definition, so we don't know it's type
error
like image 25
Daniel C. Sobral Avatar answered Nov 15 '22 15:11

Daniel C. Sobral