为什么(apply和'(1 2 3))在(和1 2 3)在R5RS中不能工作? [英] Why (apply and '(1 2 3)) doesn't work while (and 1 2 3) works in R5RS?
问题描述
我在球拍中这样尝试过
> (apply and '(1 2 3))
. and: bad syntax in: and
> (and 1 2 3)
3
有人对此有想法吗?
推荐答案
Chris Jester-Young的答案是正确的,但是还有一点我想强调.标准的and
运算符是一个宏,它通过(本质上,如果不是完全正确的话)将(and a b c)
转换为(if a (if b c #f) #f)
来延迟对其参数的求值.这意味着如果a
为false,则不会评估b
和c
.
Chris Jester-Young's answer is right, but there's one other point I want to highlight. The standard and
operator is a macro which delays the evaluation of its arguments, by (essentially, if not exactly) turning (and a b c)
into (if a (if b c #f) #f)
. This means that if a
is false, b
and c
do not get evaluated.
我们还可以选择定义and-function
,以便(and-function a b c)
计算a
,b
和c
,并在所有值均为true时返回true.这意味着所有a
,b
和c
都将得到评估. and-function
具有不错的属性,您可以将它作为函数传递,因为它是一个函数.
We also have the option of defining an and-function
such that (and-function a b c)
evaluates a
, b
, and c
, and returns true when the values are all true. This means that all of a
, b
, and c
get evaluated. and-function
has the nice property that you can pass it around as function because it is a function.
似乎仍然缺少一个选项:and-function-delaying-evaluation
仅当a
,b
和c
都返回true时返回return,但不求值,例如b
和c
(如果a
产生false).实际上,这可以通过功能and-funcalling-function
来实现,该功能要求其参数为功能列表.例如:
There's still one option that seems to be missing: an and-function-delaying-evaluation
that returns return if and only if a
, b
, and c
all return true, but that doesn't evaluate, e.g., b
and c
if a
produces false. This can be had, actually, with a function and-funcalling-function
that requires its arguments to be a list of functions. For instance:
(define (and-funcalling-function functions)
(or (null? functions)
(and ((car functions))
(and-funcalling-function (cdr functions)))))
(and-funcalling-function
(list (lambda () (even? 2))
(lambda () (odd? 3))))
; => #t
(and-funcalling-function
(list (lambda () (odd? 2))
(lambda () (even? 3)))) ; (even? 3) does not get evaluated
; => #f
使用宏和这个惯用语,我们实际上可以使用标准的and
语义实现某些东西:
Using a macro and this idiom, we can actually implement something with the standard and
semantics:
(define-syntax standard-and
(syntax-rules ()
((standard-and form ...)
(and-funcalling-function (list (lambda () form) ...)))))
(macroexpand '(standard-and (odd? 2) (even? 3)))
; =>
; (and-funcalling-function
; (list (lambda () (odd? 2))
; (lambda () (even? 3))))
当然,可以从中得到的教训是,您可以拥有类似and
的函数,可以将其传递出去,并且仍然获得延迟的评估.您只需要通过将函数包装在函数中并让类似and
的函数调用来产生值来延迟评估. (在Scheme中,这可能是使用诺言的机会.)
The lesson to take away from this, of course, is that you can have an and
-like function that you can pass around and still get delayed evaluation; you just need to delay evaluation by wrapping things in functions and letting the and
-like function call those functions to produce values. (In Scheme, this might be an opportunity to use promises.)
这篇关于为什么(apply和'(1 2 3))在(和1 2 3)在R5RS中不能工作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!