Re: Canonical Way to Mask SETF?
- From: Marco Gidde <marco.gidde@xxxxxxxxxx>
- Date: Thu, 30 Jun 2005 11:45:34 +0200
Kent M Pitman <pitman@xxxxxxxxxxx> writes:
> Actually, this doesn't seem to be working in either LispWorks 4.4.5
> nor in SBCL 0.9.1 (I'm told). The following results are from LW 4.4.5
> after doing the obvious fix from above
> (defun menu-title (x) (getf x :title))
> (defsetf menu-title (x) (title) `(setf (getf ,x :title) ,title))
>
> I get:
>
> (GET-SETF-EXPANSION '(MENU-TITLE X))
> => (#:X585),
> (X),
> (#:VALUE584),
> (SETF (GETF #:X585 :MENU-TITLE) #:VALUE584),
> (MENU-TITLE #:X585)
>
> where I think I'd expect:
>
> (),
> (),
> (#:VALUE584),
> (SETF (GETF X :MENU-TITLE) #:VALUES84),
> (MENU-TITLE X)
>
> And, even stranger, I get:
>
> (get-setf-expansion '(menu-title (cdr x)))
> => (#:X600),
> ((CDR X)),
> (#:VALUE599),
> (SETF (GETF #:X600 :MENU-TITLE) #:VALUE599),
> (MENU-TITLE #:X600)
>
> when I think I'd have expected something like:
>
> => (#:X600),
> (X),
> (#:VALUE599),
> (SETF (GETF (CDR #:X600) :MENU-TITLE) #:VALUE599),
> (MENU-TITLE (CDR #:X600))
>
> My sense from X3J13 issue SETF-SUB-METHODs
> [ see http://www.lispworks.com/documentation/HyperSpec/Issues/iss312.htm
> and http://www.lispworks.com/documentation/HyperSpec/Body/05_abb.htm ]
> is that:
>
> | 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.
>
> By this I assume that the variable X (in the first case) or the location
> (CDR X) in the second case is the "place" that must "always be both read
> and written", and that the list that is taken from that place is the
> "particular list that is the property list in question" which is
> "not necessarily [what is read or written]".
This is true for the setf expansion of getf, but not necessarily for
menu-title. From
http://www.lispworks.com/documentation/HyperSpec/Body/m_defset.htm :
| During the evaluation of the forms, the variables in the lambda-list
| and the store-variables are bound to names of temporary variables,
| generated as if by gensym or gentemp, that will be bound by the
| expansion of setf to the values of those subforms. This binding
| permits the forms to be written without regard for
| order-of-evaluation issues. defsetf arranges for the temporary
| variables to be optimized out of the final result in cases where
| that is possible.
....
| A setf of a call on access-fn also evaluates all of access-fn's
| arguments; it cannot treat any of them specially. This means that
| defsetf cannot be used to describe how to store into a generalized
| reference to a byte, such as (ldb field
| reference). define-setf-expander is used to handle situations that
| do not fit the restrictions imposed by defsetf and gives the user
| additional control.
So I think in
(defsetf menu-title (x) (title) `(setf (getf ,x :title) ,title))
it looks as if we were setting X, but it's "only" a temporary bound to
X's value.
--
Marco Gidde
.
- Follow-Ups:
- Re: Canonical Way to Mask SETF?
- From: Robert Uhl
- Re: Canonical Way to Mask SETF?
- From: Kent M Pitman
- Re: Canonical Way to Mask SETF?
- References:
- Canonical Way to Mask SETF?
- From: Robert Uhl
- Re: Canonical Way to Mask SETF?
- From: Kent M Pitman
- Re: Canonical Way to Mask SETF?
- From: Kent M Pitman
- Canonical Way to Mask SETF?
- Prev by Date: Re: ILC2005: McCarthy denounces Common Lisp, "Lisp", XML, and Rahul
- Next by Date: Re: ILC2005: McCarthy denounces Common Lisp, "Lisp", XML, and Rahul
- Previous by thread: Re: Canonical Way to Mask SETF?
- Next by thread: Re: Canonical Way to Mask SETF?
- Index(es):
Relevant Pages
|