这个问题与这个和这个Elisp问题有些相关。基本上,反引号是如何被读取和评估的?会发生什么样的进程?标准是否有任何说明?
这是我所期望的,但并不会发生:符号`是一个读取宏,被转换成某种
正在发生什么(SBCL):
如果没有逗号符号,评估读取表达式就可以了。
这意味着
PS. 有趣的是,在 Elisp 中这个方法可以运行。
这是我所期望的,但并不会发生:符号`是一个读取宏,被转换成某种
(BACKQUOTE ...)
宏/特殊形式(类似于'
被转换为(QUOTE ...)
)。这并没有发生,事实上,Common Lisp甚至没有BACKQUOTE
宏。正在发生什么(SBCL):
CL-USER> (defparameter *q* (read-from-string "`(a b ,c)"))
*Q*
CL-USER> *q*
`(A B ,C)
CL-USER> (car *q*)
SB-INT:QUASIQUOTE
CL-USER> (cdr *q*)
((A B ,C))
虽然与预期不同,但没关系。现在,C
本身是一个有趣的动物:
CL-USER> (type-of (third (cadr *q*)))
SB-IMPL::COMMA
如果没有逗号符号,评估读取表达式就可以了。
CL-USER> (eval (read-from-string "`(a b c)"))
(A B C)
但是,如果我想要使用本地绑定来评估原始表达式,即使对于 C
,也存在问题:
(let ((c 10)) (eval (read-from-string "`(a b ,c)")))
; in: LET ((C 10))
; (LET ((C 10))
; (EVAL (READ-FROM-STRING "`(a b ,c)")))
;
; caught STYLE-WARNING:
; The variable C is defined but never used.
;
; compilation unit finished
; caught 1 STYLE-WARNING condition
; Evaluation aborted on #<UNBOUND-VARIABLE C {1007A3B2F3}>.
这意味着
EVAL
没有捕获到绑定了 C
的环境。PS. 有趣的是,在 Elisp 中这个方法可以运行。