Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

nesting backquote and ` in emacs lisp

Tags:

emacs

elisp

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.

like image 980
Jisang Yoo Avatar asked Jun 30 '13 20:06

Jisang Yoo


People also ask

Is Emacs Lisp the same as Lisp?

By default, Common Lisp is lexically scoped, that is, every variable is lexically scoped except for special variables. By default, Emacs Lisp files are dynamically scoped, that is, every variable is dynamically scoped. The my-test. el is a lexically scoped file because of the first line.

What is Emacs Lisp used for?

Emacs Lisp is a dialect of the Lisp programming language used as a scripting language by Emacs (a text editor family most commonly associated with GNU Emacs and XEmacs). It is used for implementing most of the editing functionality built into Emacs, the remainder being written in C, as is the Lisp interpreter.

Is Emacs Lisp A Common Lisp?

Gnu emacs is written almost entirely in Common Lisp! Unfortunately, this version of Common Lisp is so incomplete that it won't be sufficient for programming in our class. Instead, you can run and use lisp within emacs.

Is Emacs functional Lisp?

Emacs Lisp supports multiple programming styles or paradigms, including functional and object-oriented. Emacs Lisp is not a purely functional programming language since side effects are common. Instead, Emacs Lisp is considered an early functional flavored language.


1 Answers

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))
like image 103
Diego Sevilla Avatar answered Nov 27 '22 10:11

Diego Sevilla