Programming

continuation(cont) & coroutines

don’t return function results, instead we pass them to the provided continuation(s)

continuation就是存着某个时刻的 指令寄存器(比如eip) 以及其它相关寄存器 和 整个调用栈 的一个结构体。(没优化的情况下)

上下文:env
拦截/暂停:intercept/suspend
中止/跳出:abort/skip
转移:shift
恢复/重启:resume/reset
调用:invocation

上下文用于保存当前环境,或传入外部环境,
拦截 中间值,可用于流程的暂停,并对中间值做出更多解释(interpretation)后,再交还 continuation(下一个)。
调用(invocation)可以被恢复(resume),也可以被中止(abort),甚至可以重复调用多次。

CPS 不依赖 return 的自动控制流,通过 continuation 做执行权交换(shift,转移至另一个函数)

callCC:call-with-current-continuation

continuation 实现的前提是提供执行权转移(control transfer),继而中断执行,或中断后继续执行,generator 可以实现这样的效果,但是 generator 会带来函数的染色,所以不是最好的解决方案

CPS 的结构特征

  • The function takes a callback as an additional argument
  • The function never returns its result. It always uses the callback to communicate its result
  • Contrary to what you may think. Originally, it has nothing to do with async Node.js functions ```typescript function add(x, y) { return x + y; }

// cps function add(x, y, next) { const result = x + y; return next(result); } ```

tail call 尾调用 (tail call) 指的是一个函数的最后一条语句也是一个返回调用函数的语句。在函数体末尾被返回的可以是对另一个函数的调用,也可以是对自身调用(即自身递归调用)。[1] 在 CPS 的结构下,return 语句是一个 tail call 的效果。 尾调用或尾递归理论上可以从引擎进行优化,实现调用栈的减少(每次尾调用都是一个 goto /jump 的效果),但目前貌似仍旧未被实现或应用,所以可以使用循环进行尾递归优化。 webkit 实现的尾递归优化 https://webkit.org/blog/6240/ecmascript-6-proper-tail-calls-in-webkit/