Continuation-passing style
Jan 1, 2017
我把未来抛给了你。
有话好好说别乱来啊
两个数相加,翻倍,输出结果。可以这么写
1 | function OutputDoubleSum(a,b){ |
也可以这么写
1 | function Sum(a,b){ |
还能这么写
1 | function Sum(a,b,k){ |
第一种是顺序风格,第二种是函数组合风格,第三种是后继传递风格。
后继传递风格(Continuation-passing style)是一种控制流通过参数传递的风格。
简单的说就是把后继,也就是下一步要运行的代码,封装成函数,通过参数传递的方式传给当前运行的函数。
在例子中 Output(x,k)
的第二个参数接受一个后继,在 Output
执行完成后调用后继。 Output
的后继为
1 | function(){} |
是一个空函数,表示后面什么事情都不做。
Double
的后继是
1 | function (doublex){ |
表示收到 Double
的计算结果后,执行 Output
Sum
的后继是
1 | function (sumxy){ |
表示收到 Sum
的计算结果后,执行 Double
这样通过参数传递的方式将顺序风格改为了后继传递风格。
所以有什么用呢
没什么用。当然是有用的啦,不然干嘛这么费力不讨好。
一个最常见的用法是用在异步代码中,也就是异步代码的回调。
搭配 Call/cc
能够实现控制流中的 try/catch
和 yield
等控制方式。
最后
「CPS 就是把用于经典逻辑和直觉逻辑间命题转换的 Gödel–Gentzen 转换,经 Curry–Howard correspondence 应用到证明过程表示的自然结果。」(逃