Re: Canonical Way to Mask SETF?
- From: Kent M Pitman <pitman@xxxxxxxxxxx>
- Date: Thu, 30 Jun 2005 07:27:46 GMT
peder@xxxxxxxxxxxxxxxxxxx (Peder O. Klingenberg) writes:
> I've never been able to grok defsetf. But I find that for my uses,
> (defun (setf ...) ...) has always done the trick.
The reason this works for you is not that you're using (defun (setf...) ...)
but that the argument you are passing contains an adequate pointer to reliably
update the object. That is, if you pass a hash table, you can update the
hash table reliably. But if you pass a list, you cannot reliably update the
list since, worst case, the list might be NIL and there is no way to grow NIL
to contain elements by side-effect--NIL cannot be side-effected.
Robert's problem is that he's trying to side-effect the object, which I claim
_should_ work if defsetf were doing what I think it should do, recursively
interpreting a place within a place subform so that it gets updated right.
(I might be wrong and I'm waiting for others to chime in with opinions.)
But in any case, the workaround is instead of passing a list to either pass
the result of (CONS something data-you-care-about) so that you can GETF its
cdr, and then you have something to update when the cdr is NIL, or else to
pass a hashtable (which updates something internal pointed to by the hashtable,
not the hashtable itself, or to pass something else like a struct with
(DEFSTRUCT MENU
(PLIST '()))
so that you can do
(defun menu-title (menu) (getf (menu-plist menu) :title))
(defsetf menu-title (menu) (title)
`(setf (getf (menu-plist ,menu) :title) ,title))
This will work if you do
(defun (setf menu-title) (title menu)
(setf (getf (menu-plist menu) :title) title))
also, but what won't work is
(defun menu-title (menu) (getf menu :title))
(defun (setf menu-title) (title menu) (setf (getf menu :title) title))
because there if you do (setq x nil) (setf (menu-title x) "foo")
you're just going to do (funcall #'(setf menu-title) NIL "foo") and that
is just never powerful enough to update X from within (setf menu-title),
since it gets no pointer to X, it only gets a pointer to NIL (X's content).
.
- Follow-Ups:
- Re: Canonical Way to Mask SETF?
- From: Peder O. Klingenberg
- Re: Canonical Way to Mask SETF?
- References:
- Canonical Way to Mask SETF?
- From: Robert Uhl
- Re: Canonical Way to Mask SETF?
- From: Peder O. Klingenberg
- Canonical Way to Mask SETF?
- Prev by Date: Re: Canonical Way to Mask SETF?
- Next by Date: Re: Canonical Way to Mask SETF?
- Previous by thread: Re: Canonical Way to Mask SETF?
- Next by thread: Re: Canonical Way to Mask SETF?
- Index(es):
Relevant Pages
|