Reputation: 3745
There seems to be some difference between short backquote and long backquote.
(let ((x 123))
(dolist (res (list `(a `(b ,x))
`(a (backquote (b ,x)))
(backquote (a (backquote (b ,x))))
(backquote (a `(b ,x)))))
(print res)))
Output:
(a (\` (b (\, x))))
(a (backquote (b 123)))
(a (backquote (b 123)))
(a (\` (b (\, x))))
Why does it behave differently as to x? Not even sure which two of the four results are supposed to be the surprising results.
Upvotes: 10
Views: 1317
Reputation: 29011
I'm not sure if it is a bug or a feature, mainly because I'm not sure if a elisp programmer is allowed/good practice to use the backquote
function, or it is just a convenient way of defining the function. The correct output is the first (and fourth) output. Looking at the code for backquote
(in backquote.el
) it is clear that any backquote
inside either a ` or backquote
is not properly expanded. The relevant code for this is:
((eq (car s) backquote-backquote-symbol)
(backquote-delay-process s (1+ level)))
where backquote-backquote-symbol
is defined before as '\` (quote-backslash-backtick). There are several ways of treating this error, but the line could be then:
((or (eq (car s) backquote-backquote-symbol)
(eq (car s) 'backquote))
(backquote-delay-process s (1+ level)))
(or using any other variable for specifying the backquote unaliased symbol).
EDIT: Looking at it more closely, there is another place where you have to add that test too, but this includes reporting a patch. I'll see how do I do it. With that change:
ELISP> (macroexpand-all `(a (backquote (b ,x))))
(a
(list 'b x))
ELISP> (macroexpand-all `(a `(b ,x)))
(a
(list 'b x))
Upvotes: 4