使用 ,@ 时的附加符号 LIST

Additional symbol LIST when using ,@

我观察到一个我不完全理解的宏展开:

(defmacro test (cons-list)
  `(list
     ,@(mapcar #'(lambda(elem)
                   elem)
           cons-list)))


(defmacro test-2 ()
  `(list ,@(list (cons "a" "b"))))


(defmacro test-3 (cons-list)
  `(list ,@cons-list))

我希望这两个宏以相同的方式扩展,因为我只是以一种奇特的方式使用 mapcar 再次创建相同的列表,然后使用该列表。 但是在SBCL观察到的结果是:

为什么这些宏扩展的行为不一样?

Test-2 计算形式 (list (cons "a" "b")),其他两个不计算。

记住:宏的参数是读取的未计算的形式。

为了从 test-2 获得相同的行为,您必须引用以下形式:,@'(list (cons "a" "b")).

编辑: 这是 test 的逐步扩展:

`(list
  ,@(mapcar #'(lambda (elem)
                elem)
            cons-list))

删除反引号语法糖:

(list* 'list (mapcar #'(lambda (elem)
                         elem)
                     cons-list)

您的示例中的参数替换:

(list* 'list (mapcar #'(lambda (elem)
                         elem)
                     '(list (cons "a" "b")))

评估 mapcar 形式:

(list* 'list '(list (cons "a" "b")))

评估“列表*”形式:

'(list list (cons "a" "b"))