Building Lists
..............
It has already been described how you can create lists using the Lisp
reader; this method does have a drawback though: the list created is
effectively static. If you modify the contents of the list and that
list was created when a function was defined the list will remain
modified for all future invocations of that function. This is not
usually a good idea, consider the following function definition,
(defun bogus-function (x)
"Return a list whose first element is nil and whose second element is X."
(let
((result '(nil nil))) ;Static list which is filled in each time
(rplaca (cdr result) x) ; the function is called
result))
This function does in fact do what its documentation claims, but a
problem arises when it is called more than once,
(setq x (bogus-function 'foo))
=> (nil foo)
(setq y (bogus-function 'bar))
=> (nil bar) ;The first result has been destroyed
x
=> (nil bar) ;See!
This example is totally contrived--no one would ever write a
function like the one in the example but it does demonstrate the need
for a dynamic method of creating lists.
- Function: list #!rest elements
This function creates a list out of its arguments, if zero
arguments are given the empty list, `()', is returned.
(list 1 2 3)
=> (1 2 3)
(list (major-version-number) (minor-version-number))
=> (3 2)
(list)
=> ()
- Function: list* arg1 arg2 ... argn-1 argn
Creates a new list `(ARG1 ARG2 ... ARGN-1 . ARGN)'.
(list* 1 2 '(3 4))
=> (1 2 3 4)
- Function: make-list length #!optional initial-value
This function creates a list LENGTH elements long. If the
INITIAL-VALUE argument is given it defines the value of all
elements in the list, if it is not defined they are all `()'.
(make-list 2)
=> (() ())
(make-list 3 t)
=> (t t t)
(make-list 0)
=> ()
- Function: append #!rest lists
This function creates a new list with the elements of each of its
arguments (which must be lists). Unlike the function `nconc' this
function preserves the structure of all its arguments.
(append '(1 2 3) '(4 5))
=> (1 2 3 4 5)
(append)
=> ()
What actually happens is that all arguments but the last are
copied, then the last argument is linked on to the end of the list
(uncopied).
(setq foo '(1 2))
=> (1 2)
(setq bar '(3 4))
=> (3 4)
(setq baz (append foo bar))
=> (1 2 3 4)
(eq (nthcdr 2 baz) bar)
=> t
The following diagram shows the final state of the three variables
more clearly,
foo--> +-----+-----+ +-----+-----+
| o | o----> | o | |
+--|--+-----+ +--|--+-----+
| |
o--> 1 o--> 2 bar
| | ->
baz--> +--|--+-----+ +--|--+-----+ +-----+-----+ +-----+-----+
| o | o----> | o | o----> | o | o----> | o | |
+-----+-----+ +-----+-----+ +--|--+-----+ +--|--+-----+
| |
--> 3 --> 4
Note how `foo' and the first half of `baz' use the _same_ objects
for their elements--copying a list only copies its cons cells, its
elements are reused. Also note how the variable `bar' actually
references the mid-point of `baz' since the last list in an
`append' call is not copied.
- Function: remove elt list
Return a copy of LIST, with all elements the same as ELT discarded
(using the `equal' function to compare).
- Function: remq elt list
Similar to the `remove' function, except that comparisons are made
using `eq'.
- Function: reverse list
This function returns a new list; it is made from the elements of
the list LIST in reverse order. Note that this function does not
alter its argument.
(reverse '(1 2 3 4))
=> (4 3 2 1)
As a postscript to this section, the function used as an example at
the beginning could now be written as,
(defun not-so-bogus-function (x)
(list nil x))
Also note that the `cons' function can be used to create lists by
hand and to add new elements onto the front of a list. For example:
(setq x (list 1 2 3))
=> (1 2 3)
(setq x (cons 0 x))
=> (0 1 2 3)