Generalized Assignment
Variable bindings, of course, aren’t the only places that can hold values. Common Lisp supports composite data structures such as arrays, hash tables, and lists, as well as user-defined data structures, all of which consist of multiple places that can each hold a value.
I’ll cover those data structures in future chapters, but while we’re on the topic of assignment, you should note that **SETF**
can assign any place a value. As I cover the different composite data structures, I’ll point out which functions can serve as “**SETF**
able places.” The short version, however, is if you need to assign a value to a place, **SETF**
is almost certainly the tool to use. It’s even possible to extend **SETF**
to allow it to assign to user-defined places though I won’t cover that.16
In this regard **SETF**
is no different from the =
assignment operator in most C-derived languages. In those languages, the =
operator assigns new values to variables, array elements, and fields of classes. In languages such as Perl and Python that support hash tables as a built-in data type, =
can also set the values of individual hash table entries. Table 6-1 summarizes the various ways =
is used in those languages.
Table 6-1. Assignment with =
in Other Languages
Assigning to … | Java, C, C++ | Perl | Python |
… variable | x = 10; | $x = 10; | x = 10 |
… array element | a[0] = 10; | $a[0] = 10; | a[0] = 10 |
… hash table entry | — | $hash{‘key’} = 10; | hash[‘key’] = 10 |
… field in object | o.field = 10; | $o->{‘field’} = 10; | o.field = 10 |
**SETF**
works the same way—the first “argument” to **SETF**
is a place to store the value, and the second argument provides the value. As with the =
operator in these languages, you use the same form to express the place as you’d normally use to fetch the value.17 Thus, the Lisp equivalents of the assignments in Table 6-1—given that **AREF**
is the array access function, **GETHASH**
does a hash table lookup, and field
might be a function that accesses a slot named field
of a user-defined object—are as follows:
Simple variable: (setf x 10)
Array: (setf (aref a 0) 10)
Hash table: (setf (gethash 'key hash) 10)
Slot named 'field': (setf (field o) 10)
Note that **SETF**
ing a place that’s part of a larger object has the same semantics as **SETF**
ing a variable: the place is modified without any effect on the object that was previously stored in the place. Again, this is similar to how **=**
behaves in Java, Perl, and Python.18