Common lisp 使用时的附加符号列表@
我观察到一个我不完全理解的宏观扩展:Common lisp 使用时的附加符号列表@,common-lisp,metaprogramming,sbcl,Common Lisp,Metaprogramming,Sbcl,我观察到一个我不完全理解的宏观扩展: (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)) 我希望
(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中观察到的结果是:
扩展到(测试(列表(cons“a”和“b”))
(列表(cons“a”和“b”)
扩展到(test-2)
(列表(“a”“b”))
再次扩展到(test-3(列表(cons“a”“b”))
(列表(cons“a”“b”)
为什么这些宏扩展的行为不一样?
Test-2
评估表单(列表(cons“a”和“b”)
,其他两个没有
记住:宏的参数是读取的、未计算的形式
为了从test-2
中获得相同的行为,您必须引用以下表格:,@'(列表(cons“a”“b”)
编辑:这里是测试的逐步扩展:
`(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"))
有道理,但是为什么要增加列表呢?你看到的只是你放进去的东西。不完全是。我希望@会扩展包含cons的列表。因此,在宏Expension的末尾再次出现一个包含cons的列表,您不明白答案。实际上,您正在为宏提供额外的列表
,这是您不希望看到的。尝试使用(测试(“a”“b”)
和(测试-3(“a”“b”))
。请再次记住,宏参数不是经过计算的,它们是您提供的形式。