我有点了解如何将基本功能(如算术)转换为继续传递样式。 但是如果函数涉及递归怎么办? 例如,
(define funname
(lambda (arg0 arg1)
(and (some procedure)
(funname (- arg0 1) arg1))))
请给我建议。 提前谢谢。
答案 0 :(得分:4)
一个对延续和CPS有很好解释的地方是Krishnamurthi的PLAI书。相关部分(VII)不依赖于本书的其他部分,因此您可以直接跳到那里。特别是一个扩展的例子,手动将代码转换为CPS,并处理递归函数(第17章的第一部分)。
另外,我为我的课写了extended version该文本,其中有更多关于这个主题的例子和更多细节 - 你可能会发现它也很有用。除了PLAI文本之外,我还介绍了继承的一些常见用法,例如实现生成器,模糊运算符等等。 (但请注意,PLAI继续讨论实施策略,我的文本没有涉及。)
答案 1 :(得分:1)
(define (func x y k)
(some-procedure
(lambda (ret)
(if ret
(- x 1
(lambda (ret)
(func ret y k)))
(k #f))))
您缺少基本情况,这就是为什么对延续的唯一显式调用是(k #f)
。如果你有一个基本案例,那么你也将基本案例的返回值传递给续集。例如:
(define (func x y k)
(zero? x
(lambda (ret)
(if ret
(k y)
(some-procedure
(lambda (ret)
(if ret
(- x 1
(lambda (ret)
(func ret y k)))
(k #f))))))))
答案 2 :(得分:1)
这部分重复Chris Jester-Young的答案,但是,我希望我能更好地解释它: - )。
在CPS中,您所寻求的差异在于这两件事(大致):
后者就是克里斯的例子中的lambdas正在做的事情。基本上,评估lambda会创建一个闭包 - 这些闭包用于执行堆栈框架在执行直接式程序时所做的相同工作。代替堆栈帧中的返回地址,闭包包含一个连续函数的绑定,闭包的代码调用它。