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
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.
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).
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.
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 = …
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.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With