Macros 是否可以将宏扩展为多个元素?

Macros 是否可以将宏扩展为多个元素?,macros,common-lisp,Macros,Common Lisp,我想要一个宏my macro,它可以扩展到123,而不是(123),以便 (list (my-macro) 4 5) -> (1 2 3 4 5) 这可能吗?不,宏不能扩展到多个值。当需要将宏扩展为多段代码时,典型的做法是将返回值包装在progn中 在您的注释中的示例中,似乎您使用宏不是作为语法抽象,而是作为廉价和令人愉快的函数优化,对此的通常反应是“请不要这样做,这是错误的,实际上并没有做您想做的事情”。不,宏不能扩展到多个值。当需要将宏扩展为多段代码时,典型的做法是将返回值包装在pr

我想要一个宏
my macro
,它可以扩展到
123
,而不是
(123)
,以便

(list (my-macro) 4 5) -> (1 2 3 4 5)

这可能吗?

不,宏不能扩展到多个值。当需要将宏扩展为多段代码时,典型的做法是将返回值包装在
progn


在您的注释中的示例中,似乎您使用宏不是作为语法抽象,而是作为廉价和令人愉快的函数优化,对此的通常反应是“请不要这样做,这是错误的,实际上并没有做您想做的事情”。

不,宏不能扩展到多个值。当需要将宏扩展为多段代码时,典型的做法是将返回值包装在
progn

在您的注释中的示例中,看起来您使用的宏并不是语法抽象,而是廉价而令人愉快的函数优化,对此通常的反应是“请不要这样做,它是错误的,实际上并没有做您想做的事情”。

在Common Lisp中,宏和读取宏都不能做到这一点

如果您真的需要,唯一的解决方案是自己编写一个完整的阅读器,而不使用
read
(问题是
read
将递归调用自身,而不是您的版本)

一个完全兼容的阅读器是一件非常复杂的事情,但是如果您只需要功能的一个子集,而不需要使用它来阅读其他人编写的公共Lisp代码,那么它就可以很简单。

在Common Lisp中,宏和读取宏都不能做到这一点

如果您真的需要,唯一的解决方案是自己编写一个完整的阅读器,而不使用
read
(问题是
read
将递归调用自身,而不是您的版本)


一个完全兼容的阅读器是一件非常复杂的事情,但如果您只需要功能的一个子集,而不需要使用它来阅读其他人编写的公共Lisp代码,那么它可能很简单。

我非常确信,如果要分解通常使用@的列表,则不需要,但这需要它在列表中才能分解。但是,我找不到任何明确说明这一点的参考文献。如果你心里有一个特定的问题想用这个问题来解决,你可能想发布这个问题。@Sim我想将宏扩展为函数调用的参数。现在我必须使用
(apply#'foo(append(my macro)(list 4 5))
而不是
(foo(my macro)4 5)
。后者更简单、更清晰。@Sim读宏似乎不能做到这一点,对吗?@wvxvw
apply
将接受您给定的参数,最后一个参数必须是列表。所以你可以做
(apply'frob bar1 bar2(list bar3 bar4))
,它与
(frob bar1 bar2 bar3 bar4)
相同,但通过相同的过程,
(apply'frob(list bar1 bar2)(list bar3 bar4))
相当于
(frob(list bar1 bar2)bar3 bar4)
。SaltyEgg仍然需要附加参数列表。@SaltyEgg使用apply,它实际上更清楚,因为每个人都知道它的作用,而不是你的(实际上不可能的)宏。我非常确信,不是这样,因为要分解一个通常使用@的列表,但这需要它在列表中才能分解。但是,我找不到任何明确说明这一点的参考文献。如果你心里有一个特定的问题想用这个问题来解决,你可能想发布这个问题。@Sim我想将宏扩展为函数调用的参数。现在我必须使用
(apply#'foo(append(my macro)(list 4 5))
而不是
(foo(my macro)4 5)
。后者更简单、更清晰。@Sim读宏似乎不能做到这一点,对吗?@wvxvw
apply
将接受您给定的参数,最后一个参数必须是列表。所以你可以做
(apply'frob bar1 bar2(list bar3 bar4))
,它与
(frob bar1 bar2 bar3 bar4)
相同,但通过相同的过程,
(apply'frob(list bar1 bar2)(list bar3 bar4))
相当于
(frob(list bar1 bar2)bar3 bar4)
。SaltyEgg仍然需要附加参数列表。@SaltyEgg使用apply,它实际上更清楚,因为每个人都知道它的作用,而不是你的(实际上不可能的)宏。