Scheme 电话/抄送详情

Scheme 电话/抄送详情,scheme,continuations,callcc,Scheme,Continuations,Callcc,这与,但我不想为了我自己的目的劫持这个问题,它的一些论点,比如setjmp/longjmp的类比,回避了我 我想我对什么是continuation有足够的了解,我认为它是当前调用堆栈的快照。我不想讨论为什么这可能很有趣,或者你可以用continuations做什么。我的问题更具体一些,为什么我必须提供一个函数参数来调用/cc?为什么call/cc不直接返回当前的延续,这样我就可以用它做任何我想做的事情(存储它,调用它,你可以命名它)?在另一个问题()的一个链接中,它谈到了“本质上,这只是一种干净

这与,但我不想为了我自己的目的劫持这个问题,它的一些论点,比如setjmp/longjmp的类比,回避了我


我想我对什么是continuation有足够的了解,我认为它是当前调用堆栈的快照。我不想讨论为什么这可能很有趣,或者你可以用continuations做什么。我的问题更具体一些,为什么我必须提供一个函数参数来调用/cc?为什么call/cc不直接返回当前的延续,这样我就可以用它做任何我想做的事情(存储它,调用它,你可以命名它)?在另一个问题()的一个链接中,它谈到了“本质上,这只是一种干净的方式,可以让你继续下去,并且避免后续跳转回到保存的点。”,但我不明白。它似乎不必要地复杂。

那样就不那么通用了。如果你想要这种行为,你可以:

(call/cc (lambda (x) x))

您可以查看“Darrell Ferguson and Dwight Deugo.”当前延续模式调用“.第八届程序模式语言会议.2001年9月.”()中延续的示例用法,并尝试使用上述定义的Call/cc return重写它们。

如果您使用类似Jay shows的构造,然后您可以获取延续,但在某种程度上,获取的值已经被破坏,因为您已经在该延续中。相反,
call/cc
可用于获取当前表达式外部仍挂起的延续。例如,continuations最简单的用法之一是实现一种
中止

(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

另外两个相关说明:

  • 有关连续性的实用介绍,请参见
  • call/cc
    有点复杂,因为它需要一个函数——一个概念上更容易使用的构造是
    let/cc
    ,您可以在一些实现(如PLT Scheme)中找到它。上述示例变为
    (let/cc abort(+12(abort 9))

  • 我建议你先问问自己:一流的继续教育意味着什么

    表达式的延续基本上由两部分数据组成:第一,表达式的闭包(即环境);第二,表示应该对表达式的结果执行什么操作。因此,具有一级连续性的语言是一种具有封装这些部分的数据结构的语言,它将这些数据结构与其他任何语言一样对待

    call/cc是实现这一思想的一种特别优雅的方式:当前的continuation被打包为一个过程,该过程将对表达式所做的事情封装为应用于表达式时该过程所做的事情;以这种方式表示延续只意味着此过程的结束包含调用它的站点上的环境

    你可以想象以其他方式实现一流延续的想法。它们不会是call/cc,我很难想象这样的表示方式会更简单

    在一个分离注释中,考虑ELEI所提到的LE/CC的实现,我更喜欢称为BANN/CC:

    (define-syntax bind/cc
        (syntax-rules ()
            ((bind/cc var . body)
                 (call/cc (lambda (var) . body)))))
    

    作为练习,您将如何在bind/cc的基础上实现call/cc?

    针对常见的SO netiquette我回答自己的问题,但更多的是作为编辑而不是答案的提供者

    过了一段时间,我又开始问一个类似的问题。毕竟,这些人整天都在思考语言设计,不是吗?他们中的一个最终被我踢了进来。现在这里提到的事情,例如Eli或原始问题中提到的,对我来说更有意义。这一切都是关于在延续中包含什么,以及应用的延续在哪里

    伦敦交通大学的一名学生写道:

    “你可以清楚地看到call/cc是如何让你“躲开”的。对于em或get/cc,你需要做一些测试来确定你是否有一个后跳转或只是最初的调用。基本上,call/cc不让继续使用,而对于get/cc或em,继续包含它的用法,因此(通常)您需要在继续部分的开头添加一个测试(即紧跟get/cc/em之后),以将“使用继续部分”与“继续部分的其余部分”分开

    这让我回到了家


    无论如何,谢谢你们

    谢谢你向我展示我是如何堕落到这个角落的。但是我想要的是一个解释,而不是一个解决方案。所以,你在回答我的问题时说的是,(a)如果延续立即被返回,它就被“破坏”了,因为我在延续中。但我不能在一个延续中,除非我调用它。如果连续体是一流的价值观,它们不能通过传递而被破坏,是吗?!然后,您说(b)call/cc将获取一个“挂起”的延续。值如何可以挂起?你也可以说(c)延续是当前表达式的“外部”。我不太明白。续集能捕获多少?一切正常,但不包括呼叫/抄送?!是的,你已经进入了续集。关于continuations的一点是,它们表示当前call/cc表达式完成后的“未来”计算——因此,在完成(call/cc(lambda(k)k))之后,您立即继续刚才捕获的continuation。请注意,“continuation”的视图表示当前堆栈有助于实现它,但不理解我