Common Lisp中是否存在非延迟求值的“与”或“或”运算?

时间:2019-08-13 12:54:52

标签: boolean common-lisp lazy-evaluation

Common Lisp中常用的andor运算符会延迟计算其操作数,例如and一旦遇到第一个nil,就会停止。我正在寻找一个不能以这种方式工作的运算符,而是总是在返回结果之前对所有操作数求值。有这样的东西吗?

例如,在C中,您有惰性&&和按位&,它们可以用作非惰性替代。 我知道logandbit-and,但是它们不适用于布尔操作数。

例如:

(and NIL (not-defined))

不会抛出错误,但是我希望它抛出一个错误。

3 个答案:

答案 0 :(得分:3)

(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))))

答案 1 :(得分:2)

可能的实现方式是

(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,则我们将其返回
  • 否则,我们将项目存储为结果
  • 如果我们到达循环的结尾,那么我们将返回最后一个项目

or*的实现较为简单,因为Common Lisp中唯一的“ falsy”值是NIL,因此无需记住最后一个falsy元素是什么,您可以使用{{1} } ...

some

答案 2 :(得分:1)

and*的替代实现:

(defun and* (&rest values &aux (res t))
  (every (lambda (v) (setf res v)) values)
  res)

这将返回最后一个非空值或nil