2013-06-30 5 views
8

Sembra esserci qualche differenza tra il backquote breve e il backquote lungo.nesting backquote e `in emacs lisp

(let ((x 123)) 
    (dolist (res (list `(a `(b ,x)) 
        `(a (backquote (b ,x))) 
        (backquote (a (backquote (b ,x)))) 
        (backquote (a `(b ,x))))) 
    (print res))) 

uscita:

(a (\` (b (\, x)))) 

(a (backquote (b 123))) 

(a (backquote (b 123))) 

(a (\` (b (\, x)))) 

Perché si comportano in modo diverso da x? Non sono nemmeno sicuro di quali due dei quattro risultati debbano essere i risultati sorprendenti.

+0

quelli sono in realtà backtick –

+0

Penso che sia un bug in 'backquote.el'. Vedi il mio commento qui sotto. –

risposta

3

Non sono sicuro se si tratta di un bug o di una funzionalità, principalmente perché non sono sicuro che un programmatore elisp sia autorizzato/buona pratica per utilizzare la funzione backquote, oppure è solo un modo conveniente di definire il funzione. L'output corretto è il primo (e il quarto) output. Guardando il codice per backquote (in backquote.el) è chiaro che qualsiasi backquote all'interno di un file `o backquote non è stato espanso correttamente. Il codice rilevante per questo è:

((eq (car s) backquote-backquote-symbol) 
     (backquote-delay-process s (1+ level))) 

dove backquote-backquote-symbol è definito prima come '\ `(quote-backslash-backtick). Ci sono diversi modi di trattare questo errore, ma la linea potrebbe essere quindi:

((or (eq (car s) backquote-backquote-symbol) 
     (eq (car s) 'backquote)) 
     (backquote-delay-process s (1+ level))) 

(o con qualsiasi altra variabile per specificare il backquote simbolo unaliased).

EDIT: Guardando più da vicino, c'è un altro posto dove devi aggiungere anche quel test, ma questo include riportare una patch. Vedrò come lo faccio. Con tale modifica:

ELISP> (macroexpand-all `(a (backquote (b ,x)))) 
(a 
(list 'b x)) 
ELISP> (macroexpand-all `(a `(b ,x))) 
(a 
(list 'b x))