If I have something like this,
(setq first (list 'a 'b 'c)) (setq second (list 'x 'y 'z)) ;; I know the let binding makes little sense but ;; I need it in the full version of the function. (defun return-list (list) (let ((value list)) value)) and I evaluate
(setcdr (return-list first) (append (return-list second))) then what object does setcdr actually act on? On calling (return-list first) after the setcdr form I consistently get (a x y z). It seems to me that setcdr traces back first through the let binding and actually changes the value of the variable – indeed first itself evaluates to (a x y z) – but I'm not sure. The node about mutability on the Elisp manual says,
If a program attempts to change objects that should not be changed, the resulting behavior is undefined: the Lisp interpreter might signal an error, or it might crash or behave unpredictably in other ways.
When similar constants occur as parts of a program, the Lisp interpreter might save time or space by reusing existing constants or their components.
I'm not sure there isn't something that shouldn't be changed in my program. What I'd like to know is if I can rely on first always being (a x y z) after evaluating the setcdr form.
first? Typically, you don't want that as it makes programs hard to understand. A good rule of thumb is to limit destructive operations to lists created locally.point-stack--valueand it would require a major revision of my program to change the way it works.setcdrmodifies thecdrof a cons cell. Lists are chains of any number of cons cells, but list values are passed around as the single cons cell which starts the list (or asnil, the empty list). So yourfirstandsecondvalues, and yourlistarg, are each pointers to a cons cell, and your let-boundvaluevariable (and therefore the return value of the function) point to the same cons cell as thelistarg, which is the same cons cell asfirstorsecondrespectively in your subsequent calls to that function. You have two lists, and a bunch of things pointing at them.