编辑于 2024年08月18日 20:07
Continuation就是回调
function a (num a, num b) => a + b变成 func a (num a, num b, func c) => c(a + b)
有啥用?
转为尾递归
尾递归是啥? 递归就是函数调用自己 如果调用在最末尾
像这样
func a( ...) => {...return a(...)
}
函数调用前需要保存当前函数中的变量,需要占用栈空间,栈空间比较小,容易内存溢出。如果用尾递归,只需要保存被调用函数用到的参数,这一般存在寄存器中,而当前函数的变量一定不会被再次使用,当前函数用的栈空间可以被重新利用。
一般情况下,编译器将尾递归优化为循环,像这样:
func a(...args) => {...return ...args2
}
while(...){...args = a(...args)
}
在汇编层面不需要压栈保存寄存器而是使用。
但是如果调用后面还有代码的话就做不了优化,所以把后面要做的事也就是一个函数在调用时传递。这就是cps变换
如果所有代码都自动进行这种转换,栈空间就不需要了。也就是只使用用闭包。
这种方式也存在问题,闭包中存储的函数上下文信息不会像栈一样自动回收,这种方式需要垃圾回收器。
call/cc
function callcc(f, k) {return f(k)
}
callcc((x)=> x(4 * 3),(y)=> 1 + y
)
call/cc(调用的函数, 回调函数) 就是把调用函数的返回值传给回调函数