Macros lisp宏周围和周围的问题

Macros lisp宏周围和周围的问题,macros,common-lisp,Macros,Common Lisp,所以我想写一个all宏,它接受一个元素列表,如果它们都是非假的,则返回。我想把它当作一个宏来做 (defmacro all (ls) `(and ,@ls)) 当我使用 (all (1 2 3)) 但不是 (all '(1 2 3)) 或任何其他清单。我真的不知道为什么。我做错了什么。“引用”的含义是什么 's-expression只是(QUOTE s-expression)的语法缩写,因此'(1 2 3)是双元素列表(QUOTE(1 2 3))的缩写。 2。如何评估宏 宏是将一种

所以我想写一个all宏,它接受一个元素列表,如果它们都是非假的,则返回。我想把它当作一个宏来做

(defmacro all (ls) 
  `(and ,@ls))
当我使用

(all (1 2 3))
但不是

(all '(1 2 3)) 

或任何其他清单。我真的不知道为什么。我做错了什么。“引用”的含义是什么

's-expression
只是
(QUOTE s-expression)
的语法缩写,因此
'(1 2 3)
是双元素列表
(QUOTE(1 2 3))的缩写。

2。如何评估宏

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

因此,不会计算宏的参数。它们按字面理解并绑定到宏参数

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

(all (1 2 3))  =>  (AND 1 2 3)
然后解释或编译生成的表单以进行后续评估

如果您编写
(all'(1 2 3)
,这相当于
(all(1 2 3))
,转换如下:

(all '(1 2 3)) => (all (QUOTE (1 2 3)) => (AND QUOTE (1 2 3))
这可能与您所期望的不同,并且会产生一些错误(变量
QUOTE
未绑定,
(1 2 3)
的car不是函数名或lambda表达式)

3.调试宏

如果要查看宏是如何展开的,可以使用
macroexpand-1
原语函数(请参阅):


1.引用的含义是什么

's-expression
只是
(QUOTE s-expression)
的语法缩写,因此
'(1 2 3)
是双元素列表
(QUOTE(1 2 3))的缩写。

2.如何评估宏

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

由于这个原因,宏的参数不会被计算。它们会被逐字理解并绑定到宏参数

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

(all (1 2 3))  =>  (AND 1 2 3)
然后解释或编译生成的表单以进行后续评估

如果您编写
(all'(1 2 3)
,这相当于
(all(1 2 3))
,转换如下:

(all '(1 2 3)) => (all (QUOTE (1 2 3)) => (AND QUOTE (1 2 3))
这可能与您所期望的不同,并且会产生一些错误(变量
QUOTE
未绑定,
(1 2 3)
的car不是函数名或lambda表达式)

3.调试宏

如果要查看宏是如何展开的,可以使用
macroexpand-1
原语函数(请参阅):

所以这是可行的

(defmacro all (ls)
 `(reduce (lambda (a b) (and a b)) ,ls))
虽然我觉得它不那么简洁,也不那么讨人喜欢。

所以这是可行的

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

虽然对我来说并不简洁或令人愉快。

我认为,@x应该计算x并在值中拼接。因此,我不知道如何将实际列表传递给该宏,该宏将根据需要粘贴到and表达式中。@x使用与x关联的s表达式(即(1 2 3)),并拼接列表。但传递给宏的内容永远不会计算。您无法将运行时值传递给宏。例如,如果执行
(let((x'(1 2 3)))(all x))
操作,则会得到错误:“值x不是预期的列表类型。”。这是因为与
ls
关联的s表达式是符号
X
,而不是它的值。宏不能用于在运行时计算值,因为它应该使用一个函数。我真的不明白。是不是说无法在宏中展开列表?我不相信是这样的。我相信一定有正确执行此操作的方法。对于周围的let,甚至在调用宏之前就已经对列表进行了求值。当宏仍然不起作用时,我也尝试了let。您应该区分文本列表,如(1 2 3)和求值为列表的内容(例如变量)。您的宏接受文本列表,而泛型函数可以接受任何计算为列表的表达式。因此,只能使用必须修改的文本列表调用宏,而不能使用任何计算为列表的表达式,如变量、函数或宏调用等。我想,@x应该计算x和splic因此,我不知道如何将实际列表传递给这个宏,该宏将根据需要粘贴到and表达式中。@x采用与x关联的s表达式(即(1 2 3)),并拼接列表。但传递给宏的内容永远不会计算。您无法将运行时值传递给宏。例如,如果执行
(let((x'(1 2 3)))(all x))
操作,则会得到错误:“值x不是预期的列表类型。”。这是因为与
ls
关联的s表达式是符号
X
,而不是它的值。宏不能用于在运行时计算值,因为它应该使用一个函数。我真的不明白。是不是说无法在宏中展开列表?我不相信是这样的。我相信一定有正确执行此操作的方法。对于周围的let,甚至在调用宏之前就已经对列表进行了求值。当宏仍然不起作用时,我也尝试了let。您应该区分文本列表,如(1 2 3)和求值为列表的内容(例如变量)。您的宏