6

[Warning : these are noob questions.]

I'm a beginner in Emacs Lisp and I would like to be sure that I understand well what I'm really doing when I set a value to a variable with setq or let.

Here is a piece of code:

(setq x '(1 2 3 4)) ; define x (setq y x) ; define y (setcar y 9) ; modify CAR of y y ; -> (9 2 3 4): y has changed (ok) x ; -> (9 2 3 4): but x has changed too! 
  1. It seems that when you define a symbol and give it the value of another symbol, this basically means that the two symbols become the same object?

    (eq x y) ; -> t 

    (I expected that the instruction (setq y x) would make an "independant copy" of x, as it would be the case if you do y <- x in R language for example. Or, more formally, I thought this instruction would only fill the "value cell" of y by evaluating (symbol-value 'x), but without "binding" those two objects together.)

  2. This is really a matter of pointers, if I understand well. (setq y x)creates a new symbol which is basically bound to the same address as x? (I.e., y points towards x which points towards a given value, and so if you modify y, you will also modify x because both of them point towards the same address "by transitivity"?)

  3. Robert Chassell's book says that "when a Lisp variable is set to a value, it is provided with the address of the list to which the variable refers", but I cannot figure out what this means formally (where is this address stored?). A Lisp symbol is made of 4 components (name, value, function, properties). So, when I do (setq y x), the "value cell" of y is really an address / a pointer towards x?

2
  • 1
    Great question. It is confusing for us noobs. Commented Feb 12, 2020 at 12:23
  • 1
    This is the same behavior as seen in Python (and other dynamic languages). There is an extra step in going from a variable to the value. Variables don't have the address of values, they have the address of a spot in memory that holds the address of the value. So x = y doesn't copy the value, it copies the address of the spot in memory which holds the address of the value. Don't know about EmacsLisp, but Python has a way of duplicating the value so x and y can't refer to seoarate lists. Commented Sep 22, 2020 at 5:14

1 Answer 1

5

setq is doing like expected, the thing here is, that (1 2 3 4) is not a value, so it is not what you think it is.

  • a Place is a location in memory.

  • x and y are Symbols.

  • a Symbol merely points to a place. So x points to (the first cons of) your list.

  • (1 2 3 4) is a List of conses (aka a "chain" of conses).

  • (1 2 3 4) is not a value, but multiple chained values.
  • a list is constructed like this (cons 1 (cons 2 (cons 3 nil))).
  • a cons consists of two pointers (car . cdr) to the places where the values are stored.
  • a cons by itself is stored at a place. (I'm not perfectly sure with that one)

What did you do?:

  • your new y points, after setq to the same place like x, because you said: point to the list referenced by symbol x.
  • You changed the content of your list, which exists only once in memory.

I hope I got that right. :)

Good question, btw.

5
  • 6
    Most of what you say is right, IMO. But (1 2 3 4) is a value. It's a list of 4 elements. Don't confuse Lisp values with their implementation or manipulation. Same thing for a string, for example: "1 2 3 4" is a single (string) value. But you can access any elements of the string. Yes, element access is different in the cases of a string, which is an array/vector, and a list. But they are both Lisp values. Commented Feb 12, 2020 at 15:39
  • 1
    This is really helpful, thanks! So I think it's even worse than I expected: I also misunderstood what is really a list! Because the behavior is different if we execute the three instructions (setq x "a"), (setq y x) and (setq y "b"): this time, x remains unchanged after those three instructions. If I understand well, this is simply because (unlike with those simple character values) lists involve pointers. Commented Feb 12, 2020 at 15:57
  • 1
    Yes, it is confusing. No two ways about it. Did you try with strings? Why are they not "addresses" then?... Is a string a list of chars... I shall get my cape... ;) Commented Feb 12, 2020 at 16:28
  • @Drew what I ment to say: (1 2 3 4) is not a single value, but multiple values. Thats different to arrays. Would you agree with that? Commented Feb 13, 2020 at 9:40
  • 2
    No, it's a single value. The value is a list. A list is implemented as either the atom nil or a cons cell whose cdr is a list. Think string or vector - similar concepts apply: [1 2 3] is a single value, a vector. The vector has 3 elements, which are integer values. Commented Feb 13, 2020 at 17:48

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.