Common Lisp 中是否有非延迟评估的 "and" 或 "or" 操作?
Are there non-lazily evaluated "and" or "or" operations in Common Lisp?
Common Lisp 中常用的 and
和 or
运算符将延迟计算它们的操作数,例如and
会在遇到第一个 nil
时停止。我正在寻找一个不以这种方式工作的运算符,而是总是在返回结果之前评估所有操作数。有这样的吗?
例如,在 C 中,您有惰性 &&
和按位 &
,它们可以用作非惰性替代方案。
我知道 logand
和 bit-and
,但它们不适用于布尔操作数。
例如:
(and NIL (not-defined))
不会抛出错误,但我希望它抛出一个错误。
(defun and* (&rest l)
(every #'identity l))
如果全部为真则返回最后一个值
(defun and& (&rest l)
(or (null l)
(loop for b in l
unless b
do (return nil)
finally (return b))))
或
(defun and& (&rest l)
(or (null l)
(loop for b in l
always b
finally (return b))))
一个可能的实现是
(defun and* (&rest x)
(let ((res T))
(dolist (item x)
(if (null item) (return-from and* item))
(setf res item))
res))
解释:
- 我们将结果初始化为
T
(这是需要的,因为(and)
→T
)
- 我们遍历参数
- 如果参数是
NIL
那么我们 return 它
- 否则我们将项目存储为结果
- 如果我们到达循环的末尾,那么我们 return 最后一项
or*
的实现更简单,因为 Common Lisp 中唯一的 "falsy" 值是 NIL
所以不需要记住最后一个 falsy 元素是什么,你可以使用some
...
(defun or* (&rest x)
(some #'identity x))
and*
的替代实现:
(defun and* (&rest values &aux (res t))
(every (lambda (v) (setf res v)) values)
res)
这 returns 最后一个非零值或 nil
。
Common Lisp 中常用的 and
和 or
运算符将延迟计算它们的操作数,例如and
会在遇到第一个 nil
时停止。我正在寻找一个不以这种方式工作的运算符,而是总是在返回结果之前评估所有操作数。有这样的吗?
例如,在 C 中,您有惰性 &&
和按位 &
,它们可以用作非惰性替代方案。
我知道 logand
和 bit-and
,但它们不适用于布尔操作数。
例如:
(and NIL (not-defined))
不会抛出错误,但我希望它抛出一个错误。
(defun and* (&rest l)
(every #'identity l))
如果全部为真则返回最后一个值
(defun and& (&rest l)
(or (null l)
(loop for b in l
unless b
do (return nil)
finally (return b))))
或
(defun and& (&rest l)
(or (null l)
(loop for b in l
always b
finally (return b))))
一个可能的实现是
(defun and* (&rest x)
(let ((res T))
(dolist (item x)
(if (null item) (return-from and* item))
(setf res item))
res))
解释:
- 我们将结果初始化为
T
(这是需要的,因为(and)
→T
) - 我们遍历参数
- 如果参数是
NIL
那么我们 return 它 - 否则我们将项目存储为结果
- 如果我们到达循环的末尾,那么我们 return 最后一项
or*
的实现更简单,因为 Common Lisp 中唯一的 "falsy" 值是 NIL
所以不需要记住最后一个 falsy 元素是什么,你可以使用some
...
(defun or* (&rest x)
(some #'identity x))
and*
的替代实现:
(defun and* (&rest values &aux (res t))
(every (lambda (v) (setf res v)) values)
res)
这 returns 最后一个非零值或 nil
。