CPS 变换有什么作用?

常常看见大家讨论CPS变换,形式上看好像很简单,就是把原本有返回值的函数变成无返回值,增加一个参数,类型为函数指针,将原来的返回值传递给这个函数指针,以形成一种延续的效果。 但一直理解不了CPS到底有什么作用,它到底用来解决什么问题? 按我的理解,传递进来的函数指针也是一段逻辑,把它直接写进原函数不就好了么? 或者按原来的做法,获得返回值,然后再调用其它函数将返回值当参数,不也一样能表现业务么?
关注者
325
被浏览
15611

8 个回答

CPS 变换说白了就是把程序内部原本隐式的控制流跳转,用某种方法抽象出来暴露给程序员。@vczh 之前说过光用 CPS 在小萌语言中做出了各种控制流(if 什么的)。
一种常见的情况是,通过 CPS 变换,可以将 Javascript 的回调地狱消除,能用同步的方式写异步程序: BYVoid/continuation · GitHub
人肉的 CPS 是一种递归技巧,能写出更有格(nan)调(dong)的递归程序。(SICP 有提到)
CPS 常常用到的地方是实现 call/cc ,用这货能实现诸如协程,yield 之类的特性。Call-with-current-continuation 不过要在编译器里面实现这货,还需要对过程的栈做垃圾回收。(Spaghetti stack 麻花栈)
还有很多我不知道的黑魔法,比如说阴阳谜题……(continuations
还能帮助你理解 Haskell 的 monad 陈年译稿——一个面向Scheme程序员的monad介绍
CPS变换不是用来让你写成那样的,它主要是做interprocedure analysing,干一些奇怪的事情,譬如说实现C#的async await之类的(C++17的__await在VC++上的实现跟C#是完全不同的,它真的切换了堆栈)。你如果要了解的话,可以去coursera找视频看看。