【问题标题】:leftmost and lm in Seasoned Schemer经验丰富的计划者中的最左边和 lm
【发布时间】:2023-03-10 23:02:01
【问题描述】:

第 78 页上经验丰富的计划者对 leftmostlm 的定义如下。

(define leftmost
  (lambda (l)
    (letcc skip
      (lm l skip))))

(define lm
  (lambda (l out)
    (cond
      ((null? l) (quote ()))
      ((atom? (car l)) (out (car l)))
      (else (let ()
              (lm (car l) out)
              (lm (cdr l) out))))))

在下一页上,它对值部分中有多个表达式进行了以下说明。我不明白它如何使leftmost 工作的解释,例如(() a)

当 (let ...) 的值部分有两个表达式时,我们必须首先确定第一个表达式的值。如果它有一个,我们忽略它并确定第二个表达式的值。”

【问题讨论】:

  • @LittleBobbyTables 有 several 标签用于特定书籍,例如:sicp、the-little-schemer、clrs 等。这对于学习如何学习的书籍特别有用程序,人们需要在他们的问题中参考具体的书,所以请不要因为你不同意就删除新创建的书标签,其他人可能会觉得它有用

标签: scheme let seasoned-schemer


【解决方案1】:

关键在于out 在这种情况下是一个延续。延续与过程不同,一旦调用就不会返回。

所以,let 中的两个表达式依次执行:首先是(lm (car l) out),然后是(lm (cdr l) out)。因为out 是一个延续,并且在遇到原子时调用它,所以如果在(car l) 中遇到原子,(lm (car l) out) 将不会返回。所以(lm (cdr l) out) 只会在(car l) 中没有原子的情况下才会发生---您的(() a) 示例就是这种情况。

【讨论】:

  • 因此在示例(() a) 上,它将递归执行(lm (car l) out),其计算结果为(quote ()),并且由于这不是原子计算,因此将继续进行(lm (cdr l) out)。但是书中哪里解释了具有多个值的let 表达式将按顺序计算它们,直到它碰到第一个原子?
  • @user782220 如果一个let body 有多个表达式,每个表达式都会依次执行;它不关心它是否击中原子。神奇的是(lm (car l) out) 可能会调用out(通过(out (car l))),这是一个延续。这就是它“爆发”而不是继续使用(lm (cdr l) out)的原因。
猜你喜欢
  • 2012-06-21
  • 1970-01-01
  • 2010-11-15
  • 2023-04-08
  • 2012-06-18
  • 1970-01-01
  • 2012-03-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多