Basic Setf Generalized Variables Customizing Setf
This package defines a number of other macros besides
that operate on generalized variables. Many are interesting and
useful even when the place is just a variable name.
setq: When several places and forms are involved, the assignments take place in parallel rather than sequentially. Specifically, all subforms are evaluated from left to right, then all the assignments are done (in an undefined order).
(incf i)is equivalent to
(setq i (1+ i)), and
(incf (car x) 2)is equivalent to
(setcar x (+ (car x) 2)).
Once again, care is taken to preserve the ``apparent'' order of evaluation. For example,
(incf (aref vec (incf i)))
appears to increment
i once, then increment the element of
vec addressed by
i; this is indeed exactly what it
does, which means the above form is not equivalent to the
(setf (aref vec (incf i)) (1+ (aref vec (incf i)))) ; Wrong!
but rather to something more like
(let ((temp (incf i))) (setf (aref vec temp) (1+ (aref vec temp))))
Again, all of this is taken care of automatically by
the other generalized-variable macros.
As a more Emacs-specific example of
incf, the expression
(incf (point) n) is essentially equivalent to
(prog1 (car place) (setf place (cdr place))), except that it takes care to evaluate all subforms only once.
(setf place (cons x place)), except for evaluation of the subforms.
&key :test :test-not :key
eqlto any existing element of the list. The optional keyword arguments are interpreted in the same way as for
adjoin. See Lists as Sets.
(shiftf a b c d)is equivalent to
(prog1 a (psetf a b b c c d))
except that the subforms of a, b, and c are actually evaluated only once each and in the apparent order.
(rotatef a b c d)is equivalent to
(psetf a b b c c d d a)
except for the evaluation of subforms.
nil. Note that
(rotatef a b)
conveniently exchanges a and b.
The following macros were invented for this package; they have no analogues in Common Lisp.
let, but for generalized variables rather than just symbols. Each binding should be of the form
(place value); the original contents of the places are saved, the values are stored in them, and then the body forms are executed. Afterwards, the places are set back to their original saved contents. This cleanup happens even if the forms exit irregularly due to a
throwor an error.
(letf (((point) (point-min)) (a 17)) ...)
moves ``point'' in the current buffer to the beginning of the buffer,
and also binds
a to 17 (as if by a normal
a is just a regular variable). After the body exits,
is set back to its original value and point is moved back to its
(point) is not quite like a
save-excursion, as the latter effectively saves a marker
which tracks insertions and deletions in the buffer. Actually,
(point-marker) is much closer to this
point-marker are equivalent
setf places; each will accept either an integer or a
marker as the stored value.)
Since generalized variables look like lists,
of using `
foo' for `
(foo nil)' as a binding would
be ambiguous in
letf and is not allowed.
However, a binding specifier may be a one-element list
(place)', which is similar to `
(place place)'. In other words, the place is not disturbed
on entry to the body, and the only effect of the
to restore the original value of place afterwards. (The
redundant access-and-store suggested by the
(place place) example does not actually occur.)
In most cases, the place must have a well-defined value on
entry to the
letf form. The only exceptions are plain
variables and calls to
If the symbol is not bound on entry, it is simply made unbound by
fmakunbound on exit.
let: It does the bindings in sequential rather than parallel order.
(incf place n)is the same as
(callf + place n). Some more examples:
(callf abs my-number) (callf concat (buffer-name) "<" (int-to-string n) ">") (callf union happy-people (list joe bob) :test 'same-person)
See Customizing Setf, for
define-modify-macro, a way
to create even more concise notations for modify macros. Note
callf is an extension to standard Common Lisp.
callf, except that place is the second argument of function rather than the first. For example,
(push x place)is equivalent to
(callf2 cons x place).
callf2 macros serve as building
blocks for other macros like
macros are used in the processing of symbol macros;
see Macro Bindings.