【问题标题】:The Seasoned Schemer, letcc and guile经验丰富的计划者,letcc 和诡计
【发布时间】:2012-06-21 15:54:13
【问题描述】:

这里有几个问题,关于 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​​ 中的 catchthrow(看起来是 CL),这基本上意味着可以缩短整个代码块调用名为 letcc 的任何名称。这感觉就像我在这一系列短书中遇到的最不“实用”的东西,它让我觉得使用它有点犹豫,因为我想学习一种好的实用风格。我只是误解了letcc,还是它不是一个真正的函数式编程概念,只是为了提高性能而存在?我可以在一些例程中间然后突然进入代码中的另一个点的整个想法感觉有点不对……就像在 Java 中滥用 try/catch 来进行程序流一样。

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

  3. 1234563非红宝石主义者),它在功能层面上究竟是如何工作的?它能否以更长、更复杂的方式表达,让我相信它毕竟是功能性的?

【问题讨论】:

  • 如果您的实现同时支持“正常”延续和转义延续,则使用后者通常更便宜。您示例中的模式非常适合转义延续。标准缩写为let/ec
  • 仅供参考,this page 展示了如何使用简单的宏根据call/cc 定义letcc
  • @JonO,我之前读过并尝试过,但诡计只是说ERROR: invalid syntax ()ABORT: (misc-error)。检查我已经按照页面上说的方式完成了它,但它仍然不起作用。当我开始学习宏时,我可能会弄清楚为什么。
  • 谁知道这是在哪里记录的,但是在定义宏之前需要(use-syntax (ice-9 syncase))(至少是定义宏的方式):)

标签: functional-programming scheme seasoned-schemer


【解决方案1】:
  1. “功能”有多种含义,但没有任何通俗的含义与延续有任何矛盾。但是它们可以被滥用来创建难以阅读的代码。它们不是可以“被滥用于程序流程”的工具——它们程序流程工具。

  2. 那里帮不了你。我知道 Guile 有半新的续集,但我不知道情况如何。它肯定应该有call-with-current-continuation,通常也使用更友好的名称call/cc,而let/cc 是一个可以用call/cc 构建的简单宏。

    我可以告诉你,在 Racket 中有一个内置的 let/cc 和一堆 others builtinssame family 中,另外还有一个 whole library 的各种控制运算符(带有大量参考列表。 )。

  3. let/cc 的简单用法确实类似于 catch/throw 类型的东西——更具体地说,这种延续通常称为“转义延续”(或有时“向上”)。这就是您在该代码中的用途,通常用于实现abortreturn

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

    (define (foo f) (f 100))
    (let/cc k (+ (foo k) "junk") (more junk))
    
  4. 1234563基于 PLAI 编写的,其中一些示例受后一篇文章的启发。

【讨论】:

  • 哇,在阅读了 Matthew Right 的那篇文章后,我的看法发生了变化。我认为真正了解call/cc 的工作原理使它看起来比我最初想的要干净得多。非常感谢您的解释。原来我的 guile 版本有call/cccall-with-current-continuation,但没有letcc。此外,call/cc 比 ruby​​ 中的catch/throw 有趣得多,因为它可以让你做更酷的事情。我想经验丰富的计划者将在后面的章节中更详细地探讨这一点。
  • 如果你读完了他的课文,那么也可以看看我的课堂笔记:有几个例子得到了更多的扩展,生成器和 amb 的完整开发,它开始于对 CPS 的描述——用其他语言实现其中一些的方式。
  • 顺便说一句,他的名字叫马修·梅特。 (他可能是对的,但他的名字是 Might。)
  • let/cc 实际上是类固醇上的gotos。如果被滥用,他们会比gotos 更糟。当然,let/cc 也有合法的情况,就像goto 的合法(受限)用途一样,例如switch
猜你喜欢
  • 1970-01-01
  • 2023-03-10
  • 2010-11-15
  • 1970-01-01
  • 2012-06-18
  • 2020-07-25
  • 1970-01-01
  • 2011-03-12
  • 1970-01-01
相关资源
最近更新 更多