Взятие «и» списка путем свертывания в схеме - PullRequest
1 голос
/ 06 февраля 2020

В книге Структура и интерпретация компьютерных программ Х. Абельсона и Дж. Дж. Суссмана с Дж. Суссманом accumulation или fold-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))

Однако, это дало мне ошибку and: bad syntax в DrRacket ( с #lang sicp), и я должен был сделать это вместо:

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

Почему? Я полагаю, что это как-то связано с тем, как and является особой формой, но я недостаточно понимаю Схему, чтобы сказать. Возможно, я просто упускаю очевидную ошибку ...

1 Ответ

2 голосов
/ 06 февраля 2020

Вы ответили на свой вопрос: 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
...