Assignment
Once you’ve created a binding, you can do two things with it: get the current value and set it to a new value. As you saw in Chapter 4, a symbol evaluates to the value of the variable it names, so you can get the current value simply by referring to the variable. To assign a new value to a binding, you use the **SETF**
macro, Common Lisp’s general-purpose assignment operator. The basic form of **SETF**
is as follows:
(setf place value)
Because **SETF**
is a macro, it can examine the form of the place it’s assigning to and expand into appropriate lower-level operations to manipulate that place. When the place is a variable, it expands into a call to the special operator **SETQ**
, which, as a special operator, has access to both lexical and dynamic bindings.15 For instance, to assign the value 10 to the variable x
, you can write this:
(setf x 10)
As I discussed earlier, assigning a new value to a binding has no effect on any other bindings of that variable. And it doesn’t have any effect on the value that was stored in the binding prior to the assignment. Thus, the **SETF**
in this function:
(defun foo (x) (setf x 10))
will have no effect on any value outside of foo
. The binding that was created when foo
was called is set to 10, immediately replacing whatever value was passed as an argument. In particular, a form such as the following:
(let ((y 20))
(foo y)
(print y))
will print 20, not 10, as it’s the value of y
that’s passed to foo
where it’s briefly the value of the variable x
before the **SETF**
gives x
a new value.
**SETF**
can also assign to multiple places in sequence. For instance, instead of the following:
(setf x 1)
(setf y 2)
you can write this:
(setf x 1 y 2)
**SETF**
returns the newly assigned value, so you can also nest calls to **SETF**
as in the following expression, which assigns both x
and y
the same random value:
(setf x (setf y (random 10)))