B.4 Multiple Value setf

CLIM provides a facility, sometimes referred to as setf*, that allows setf to be used on "places" that name multiple values. For example, output-record-position returns the position of an output record as two values that correspond to the x and y coordinates. In order to change the position of an output record, the programmer would like to invoke (setf output-record-position). Normally however, setf only takes a single value with which to modify the specified place. The setf* facility provides a "multiple value" version of setf that allows an expression that returns multiple values to be used to update the specified place. [annotate]

defgeneric*  name lambda-list &body options [Macro]

Defines a setf* generic function named name. The last argument in lambda-list is intended to be class specialized, just as is the case for normal setf generic functions. options is as for defgeneric. [annotate]

Note: LAMBDA-LIST may also have &KEY values (definitely used), and presumably &OPTIONAL values or an &REST list. It might be better to say that the last REQUIRED argument in LAMBDA-LIST is intended to be class specialized. The same argument applies to DEFMETHOD*, below, as well. [edit]-- Alastair Bridgewater 2011-03-30 22:36Z


defmethod*  name {method-qualifier}* specialized-lambda-list &body body [Macro]

Defines a setf* method for the generic function name. The last argument in specialized-lambda-list is intended to be class specialized, just as is the case for normal setf methods. {method-qualifier}* amd body are as for defgeneric. [annotate]

For example, output-record-position and its setf* method for a class called sample-output-record might be defined as follows: [annotate]

(defgeneric output-record-position (record)
  (declare (values x y)))
(defgeneric* (setf output-record-position) (x y record))

(defmethod output-record-position ((record sample-output-record))
  (with-slots (x y)
    (values x y)))

(defmethod* (setf output-record-position) (nx ny (record sample-output-record))
  (with-slots (x y)
    (setf x nx
          y ny)))

The position of such an output record could then be changed as follows: [annotate]

(setf (output-record-position record) (values nx ny))

(setf (output-record-position record1) (output-record-position record2))