为什么 AND 是 common lisp 中的一个宏
Why is AND a macro in common lisp
正如标题所说:为什么and
是宏而不是函数?
我试图申请和列出并得到一个错误,经过一些搜索,我发现我应该做类似 (every #'identify list)
的事情。
但现在我想知道为什么and
是一个宏,我找不到任何好的解释。
想象一下这个函数:
(defun my-every (predicate list)
(or (null list)
(and (funcall predicate (car list))
(my-every predicate (cdr list)))))
如果 and
或 or
是函数,则此函数将始终是一个无限循环。这同时使用了 or
和 and
短路的事实。例如,如果 list
是 nil
那么整个事情就是 t
并且没有进一步的处理。如果 (funcall predicate (car list))
是 nil
那么这是因为 and
短路错误的结果。
事实上,or
和 and
都可以使用 if
来实现,所以也可以这样写:
(defun my-every (predicate list)
(if (null list)
T
(if (funcall predicate (car list))
(my-every predicate (cdr list))
NIL)))
逻辑运算符和控制结构
and
根据定义和设计都是 控制结构 和 逻辑运算符 .
and
和 or
等逻辑运算符也是有用的控制结构。因此它们不能是函数,因为所有参数都将在调用运算符之前进行评估。需要将它们定义为 内置运算符 或函数。 Common Lisp 的设计具有最少数量的 内置运算符 并且 and
/or
功能可以由宏提供,它扩展到其他结构,如...因此选择那些是宏。
CLtL2
是这样描述的:
To put it another way, the and
special form does short-circuit Boolean evaluation, like the and then
operator in Ada and what in some Pascal-like languages is called cand
(for conditional and); the Lisp and special form is unlike the Pascal or Ada and
operator, which always evaluates both arguments.
文中略有错误:(and ...)
不是特殊形式,而是宏形式
正如标题所说:为什么and
是宏而不是函数?
我试图申请和列出并得到一个错误,经过一些搜索,我发现我应该做类似 (every #'identify list)
的事情。
但现在我想知道为什么and
是一个宏,我找不到任何好的解释。
想象一下这个函数:
(defun my-every (predicate list)
(or (null list)
(and (funcall predicate (car list))
(my-every predicate (cdr list)))))
如果 and
或 or
是函数,则此函数将始终是一个无限循环。这同时使用了 or
和 and
短路的事实。例如,如果 list
是 nil
那么整个事情就是 t
并且没有进一步的处理。如果 (funcall predicate (car list))
是 nil
那么这是因为 and
短路错误的结果。
事实上,or
和 and
都可以使用 if
来实现,所以也可以这样写:
(defun my-every (predicate list)
(if (null list)
T
(if (funcall predicate (car list))
(my-every predicate (cdr list))
NIL)))
逻辑运算符和控制结构
and
根据定义和设计都是 控制结构 和 逻辑运算符 .
and
和 or
等逻辑运算符也是有用的控制结构。因此它们不能是函数,因为所有参数都将在调用运算符之前进行评估。需要将它们定义为 内置运算符 或函数。 Common Lisp 的设计具有最少数量的 内置运算符 并且 and
/or
功能可以由宏提供,它扩展到其他结构,如...因此选择那些是宏。
CLtL2
是这样描述的:
To put it another way, the
and
special form does short-circuit Boolean evaluation, like theand then
operator in Ada and what in some Pascal-like languages is calledcand
(for conditional and); the Lisp and special form is unlike the Pascal or Adaand
operator, which always evaluates both arguments.
文中略有错误:(and ...)
不是特殊形式,而是宏形式