【发布时间】:2014-01-09 22:59:08
【问题描述】:
我意识到这与 SO 问题的通常意义背道而驰,但即使我认为它不应该工作,以下代码仍然有效。下面是一个小的 Scala 程序,它使用带有 while 循环的延续。根据我对延续传递风格的理解,这段代码应该会通过为 while 循环的每次迭代向堆栈添加一个帧来产生堆栈溢出错误。但是,它工作得很好。
import util.continuations.{shift, reset}
class InfiniteCounter extends Iterator[Int] {
var count = 0
var callback: Unit=>Unit = null
reset {
while (true) {
shift {f: (Unit=>Unit) =>
callback = f
}
count += 1
}
}
def hasNext: Boolean = true
def next(): Int = {
callback()
count
}
}
object Experiment3 {
def main(args: Array[String]) {
val counter = new InfiniteCounter()
println(counter.next())
println("Hello")
println(counter.next())
for (i <- 0 until 100000000) {
counter.next()
}
println(counter.next())
}
}
输出是:
1
Hello
2
100000003
我的问题是:为什么没有堆栈溢出? Scala 编译器是在做尾调用优化(我认为它不能用延续做)还是有其他事情发生?
(此实验在 github 上以及运行它所需的 sbt 配置:https://github.com/jcrudy/scala-continuation-experiments。参见提交 7cec9befcf58820b925bb222bc25f2a48cbec4a6)
【问题讨论】:
标签: scala continuations delimited-continuations