2016-03-05 31 views
3

此問題已重新插入到thisthis for Elisp。基本上,如何閱讀和評估反向報價?什麼過程正在發生?標準是否對此有任何說明?通用Lisp中的反引號:閱讀並評估

以下是我所期望的,但它不會發生:符號`是讀者宏觀和被翻譯成某種(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中這是有效的。

+0

@RainerJoswig是「標準的宏觀人物」和「讀者宏觀」是一回事還是我對他們感到困惑? – mobiuseng

+1

'標準宏字符'表示字符是由標準定義的宏字符。 CLHS詞彙表:宏觀人物n。 Lisp閱讀器在其主要調度循環中遇到的字符引入閱讀器宏。 –

+2

有關技術細節,您還可以查看您的實現如何操作quasiquotes,就像[Faréquasiquotes](https://gitlab.common-lisp.net/frideau/fare-quasiquote)一樣。 – coredump

回答

11

反引號

Backquote是Common Lisp的標準macro character

在通用Lisp中,反引號表達式的表示是不確定的。實現實際上使用不同的表示。您看到的SBCL是特定於實現的。

EVAL

你有eval的問題是完全無關的閱讀器或反引號的表達式:

? (let ((c 10)) 
    (eval '(list 'a 'b c))) 

Error: The variable C is unbound. 

Common Lisp中EVAL使用動態的環境和null lexical environment的形式評價。在詞彙環境以上,其中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默認具有詞法綁定。

+0

我不知道使用null詞法環境的'EVAL'。謝謝! – mobiuseng