周围有 lisp 宏的麻烦

trouble with lisp macro around and

所以我想写一个全宏,它接受一个元素列表和 returns 如果它们都是非假的。我想像

这样的宏来做
(defmacro all (ls) 
  `(and ,@ls))

当我用

测试时,这有效
(all (1 2 3))

但不是

(all '(1 2 3)) 

或任何其他列表。我不太确定为什么。我做错了什么?

1. ',quote

是什么意思

's-expression只是(QUOTE s-expression)的语法缩写,所以'(1 2 3)是二元列表(QUOTE (1 2 3))

的缩写

2。如何计算宏

宏是将一种形式(s 表达式)转换为另一种形式的函数,它通常用于向语言添加新的句法结构。

因此,不评估宏的参数。它们是按字面意思获取并绑定到宏参数。

因此宏 all 在使用时将列表参数绑定到 ls 参数而不进行任何计算,并将列表转换为插入原子 and 的新列表第一个元素:

(all (1 2 3))  =>  (AND 1 2 3)

然后解释或编译生成的表格以供后续评估。

如果你写 (all '(1 2 3) 这等同于 (all (QUOTE (1 2 3)) 并且转换如下:

(all '(1 2 3)) => (all (QUOTE (1 2 3)) => (AND QUOTE (1 2 3))

这可能与您的预期不同,并且会产生几个错误(变量 QUOTE 未绑定,(1 2 3) 的汽车不是函数名称或 lambda 表达式)。

3。调试宏

如果你想看一个宏是如何展开的,你可以使用macroexpand-1原始函数(见manual):

CL-USER> (macroexpand-1 '(all (1 2 3)))
(AND 1 2 3)

CL-USER> (macroexpand-1 '(all '(1 2 3)))
(AND QUOTE (1 2 3))

所以这行得通。

(defmacro all (ls)
 `(reduce (lambda (a b) (and a b)) ,ls))

虽然它不那么简洁或令我满意。