Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

when to quote symbol in Emacs Lisp

Tags:

emacs

lisp

elisp

I've beginning learning programming with Emacs Lisp. I'm so confused by symbol quotation. For example:

(progn
  (setq a '(1 2))
  (prin1 a)
  (add-to-list 'a 3)
  (prin1 a)
  (setcar a 4)
  (prin1 a)
  (push 5 a)
  ""
)

why the "add-to-list" function need a quoted symbol as its first argument, while the "setcar" and "push" function need no argument quotation?

like image 931
lululau Avatar asked Dec 29 '11 16:12

lululau


People also ask

What is quote used for in Lisp?

Because quote is used so often in programs, Lisp provides a convenient read syntax for it. An apostrophe character (' ' ') followed by a Lisp object (in read syntax) expands to a list whose first element is quote , and whose second element is the object. Thus, the read syntax 'x is an abbreviation for (quote x) .

What does a single quote mean in Lisp?

The single-quote character is shorthand way of saying (quote foo) where quote is the form to return just foo without evaluating it.

How do I quote in Emacs?

Type ' C-q " ' and ' C-q ' ' to insert literal ASCII double and single quotation marks.

What does apostrophe in Lisp mean?

An acute accent (also called single quote or apostrophe) followed by an expression form is an abbreviation for (quote form). Thus 'foo means (quote foo) and '(cons 'a 'b) means (quote (cons (quote a) (quote b))).


1 Answers

Here's a diagram that represents the symbol a and its value after (setq a '(1 2)). The boxes are elementary data structures (symbols and conses) and the arrows are pointers (where a piece of data references another). (I'm simplifying a little.)

 symbol                     cons              cons
+-------+----------+       +------+------+   +------+------+
|name:  |variable: |       |car:  |cdr:  |   |car:  |cdr:  |
| a     |    |     |       | 1    |  |   |   | 2    | nil  |
+-------+----|-----+       +------+--|---+   +------+------+
             |             ​↑         |       ↑
             +-------------+         +-------+

The expression '(1 2) builds the two conses on the right, which make up a two-element list. The expression (setq a '(1 2)) creates the symbol a if it doesn't exist, then makes its “variable slot” (the part that contains the value of the symbol) point to the newly created list. setq is a built-in macro, and (setq a '(1 2)) is shorthand for (set 'a '(1 2)). The first argument of set is the symbol to modify and the second argument is the value to set the symbol's variable slot to.

(add-to-list 'a 3) is equivalent to (set 'a (cons 3 a)) here, because 3 is not in the list. This expression does four things:

  1. Create a new cons cell.
  2. Set the new cons cell's car field to 3.
  3. Set the new cons cell's cdr field to the former (and still current) value of a (i.e. copy the contents of a's variable slot).
  4. Set the variable slot of a to the new cons cell.

After that call, the data structures involved look like this:

 symbol                     cons              cons              cons
+-------+----------+       +------+--|---+   +------+------+   +------+------+
|name:  |variable: |       |car:  |cdr:  |   |car:  |cdr:  |   |car:  |cdr:  |
| a     |    |     |       | 3    |  |   |   | 1    |  |   |   | 2    | nil  |
+-------+----|-----+       +------+--|---+   +------+--|---+   +------+------+
             |             ​↑         |       ↑         |       ↑
             +-------------+         +-------+         +-------+

The call to setcar doesn't create any new data structure, and doesn't act on the symbol a but on its value, which is the cons cell whose car currently contains 3. After (setcar a 4), the data structures look like this:

 symbol                     cons              cons              cons
+-------+----------+       +------+--|---+   +------+------+   +------+------+
|name:  |variable: |       |car:  |cdr:  |   |car:  |cdr:  |   |car:  |cdr:  |
| a     |    |     |       | 4    |  |   |   | 1    |  |   |   | 2    | nil  |
+-------+----|-----+       +------+--|---+   +------+--|---+   +------+------+
             |             ​↑         |       ↑         |       ↑
             +-------------+         +-------+         +-------+

push is a macro; here, (push 5 a) is equivalent to (set 'a (cons 5 a)).

setq and push are macros (setq is a “special form”, which as far as we're concerned here means a macro whose definition is built into the interpreter and not provided in Lisp). Macros receive their arguments unevaluated and can choose to expand them or not. set, setcar and add-to-list are functions, which receive their arguments evaluated. Evaluating a symbol returns the contents of its variable slot, e.g. after the initial (setq a '(1 2)) the value of the symbol a is the cons cell whose car contains 1.

If you're still confused, I suggest experimenting with (setq b a) and seeing for yourself which of the expressions modify b when you act on a (the ones that act on the symbol a) and which don't (the ones that act on the value of the symbol a).

like image 164
Gilles 'SO- stop being evil' Avatar answered Oct 19 '22 10:10

Gilles 'SO- stop being evil'