Common LISP Hints: Setf

## 16. Setf

Certain forms in LISP naturally define a memory location. For example, if the value of `x` is a structure of type `foo`, then `(foo-bar x)` defines the `bar` field of the value of `x`. Or, if the value of `y` is a one-dimensional array, `(aref y 2)` defines the third element of `y`.

The `setf` special form uses its first argument to define a place in memory, evaluates its second argument, and stores the resulting value in the resulting memory location. For example,

> `

>     > (setq a (make-array 3))
>     #(NIL NIL NIL)
>     > (aref a 1)
>     NIL
>     > (setf (aref a 1) 3)
>     3
>     > a
>     #(NIL 3 NIL)
>     > (aref a 1)
>     3
>     > (defstruct foo bar)
>     FOO
>     > (setq a (make-foo))
>     #s(FOO :BAR NIL)
>     > (foo-bar a)
>     NIL
>     > (setf (foo-bar a) 3)
>     3
>     > a
>     #s(FOO :BAR 3)
>     > (foo-bar a)
>     3

> `

`Setf` is the only way to set the fields of a structure or the elements of an array.

Here are some more examples of `setf` and related functions.

> `

>     > (setf a (make-array 1))       ;setf on a variable is equivalent to setq
>     #(NIL)
>     > (push 5 (aref a 1))           ;push can act like setf
>     (5)
>     > (pop (aref a 1))              ;so can pop
>     5
>     > (setf (aref a 1) 5)
>     5
>     > (incf (aref a 1))             ;incf reads from a place, increments,
>     6                               ;and writes back
>     > (aref a 1)
>     6

> `