Functional programming 老练的阴谋家,letcc和诡计

Functional programming 老练的阴谋家,letcc和诡计,functional-programming,scheme,seasoned-schemer,Functional Programming,Scheme,Seasoned Schemer,这里有几个问题,关于经验丰富的Schemer中使用的letcc (define (intersect-all sets) (letcc hop (letrec ((A (lambda (sets) (cond ((null? (car sets)) (hop '()) ((null? (cdr sets)) (car sets)) (else

这里有几个问题,关于经验丰富的Schemer中使用的
letcc

(define (intersect-all sets)
  (letcc hop
    (letrec
      ((A (lambda (sets)
            (cond
              ((null? (car sets)) (hop '())
              ((null? (cdr sets)) (car sets))
              (else
                (intersect (car sets)
                           (A (cdr sets)))))))
       ; definition of intersect removed for brevity
      (cond
        ((null? sets) '())
        (else (A sets))))))
  • 我想我知道
    letcc
    实现了什么,这基本上类似于ruby中的
    catch
    throw
    (似乎是CL),这基本上意味着可以通过调用任何名为
    letcc
    的函数来缩短整个代码块。这感觉像是我在这本短小的系列书中遇到的最不“实用”的东西,它让我觉得使用它有点犹豫,因为我想学习一种好的实用风格。我只是误解了letcc,还是它不是真正的函数式编程概念,只是为了提高性能而存在?我可以在一些例程中间突然想到代码中的另一个点的感觉有点不对…比如在Java中滥用try/catch来实现程序流

  • letcc
    在我安装在OS X中的guile(1.8.7)版本中似乎不存在。我应该在guile中查找它的其他名称吗

  • 如果我将它与Java中的try/catch或ruby中的catch/throw(这对于非ruby主义者来说不是异常处理,只是为了清楚起见)进行比较,从而误解了
    letcc
    ,那么它在功能级别上究竟是如何工作的?它能不能用一种更长、更复杂的方式来表达,让我相信它毕竟是功能性的

  • “功能性”有多种含义,但没有流行的含义以任何方式与延续相矛盾。但它们也可能被滥用,造成难以阅读的代码。它们不是可以“为程序流滥用”的工具——它们是程序流工具

  • 我帮不了你。我知道在《诡计》中有一些关于续集的半最近版本,但我不知道现在的情况如何。它肯定应该具有当前延续的
    调用
    ,通常也使用更友好的名称
    call/cc
    ,而
    let/cc
    是一个可以使用
    call/cc
    构建的简单宏

    我可以告诉你,在Racket中有一个内置的和一堆的,另外还有一系列不同的控制操作符(有大量的参考文献)

  • let/cc
    的简单用法实际上类似于捕获/抛出之类的东西——更具体地说,这种延续通常被称为“逃逸延续”(或者有时是“向上”)。这就是您在该代码中的用法,通常用于实现
    中止
    返回

    但Scheme中的continuation是可以在任何地方使用的东西。对于显示此差异的非常简单的示例,请尝试以下方法:

    (define (foo f) (f 100))
    (let/cc k (+ (foo k) "junk") (more junk))
    
  • 最后,如果你想读更多关于连续体的内容,你可以看到的相关部分,还有Matthew可能写的更多内容,你可以看到我写的一些基于PLAI的内容,还有一些受后一篇文章启发的例子


  • 如果您有一个同时支持“正常”延续和转义延续的实现,那么使用后者通常比较便宜。您示例中的模式自然适合于转义延续。标准缩写是
    let/ec
    。仅供参考,它显示了如何使用一个简单的宏来定义
    letcc
    ,即
    call/cc
    。@JonO,我以前读过并尝试过它,但guile只是说
    错误:无效语法()
    中止:(杂项错误)
    。检查我已经按照页面上说的方式做了,但仍然不起作用。当我开始学习宏时,我可能会弄明白为什么。谁知道这是在哪里记录的,但是在定义宏之前需要
    (使用语法(ice-9 syncase))
    (至少是定义宏的方式):)哇,在读了Matthew Right的那篇文章之后,我的观点改变了。我认为,实际上理解了
    call/cc
    的工作原理,使它看起来比我最初想象的要干净得多。非常感谢你的解释。原来我的guile版本有
    call/cc
    call与当前的continuation
    ,但没有
    letcc
    。而且,在ruby中,
    call/cc
    catch/throw
    有趣得多,因为它可以让你做更酷的事情。我想这位经验丰富的策划家会在后面的章节中对此进行更详细的探讨。如果你看完了他的课文,那么也可以看看我的课堂笔记:有几个例子扩展得更广,包括生成器和amb的完整开发,首先是对CPS的描述——在其他语言中实现其中一些的方式。顺便说一句,他的名字是Matthew May。(他可能是对的,但他的名字可能是。)
    let/cc
    实际上是
    goto
    s在服用类固醇。如果被滥用,他们将比转到更糟糕。当然,
    let/cc
    也有合法的情况,同样的,
    goto
    也有合法的(受限的)用途,例如
    switch