这个问题在一定程度上重新接种到这个和这个对elisp的。基本上,如何阅读和评估反引号?正在发生什么过程?标准对此有何规定?
这是我期望的,但不会发生:symbol`是读者宏,被翻译成某种(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中,此方法有效。
反引号
在Common Lisp中,反引号表达式的表示形式是未定义的。实现实际上使用不同的表示形式。您在SBCL中看到的是特定于实现的。
评估
您的eval问题与阅读器或反引号表达式完全无关:
? (let ((c 10))
(eval '(list 'a 'b c)))
Error: The variable C is unbound.
在Common LispEVAL
中,使用动态环境和空词法环境来评估表单。在词汇环境之上,c
未绑定到10
。
但是动态绑定是。我们需要声明变量为special
:
? (let ((c 10))
(declare (special c))
(eval '(list 'a 'b c)))
(A B 10)
因此,这也起作用:
? (let ((c 10))
(declare (special c))
(eval (read-from-string "`(a b ,c)")))
(A B 10)
默认情况下,Emacs Lisp具有动态绑定(尽管GNU Emacs现在也支持词汇绑定)。Common Lisp默认情况下具有词法绑定。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句