Scala has smart compiler?

我只是一个虾纸丫 提交于 2019-12-23 12:48:03

问题


I made recursive function, just like

require : L (List[Int])

L pattern matching

  1. Nil => Thread.dumpStack()
  2. 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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!