经验丰富的Schemer,letcc和guile

时间:2012-06-19 15:05:01

标签: functional-programming scheme seasoned-schemer

这里有几个问题,关于The Seasoned 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))))))
  1. 我想我明白了letcc取得了什么,这基本上类似于ruby(和看似CL)中的catchthrow,这基本上意味着整个块通过调用名为letcc的任何内容,可以缩短代码。这感觉就像我在这一系列短篇小说中遇到的最少“功能性”的东西,它让我觉得有点犹豫使用它,因为我想要学习一个好的功能风格。我只是误解letcc,还是它不是一个真正的函数式编程概念而只是为了提高性能?整个想法,我可以在一些例程的中间,然后突然到达代码中的另一个点感觉有点错误...就像滥用Java中的try / catch程序流一样。

  2. letcc似乎不存在于我在OS X中安装的guile(1.8.7)版本中。是否还有其他名称,我应该在guile中寻找它?< / p>

  3. 如果我通过将它与Java中的try / catch进行比较来误解letcc,或者抓住/抛出ruby(这是异常处理,只是为了清楚,对于非rubyists),它在功能层面上究竟是如何工作的?是否可以用更长,更复杂的方式表达,这让我觉得它毕竟是有用的?

1 个答案:

答案 0 :(得分:11)

  1. “功能”有几个含义,但没有任何流行的含义以任何方式与延续相矛盾。但是他们可以被滥用来创建难以阅读的代码。它们不是可以“滥用程序流程”的工具 - 它们程序流程工具。

  2. 无法帮助你。我知道Guile有一个半新近的延续,但我不知道事情的立场。它应该是call-with-current-continuation,通常也是call/cc更友好的名称,而let/cc是一个可以使用call/cc构建的简单宏。

    我可以告诉你,在Racket中let/cc内置了others builtins中的same family whole library,另外还有PLAI个各种控制运算符(附有大量参考文献。)。

  3. let/cc的简单用法确实类似于捕获/抛出的东西 - 更具体地说,这种延续通常被称为“逃避延续”(或有时“向上”)。这是您在该代码中使用的一种用法,通常用于实现abortreturn

    但Scheme中的延续是可以在任何地方使用的东西。有关显示此差异的非常简单的示例,请尝试以下操作:

    (define (foo f) (f 100))
    (let/cc k (+ (foo k) "junk") (more junk))
    
  4. 最后,如果你想了解更多关于延续的内容,你可以看到brief by-example overview的相关部分,还有更多的class notes,Matthew Might写的,你可以看到一些{{3}} {3}}我写的是基于PLAI的,其中一些例子受到后一篇文章的启发。