Lisp 当前延续的调用只能用lambda和闭包实现吗?

Lisp 当前延续的调用只能用lambda和闭包实现吗?,lisp,computer-science,scheme,continuations,callcc,Lisp,Computer Science,Scheme,Continuations,Callcc,是否有人知道只要lambda和闭包就可以实现call/cc 似乎call/cc会中断程序的流程(就像一个异常),但lambdas和closures无法做到这一点。因此我认为,call/cc不能通过lambda和闭包实现 还有什么想法吗?问题不是特别清楚,因为“仅使用lambdas和闭包实现”到底意味着什么 在任何情况下,通过手动写入,continuations可以在任何语言中与闭包一起使用。然后,可以通过扩展编译器来实现这种形式的自动转换,Lisps通常允许在用户级通过宏进行编译。例如,请参见为

是否有人知道只要lambda和闭包就可以实现
call/cc

似乎
call/cc
会中断程序的流程(就像一个异常),但lambdas和closures无法做到这一点。因此我认为,
call/cc
不能通过lambda和闭包实现


还有什么想法吗?

问题不是特别清楚,因为“仅使用lambdas和闭包实现”到底意味着什么

在任何情况下,通过手动写入,continuations可以在任何语言中与闭包一起使用。然后,可以通过扩展编译器来实现这种形式的自动转换,Lisps通常允许在用户级通过宏进行编译。例如,请参见为Common Lisp实现continuations的库,这是一种没有内置continuations的语言


类似Scheme中的高效普适延续可能会在直接处理程序堆栈的较低级别上实现,但这不是一个要求,只是一种优化。

在Scheme中,您可以在转换为延续传递样式(CPS)时使用lambdas实现
调用/cc
。转换为CPS时,每次出现的
call/cc
都可以替换为以下等效项:

(lambda (f k) (f (lambda (v k0) (k v)) k))
其中,
k
是要保存的延续,而
(lambda(vk0)(kv))
是恢复该延续的转义过程(调用时处于活动状态的任何延续
k0
都将被丢弃)


所以,为了回答您对Scheme的问题:是的,它可以完成。

否,要获得完整的连续性支持(不支持单次激发),您将需要堆栈和堆捕获。这一切都发生在一个非常低的层次上。@leppie我很乐意把它作为一个答案。@Frank Shearr:如果我真的成功地实现了它们,我会的:)延续很难,我们去购物吧!海边的人(3.0之前)作弊了:有权访问堆栈,他们只是简单地浏览激活记录,然后将其旋转到流中。在重新激活延续时,他们取消了流的连接并继续。CPS只有在基础语言支持尾部调用时才起作用(在Scheme的情况下,它应该支持尾部调用)。一般来说,这是正确的,但原则上,您可以通过将延续和参数向上返回到某个“CPS驱动程序”循环来手动擦除堆栈帧。CPS将起作用,但问题是,它只适用于您控制的代码(并且可以是CPS)。例如,处理库变得很困难,因为您需要将它们视为外呼,即使它们使用的是您的语言。(顺便说一句,那些“SPC驱动循环”通常被称为填塞。)带有call/cc的公共lisp
真的提供了方案延续的全部功能吗?这一页表明它是有限的:据我的理解,不是。它实际上只是一个语法抽象,但你不能在上面实现真正的协同路由。这就是call/cc通常在Scheme这样的尾部调用优化语言上实现的方式吗?作为一个宏?