问题
I made recursive function, just like
require : L (List[Int])
L pattern matching
Nil => Thread.dumpStack()x :: xs => print(x) + function(xs)
def function(L : List[Int]) { L match { case Nil => Thread.dumpStack() case x :: xs => print(x + " "); function(xs) } }val l = (1 to 5).toList // function(l)
So I think this function in the stack frame n times, but it occurs one time, I think this function has already found Nil and print out exception Thread.dumpStack.
Is scala compiler smart or other else?
回答1:
You are observing tail recursion: there is nothing to store from one iteration to the next, so the recursion is essentially turned into a while loop by the compiler. (So, yes, the compiler is smart in that way.)
回答2:
As Rex Kerr pointed out, this is the Scala compiler applying a tail call optimization. If you want to know what is compiled in the end, you can run the compiler with an extra argument:
scalac -Xprint:tailcalls yourfile.scala
This will print the intermediate representation after the tailcalls compiler phase. (If you want to learn about all phases, you can also run scalac -Xshow-phases.) For example, on the following input:
object TailRec {
def foo(l : List[Int]) : Unit = l match {
case Nil => Thread.dumpStack()
case x :: xs => println(x); foo(xs)
}
}
The compiler will print (for the function foo):
def foo(l: List[Int]): Unit = {
<synthetic> val _$this: TailRec.type = TailRec.this;
_foo(_$this,l){
l match {
case immutable.this.Nil => java.this.lang.Thread.dumpStack()
case (hd: Int, tl: List[Int])collection.immutable.::[Int]((x @ _), (xs @ _)) => {
scala.this.Predef.println(x);
_foo(TailRec.this, xs)
}
}
}
}
The part _foo(_$this,l) looks like a function definition, but it's really a label, and the "call" _foo(TailRec.this, xs) is in fact a jump to that label. So in short, the compiler rewrote a recursive call into what really is a while loop.
The compiler will apply the optimization automatically when it can. If you want to make sure that a function is properly rewritten, you can annotate it with @tailrec, and the compiler will produce an error if it cannot optimize it.
来源:https://stackoverflow.com/questions/8104587/scala-has-smart-compiler