Common lisp (列表.值)不是正确的列表

Common lisp (列表.值)不是正确的列表,common-lisp,Common Lisp,下面是一个示例代码: (defun my-test (&rest values) (macrolet ((my-macro (v) `(list ,@v))) (print values) (my-macro values))) (my-test 1 2 3 4) ;; The goal is to obtain : (1 2 3 4). 当我执行最后一行时,它会打印(1 2 3 4),然后函数失败。 当我执行defun或尝试执行最后

下面是一个示例代码:

(defun my-test (&rest values)
  (macrolet ((my-macro (v)
               `(list ,@v)))
    (print values)
    (my-macro values)))

(my-test 1 2 3 4)
;; The goal is to obtain : (1 2 3 4).
当我执行最后一行时,它会打印
(1 2 3 4)
,然后函数失败。 当我执行defun或尝试执行最后一行时,我得到以下警告/错误(resp.):


为什么失败?

一个宏转换代码,它不知道任何关于运行时值的信息,只知道文本代码。例如

(cond (p1 e1) (p2 e2) (t e3))
变成

(if p1
    e1
    (if p2
        e3))
我们真的不知道p1此刻在哪里。现在看看您的代码:

(defun my-test (&rest values)
  (macrolet ((my-macro (v)
               `(list ,@v)))
    (print values)
    (my-macro values)))
因此,当创建
my test
时,宏将展开。您能告诉我如果不是
(list.values)
,我的宏将如何展开
(我的宏值)
(list.values)
不是有效的公共Lisp,这是错误的根源


您或许应该在不使用宏的情况下执行此操作。只要使用
就可以了。要调用以列表作为参数的函数,可以使用
apply
。要复制不需要的列表,可以使用宏转换代码
复制列表
复制树
,它不知道任何运行时值,只知道文字代码。例如

(cond (p1 e1) (p2 e2) (t e3))
变成

(if p1
    e1
    (if p2
        e3))
我们真的不知道p1此刻在哪里。现在看看您的代码:

(defun my-test (&rest values)
  (macrolet ((my-macro (v)
               `(list ,@v)))
    (print values)
    (my-macro values)))
因此,当创建
my test
时,宏将展开。您能告诉我如果不是
(list.values)
,我的宏将如何展开
(我的宏值)
(list.values)
不是有效的公共Lisp,这是错误的根源


您或许应该在不使用宏的情况下执行此操作。只要使用
就可以了。要调用以列表作为参数的函数,可以使用
apply
。要复制一个不需要的列表,你可以使用
复制列表
复制树

我知道将
列表、@v
更改为
、@v
可以达到很好的效果,但我不明白为什么我不能使用
列表
;在我的真实代码中,我必须在
之前有符号,@v
术语“values”是符号,而不是列表。我怀疑“,@v”单独起作用。如果用“flet”更改宏,则“v”将绑定“值”的计算,一个列表。我知道将
列表、@v
更改为
、@v
可以获得好的结果,但我不明白为什么不能使用
列表
;在我的真实代码中,我必须在
之前有符号,@v
术语“values”是符号,而不是列表。我怀疑“,@v”单独起作用。如果您通过“flet”更改宏,那么“v”将绑定“values”的计算,这是一个列表。我忽略了宏的“not runtime”属性,谢谢您的回答。关于我不应该使用宏的事实,我认为这是因为它是一个XY问题。关于这一点,我将提出一个新的问题。对于感兴趣的人来说:所以应用确实是一个很好的解决方案。再次感谢你。我忽略了宏的“非运行时”属性,谢谢你的回答。关于我不应该使用宏的事实,我认为这是因为它是一个XY问题。关于这一点,我将提出一个新的问题。对于感兴趣的人来说:所以应用确实是一个很好的解决方案。再次感谢你。