Книга: Practical Common Lisp



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.[81] 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)
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)))

Оглавление книги

Генерация: 3.646. Запросов К БД/Cache: 2 / 0
Вверх Вниз