A function form can be used as a place if it falls into one of the following categories:
aref cdadr get bit cdar gethash caaaar cddaar logical-pathname-translations caaadr cddadr macro-function caaar cddar ninth caadar cdddar nth caaddr cddddr readtable-case caadr cdddr rest caar cddr row-major-aref cadaar cdr sbit cadadr char schar cadar class-name second caddar compiler-macro-function seventh cadddr documentation sixth caddr eighth slot-value cadr elt subseq car fdefinition svref cdaaar fifth symbol-function cdaadr fill-pointer symbol-plist cdaar find-class symbol-value cdadar first tenth cdaddr fourth third
Figure 5-7. Functions that setf can be used with---1
In the case of subseq, the replacement value must be a sequence whose elements might be contained by the sequence argument to subseq, but does not have to be a sequence of the same type as the sequence of which the subsequence is specified. If the length of the replacement value does not equal the length of the subsequence to be replaced, then the shorter length determines the number of elements to be stored, as for replace.
Function name Argument that is a place Update function used ldb second dpb mask-field second deposit-field getf first implementation-dependent
Figure 5-8. Functions that setf can be used with---2 During the setf expansion of these forms, it is necessary to call get-setf-expansion in order to figure out how the inner, nested generalized variable must be treated.
The information from get-setf-expansion is used as follows.
(setf (ldb byte-spec place-form) value-form)
the place referred to by the place-form must always be both read and written; note that the update is to the generalized variable specified by place-form, not to any object of type integer.
Thus this setf should generate code to do the following:
(setq integer #x69) => #x69 (rotatef (ldb (byte 4 4) integer) (ldb (byte 4 0) integer)) integer => #x96 ;;; This example is trying to swap two independent bit fields ;;; in an integer. Note that the generalized variable of ;;; interest here is just the (possibly local) program variable ;;; integer.
(setf (getf place-form ind-form) value-form)
the place referred to by place-form must always be both read and written; note that the update is to the generalized variable specified by place-form, not necessarily to the particular list that is the property list in question.
Thus this setf should generate code to do the following:
For example:
(setq s (setq r (list (list 'a 1 'b 2 'c 3)))) => ((a 1 b 2 c 3)) (setf (getf (car r) 'b) (progn (setq r nil) 6)) => 6 r => NIL s => ((A 1 B 6 C 3)) ;;; Note that the (setq r nil) does not affect the actions of ;;; the SETF because the value of R had already been saved in ;;; a temporary variable as part of the step 1. Only the CAR ;;; of this value will be retrieved, and subsequently modified ;;; after the value computation.