在F Sharp中,Continuation可以用于防止stack overflow。scala则不行。
Scala 的code:
def recCont(i:Int,cont:Int=>Int):Int = {
if (i == 0) cont(0) else
recCont(i-1,y=>cont(y+i))
}
println("recCont="+recCont(5000,m=>m)) //stack overflow
F# 的code:
let rec recCont i cont =
if i=0
then cont(0)
else recCont (i - 1) (fun y->cont(y+i))
let r = recCont 1000000 (fun m->m)
/// r= 1784293664
反编译java的byte code, 发现Scala 和F#都是采取heap trade off stack 的策略。
在scala中, continuations是用类似List的列表组织的: (5000+cont(4999+cont(4998+cont(4997+...cont(0))
问题出在apply函数上, 当调用apply时, 因为java没有.net的tail-call优化机制(http://www.sidhe.org/~dan/blog/archives/000211.html) - 在byte-code级别把recursion转换成goto而不是函数调用, 以避免stack oveflow.