Re: Canonical Way to Mask SETF?
- From: Kent M Pitman <pitman@xxxxxxxxxxx>
- Date: Thu, 30 Jun 2005 04:50:32 GMT
Kent M Pitman <pitman@xxxxxxxxxxx> writes:
> Robert Uhl <eadmund42@xxxxxxxxxxxxxxx> writes:
>
> > I'm playing with a menu system, and would like to be able to write the
> > following:
> >
> > (menu-item menu) -> item
> > (setf (menu-item menu) item)
> >
> > I figured that something like this would do the trick:
> >
> > (defun menu-item (menu)
> > (getf menu :title))
> >
> > (defsetf menu-title (menu) (title)
> > `(setf (getf ,menu :title) ,title))
> >
> > But of course it doesn't work. Any advice on how this needs to be
> > written?
>
> Maybe you want to call the defun menu-TITLE, not menu-ITEM?
> Or you want to call the setf function menu-ITEM, not menu-TITLE?
[following up after private discussion between robert and me.]
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]".
Does anyone else read this the same as me and agree that poor Robert is
just experiencing an implementation bug (perhaps a widespread one), or does
someone want to make the case to me that I'm reading the spec wrong.
(Note: As usual, I claim no special standing in interpreting the spec.)
.
- Follow-Ups:
- Re: Canonical Way to Mask SETF?
- From: Marco Gidde
- 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
- Canonical Way to Mask SETF?
- Prev by Date: Re: Implementing custom containers in Lisp
- Next by Date: Re: Implementing custom containers in Lisp
- Previous by thread: Re: Canonical Way to Mask SETF?
- Next by thread: Re: Canonical Way to Mask SETF?
- Index(es):