Modifying Data

So far when I have asked you to type in a list of numbers I have been assuming that you will type the list correctly. If you made an error you had to retype the entire "2D def expression. Since you can use cut–and–paste this is really not too serious. However it would be nice to be able to replace the values in a list after you have typed it in. The "2D setf special form is used for this. Suppose you would like to change the 12 in the list "2D x used in the Section [*] to 11. The expression
(setf (select x 4) 11)
will make this replacement:
> (setf (select x 4) 11)
11
> x
(3 7 5 9 11 3 14 2)

The general form of "2D setf is

(setf form value)
where "2D form is the expression you would use to select a single element or a group of elements from "2D x and "2D value is the value you would like that element to have, or the list of the values for the elements in the group. Thus the expression
(setf (select x (list 0 2)) (list 15 16))
changes the values of elements 0 and 2 to 15 and 16:
> (setf (select x (list 0 2)) (list 15 16))
(15 16)
> x
(15 7 16 9 11 3 14 2)

A note of caution is needed here. Lisp symbols are merely labels for different items. When you assign a name to an item with the "2D def command you are not producing a new item. Thus

(def x (list 1 2 3 4))
(def y x)
means that "2D x and "2D y are two different names for the same thing. As a result, if we change an element of (the item referred to by) "2D x with "2D setf then we are also changing the element of (the item referred to by) "2D y, since both "2D x and "2D y refer to the same item. If you want to make a copy of "2D x and store it in "2D y before you make changes to "2D x then you must do so explicitly using, say, the "2D copy-list function. The expression
(def y (copy-list x))
will make a copy of "2D x and set the value of "2D y to that copy. Now "2D x and "2D y refer to different objects and changes to "2D x will not affect "2D y.