Lisp lists are based on cons cells. Variables are similar to pointers to cons cells (or other Lisp objects). Changing a variable will not change other variables. Changing cons cells will be visible in all places where there are references to these cons cells.
A good book is Touretzky, General Lisp: A gentle introduction to symbolic computing .
There is also software that draws list trees and cons elements.
If you pass a list to a function like this:
(modify (list 1 2 3))
Then you have three different ways to use the list:
destructive modification of cons cells
(defun modify (list) (setf (first list) 'foo)) ; This sets the CAR of the first cons cell to 'foo .
separation of structure
(defun modify (list) (cons 'bar (rest list)))
Above returns a list that shares the structure with the one passed in the list: the remaining elements in both lists are the same.
copying
(defun modify (list) (cons 'baz (copy-list (rest list))))
Above, the BAZ function is similar to the BAR, but no list cells are shared as the list is copied.
Needless to say, destructive modification should often be avoided if there is no real reason for this (for example, saving memory when it's worth it).
Notes:
never destructively change literal lists of constants
Dont 'do: (let ((l' (abc))) (setf (first l) 'bar))
Reason: the list may be write protected or may be used in conjunction with other lists (organized by the compiler), etc.
also:
Enter variables
like this
(let ((original (list 'a 'b 'c))) (setf (first original) 'bar))
or how is it
(defun foo (original-list) (setf (first original-list) 'bar))
never SETF a undefined.
Rainer joswig
source share