2013-06-30 14 views
8

Es scheint einen Unterschied zwischen kurzer und langer Rückseite zu geben.nest backquote und `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))) 

Ausgang:

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

(a (backquote (b 123))) 

(a (backquote (b 123))) 

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

Warum es anders als zu x verhält? Nicht einmal sicher, welche der beiden Ergebnisse die überraschenden Ergebnisse sein sollen.

+0

das sind eigentlich Backtick –

+0

Ich denke, es ist ein Fehler in 'backquote.el'. Siehe meinen Kommentar unten. –

Antwort

3

Ich bin mir nicht sicher, ob es ein Fehler oder ein Feature ist, hauptsächlich weil ich nicht sicher bin, ob ein elisp Programmierer die backquote Funktion verwenden darf, oder es ist nur eine bequeme Möglichkeit, das zu definieren Funktion. Die korrekte Ausgabe ist der erste (und vierte) Ausgang. Betrachtet man den Code für backquote (in backquote.el) ist klar, dass alle backquote innerhalb eines `oder backquote nicht richtig erweitert wird. Der entsprechende Code hierfür lautet:

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

wo backquote-backquote-symbol definiert ist, bevor sie als ‚\` (quote-Backslash-Graviszeichen). Es gibt verschiedene Möglichkeiten, diesen Fehler zu behandeln, aber die Linie dann könnte:

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

(oder jede andere Variable zur Angabe des Backquote unaliased Symbol).

BEARBEITEN: Wenn man es genauer betrachtet, gibt es einen anderen Ort, an dem man diesen Test hinzufügen muss, aber dazu gehört auch das Melden eines Patches. Ich werde sehen, wie ich es mache. Mit dieser Änderung:

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