这与What is call/cc?有关,但我不想为了自己的目的而劫持这个问题,而且它的一些论点,比如对setjmp/longjmp的类比,都回避了我。
我想我对延续是什么已经有了足够的了解,我认为它是当前调用堆栈的快照。我不想深入讨论为什么这可能很有趣,或者您可以使用continuations做些什么。我的问题更具体地说,为什么我必须提供一个函数参数来调用/cc?为什么不调用/cc只返回当前的延续,这样我就可以随心所欲地处理它(存储它,调用它,你能说出它的名字)?在另一个问题(http://community.schemewiki.org/?call-with-current-continuation-for-C-programmers)的链接中,它谈到了“本质上这只是一种干净的方式,可以让你获得延续,并避免随后跳回保存的点。”,但我没有得到它。这似乎是不必要的复杂。
发布于 2009-12-08 06:30:31
与常见的网络礼仪相比,我是在回答自己的问题,但更多的是作为编辑而不是答案的提供者。
过了一段时间,我在LtU上开始了一个类似的问题。毕竟,这些人整天都在思考语言设计,不是吗,其中一位answers终于和我一起工作了。现在,这里提到的事情,例如Eli或在原始问题中提到的事情,对我来说更有意义。这一切都是关于在延续中包含什么,以及应用的延续在哪里开始。
LtU的一位posters写道:
“你可以确切地看到call/cc如何允许你”避开“。对于em或get/cc,你需要做一些测试来确定你是有一个反向跳转,还是仅仅是初始调用。基本上,call/cc会将延续的使用排除在延续之外,而对于get/cc或em,延续包含它的使用,因此(通常)你需要在延续的开始处(即紧跟在get/cc /em之后)添加一个测试,以将”使用延续部分“与”其余的延续部分“分开。”
为我把它带回了家。
不管怎样,谢谢你们!
发布于 2009-07-14 03:45:10
如果你使用像Jay show这样的结构,那么你可以抓取延续,但在某种程度上,抓取的值已经被破坏了,因为你已经在那个延续中了。相反,call/cc
可用于获取在当前表达式之外仍处于挂起状态的延续。例如,延续最简单的用法之一就是实现一种abort
(call/cc (lambda (abort)
(+ 1 2 (abort 9))))
您不能使用您描述的操作来做到这一点。如果你尝试一下:
(define (get-cc) (call/cc values))
(let ([abort (get-cc)]) (+ 1 2 (abort 9)))
然后,您会得到一个关于将9
作为过程应用的错误。之所以会发生这种情况,是因为abort
使用新值9
跳回到let
--这意味着您现在正在执行第二轮相同的加法表达式,只不过现在abort
绑定到了9
……
另外两个相关注释:
对于continuations的一个很好的实用介绍,请参见PLAI.
call/cc
有点复杂,因为它接受一个函数--一个概念上更容易使用的结构是let/cc
。上面的例子变成了(let/cc abort (+ 1 2 (abort 9)))
.发布于 2009-07-13 14:57:34
这就不那么通用了。如果你想要这样的行为,你可以这样做:
(call/cc (lambda (x) x))
你可以看一下"Darrell Ferguson and Dwight Deugo. "Call with Current Conference“.第8次会议on Pattern Languages of Programs.2001年9月.”(http://library.readscheme.org/page6.html)中的延续用法示例,并尝试使用上面定义的调用/cc-return重写它们。
https://stackoverflow.com/questions/1119914
复制相似问题