Continuation Passing Style 连续传递样式

编辑于 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(调用的函数, 回调函数) 就是把调用函数的返回值传给回调函数

posted @ 2025-10-21 10:48  ovida  阅读(6)  评论(0)    收藏  举报