通过在 Scheme 中折叠获取列表的 'and'

Taking the 'and' of a list by folding in Scheme

在书计算机程序的结构和解释 作者:H. Abelson 和 G. J. Sussman 与 J. Sussman, accumulationfold-right在2.2.3节中介绍如下:

(define (accumulate op initial sequence)
  (if (null? sequence)
      initial
      (op (car sequence)
          (accumulate op initial (cdr sequence)))))

我试图用它来获取布尔变量列表的and,写成:

(accumulate and 
            true 
            (list true true false))

然而,这给了我 DrRacket 中的错误 and: bad syntax(带有 #lang sicp), 而我不得不这样做:

(accumulate (lambda (x y) (and x y))
            true
            (list true true false))

为什么?我相信这与 and 是一种特殊形式有关, 但我对 Scheme 的了解还不够多。 也许我只是遗漏了一些明显的错误...

你回答了你自己的问题:and是一个特殊的形式(不是一个正常的过程!)有特殊的评估规则,accumulate期望一个正常的过程,所以你需要把它包在里面一个程序。

要了解为什么 and 是一种特殊形式,请考虑以下示例,这些示例表明 and 需要特殊的评估规则(与过程不同),因为它会在发现假值时短路:

; division by zero never gets executed
(and #f (/ 1 0))
=> #f

; division by zero gets executed during procedure invocation
((lambda (x y) (and x y)) #f (/ 1 0))
=>  /: division by zero