为什么(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?

查看:83
本文介绍了为什么(apply和'(1 2 3))在(和1 2 3)在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,则不会评估bc.

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)计算abc,并在所有值均为true时返回true.这意味着所有abc都将得到评估. 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仅当abc都返回true时返回return,但不求值,例如bc(如果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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆