经验丰富的Schemer,letcc和guile

d11*_*wtq 8 scheme functional-programming seasoned-schemer

关于letcc这一点的一些问题在The Seasoned Schemer中使用.

(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))))))
Run Code Online (Sandbox Code Playgroud)
  1. 我想我明白什么letcc实现,那就是基本类似catch,并throw在红宝石(貌似CL),这基本上意味着代码的整体结构可以通过调用任何指定的剪短letcc的.这感觉就像是最"功能性"的事情我已经在这短短的系列丛书遇到,这让我觉得有点犹豫,使用它,因为我想学习的好功能的风格.我只是误解letcc,还是它不是一个真正的函数式编程概念,只是为了提高性能?整个想法,我可以在一些例程的中间,然后突然到达代码中的另一个点感觉有点错误...就像滥用Java中的try/catch程序流程一样.

  2. letcc 似乎不存在于我在OS X中安装的guile版本(1.8.7).我应该在guile中寻找另一个名称吗?

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

Eli*_*lay 11

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

  2. 在那里帮不了你.我知道Guile有一个半新近的延续,但我不知道事情的立场.它应该肯定有call-with-current-continuation,通常也在更友好的名称下call/cc,并且let/cc是一个可以构建的简单宏call/cc.

    我可以告诉你,在Racket中有一个let/cc内置的和一堆其他内置同一个系列中,另外还有一个完整的各种控制操作符(带有大量的引用列表).

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

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

    (define (foo f) (f 100))
    (let/cc k (+ (foo k) "junk") (more junk))
    
    Run Code Online (Sandbox Code Playgroud)
  4. 最后,如果你想阅读更多关于continuation的内容,你可以看到PLAI的相关部分,还有Matthew Might写的更简单的示例概述,你可以看到我写的一些基于PLAI的类注释,一些受后一篇文章启发的例子.

  • 顺便说一句,他的名字是Matthew Might.(他可能是对的,但可能是他的名字.) (4认同)
  • 哇,在阅读Matthew Right撰写的那篇文章后,我的观点发生了变化.我认为实际上理解`call/cc`的工作原理使它看起来比我原先想的要清晰得多.非常感谢您的解释.结果我的版本的guile有`call/cc`和`call-with-current-continuation`,但没有`letcc`.另外,`call/cc`比ruby中的`catch/throw`更有趣,因为它可以让你做更酷的事情.我想The Seasoned Schemer将在后面的章节中更详细地探讨这一点. (2认同)