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