问题
In the book Structure and Interpretation of Computer Programs
by H. Abelson and G. J. Sussman with J. Sussman,
the accumulation
or fold-right
is introduced in Section 2.2.3 as follows:
(define (accumulate op initial sequence)
(if (null? sequence)
initial
(op (car sequence)
(accumulate op initial (cdr sequence)))))
I tried to use this to take the and
of a list of Boolean variables, by writing:
(accumulate and
true
(list true true false))
However, this gave me the error and: bad syntax
in DrRacket (with #lang sicp
),
and I had to do this instead:
(accumulate (lambda (x y) (and x y))
true
(list true true false))
Why? I believe it has something to do with how and
is a special form,
but I don't understand Scheme enough to say.
Perhaps I'm just missing some obvious mistake...
回答1:
You answered your own question: and
is a special form (not a normal procedure!) with special evaluation rules, and accumulate
expects a normal procedure, so you need to wrap it inside a procedure.
To see why and
is a special form, consider these examples that demonstrate that and
requires special evaluation rules (unlike procedures), because it short-circuits whenever it finds a false value:
; 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
来源:https://stackoverflow.com/questions/60092146/taking-the-and-of-a-list-by-folding-in-scheme