Common Lisp:反引号中的反引号符号

Common Lisp:反引号中的反引号符号,lisp,common-lisp,Lisp,Common Lisp,下面的代码给出了预期的结果: (let ((name 'test) (args '("arg1" "arg2"))) `(defun ,name ,@args)) ;; (DEFUN TEST "arg1" "arg2") 如果args是符号列表,为什么会出现QUOTE (let ((name 'test) (args '('arg1 'arg2))) `(defun ,name ,@args)) ;; (DEFUN TEST (QUOTE AR

下面的代码给出了预期的结果:

(let ((name 'test)
      (args '("arg1" "arg2")))
     `(defun ,name ,@args))

;; (DEFUN TEST "arg1" "arg2")
如果
args
是符号列表,为什么会出现
QUOTE

(let ((name 'test)
      (args '('arg1 'arg2)))
     `(defun ,name ,@args))

;; (DEFUN TEST (QUOTE ARG1) 'ARG2)

读取器将
'symbol
展开为
(引用符号)
。那么你的情况呢

'('arg1 'arg2)
相当于

(quote ((quote arg1) (quote arg2)))
其计算结果如下所示:

((quote arg1) (quote arg2))
从反引号开始计算表单会导致将列表元素(
(引号arg1)
(引号arg2)
)与前面的字符串在结果列表中的相同位置进行拼接


我不知道为什么您的实现会打印扩展的第一个拼接元素,而不是第二个。但是,如上所述,两种形式在读取时是等效的。

('arg1'arg2)
不是符号列表,而是列表列表。第一个列表是
(quote arg1)
,第二个列表是
(quote arg2)
。我认为标准打印机将数据
(quote x)
打印为
'x
。漂亮的打印机将尝试以最可读的方式打印以
defun
开头的列表。规范形式是(
defun
),因此它将为两个参数
quote
arg1
打印
(quote arg1)
,并且在主体中;使用更短、可能更人性化的arg2。