I have a simple structure like this:
(defstruct node
(name nil)
(yes nil)
(no nil))
And I want to write a to update a node instance:
(defun update (node-instance accessor)
(setf (funcall accessor node-instance) 'XYZ))
so i can (update #'node-yes a-node) or (update #'node-name a-node)
I get the following error:
Couldn't find a setf expansion for (FUNCALL ACCESSOR CONCEPT).
How can I fix this? O:-)
TIA
-----------------------
Fernando Rodriguez
In article <·······················@news3.calgary.shaw.ca>,
Coby Beck <·····@mercury.bc.ca> wrote:
>
>"Fernando Rodr�guez" <····@wanadoo.es> wrote in message
>·······································@4ax.com...
>>
>> I have a simple structure like this:
>> (defstruct node
>> (name nil)
>> (yes nil)
>> (no nil))
>>
>> And I want to write a to update a node instance:
>>
>> (defun update (node-instance accessor)
>> (setf (funcall accessor node-instance) 'XYZ))
>>
>
>Does this fit the bill?
>
>CL-USER 17 > (setf foo (make-node))
>#S(NODE NAME NIL YES NIL NO NIL)
>
>CL-USER 18 > (defun update-node (node slot value)
> (setf (slot-value node slot) value))
>UPDATE-NODE
There's no requirement that SLOT-VALUE work for DEFSTRUCT slots. It's only
defined for CLOS slots. You're making use of an implementation-specific
extension.
Of course, it should be simple for the OP to change from using DEFSTRUCT to
DEFCLASS, and then he could do what he wants.
To the OP: the Lisp FAQ addresses this issue in some detail. I know,
because this is one of the questions that prompted me to write the FAQ
about a decade ago.
--
Barry Margolin, ······@genuity.net
Genuity, Woburn, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.
Fernando Rodr�guez <····@wanadoo.es> writes:
> I have a simple structure like this:
> (defstruct node
> (name nil)
> (yes nil)
> (no nil))
>
> And I want to write a to update a node instance:
>
> (defun update (node-instance accessor)
> (setf (funcall accessor node-instance) 'XYZ))
> How can I fix this? O:-)
(defmacro update (node-instance accessor value)
`(setf (,accessor ,node-instance) ,value))
might help. Lookup defsetf, define-modify-macro ... in CLHS.
--
"Das Auto hat keine Zukunft. Ich setze aufs Pferd." Wilhelm II. (1859-1941)
"Wolfhard Bu�" <·····@gmx.net> wrote in message
···················@buss-14250.user.cis.dfn.de...
> Fernando Rodr�guez <····@wanadoo.es> writes:
>
> > I have a simple structure like this:
> > (defstruct node
> > (name nil)
> > (yes nil)
> > (no nil))
> >
> > And I want to write a to update a node instance:
> >
> > (defun update (node-instance accessor)
> > (setf (funcall accessor node-instance) 'XYZ))
>
> > How can I fix this? O:-)
>
>
> (defmacro update (node-instance accessor value)
> `(setf (,accessor ,node-instance) ,value))
>
That only works if accessor is known at macroexpansion time, ie is not a
variable name but one of NAME, YES or NO.
--
Coby Beck
(remove #\Space "coby 101 @ bigpond . com")
From: Kenny Tilton
Subject: Re: Trouble with setf and slot accessor function
Date:
Message-ID: <3CA39E40.346D9ED8@nyc.rr.com>
>
> Fernando Rodr�guez <····@wanadoo.es> writes:
>
> > I have a simple structure like this:
> > (defstruct node
> > (name nil)
> > (yes nil)
> > (no nil))
> >
> > And I want to write a to update a node instance:
> >
> > (defun update (node-instance accessor)
> > (setf (funcall accessor node-instance) 'XYZ))
>
> > How can I fix this? O:-)
>
Just curious: what is wrong with:
(setf (node-name <node>) <value)
? BTW, even getting this to work:
(update <node> <slot-name> <value>) ;; I cannot believe you mean to
hard-code the new value
...would be against the grain of Lisp, you would want the syntax to be:
(update (<slot-name> <node>) <value>)
...but in Lisp update is called setf, so we're back to:
(setf (<accessor> <node>) <value>)
Now I /do/ have code that says:
(defun set-obsolete (node) (setf (node-status node) :obsolete))
...so I can change that if necessary to:
(defun set-obsolete (node) (setf (obsolete-p node) t))
...and then I get all Lisp-y and create:
(defun (setf obsolete-p node) (setf (valid node) nil)) ;; just to
show implementation is hidden
(defun obsolete-p (node) (null (valid node)))
Sorry for rambling on, but your query left a lot of questions so I was
not sure where you were going with this.
--
kenny tilton
clinisys, inc
---------------------------------------------------------------
"Don't you just hate it when you run out of ice?"
Arthur (RIP)
From: Kenny Tilton
Subject: Re: Trouble with setf and slot accessor function
Date:
Message-ID: <3CA40887.84A9B972@nyc.rr.com>
Kenny Tilton wrote:
> ...and then I get all Lisp-y and create:
>
> (defun (setf obsolete-p node) (setf (valid node) nil)) ;; just to
> show implementation is hidden
oops. should be:
(defun (setf obsolete-p) (new-state node)
; but then this is a dumb example...
kenny tilton
clinisys, inc
---------------------------------------------------------------
"Don't you just hate it when you run out of ice?"
Arthur (RIP)
On Thu, 28 Mar 2002 22:47:02 GMT, Kenny Tilton <·······@nyc.rr.com> wrote:
>>
>> Fernando Rodr�guez <····@wanadoo.es> writes:
>>
>> > I have a simple structure like this:
>> > (defstruct node
>> > (name nil)
>> > (yes nil)
>> > (no nil))
>> >
>> > And I want to write a to update a node instance:
>> >
>> > (defun update (node-instance accessor)
>> > (setf (funcall accessor node-instance) 'XYZ))
>>
>> > How can I fix this? O:-)
>>
>
>Just curious: what is wrong with:
>
> (setf (node-name <node>) <value)
>Sorry for rambling on, but your query left a lot of questions so I was
>not sure where you were going with this.
The examle I gave was over-simplified and probably not a very good one. The
real 'update' function only modifies certain slots if a given number of
conditions are satisfied. Of course I could hard-code all the setfs in the
function that calls 'update', but it would be a bit ugly.
-----------------------
Fernando Rodriguez
Fernando Rodr�guez <····@wanadoo.es> writes:
> I have a simple structure like this:
> (defstruct node
> (name nil)
> (yes nil)
> (no nil))
>
> And I want to write a to update a node instance:
>
> (defun update (node-instance accessor)
> (setf (funcall accessor node-instance) 'XYZ))
>
> so i can (update #'node-yes a-node) or (update #'node-name a-node)
[You flipped your argument order here.]
I don't think that DEFSTRUCT is defined to guarantee you the use of
funcallable methods for the access, so as a consequence, the following
may or may not work, depending on the implementation:
(defun update (node-instance accessor new-value)
(funcall (fdefinition `(setf ,accessor)) new-value node-instance))
(update a-node 'node-yes 'xyz)
You must use the symbol, not the function, in order for the funcall
of (SETF NODE-YES) to work.
If you changed this to be a DEFCLASS instead of a DEFSTRUCT, you would
get this ability. But then, if you'd used DEFCLASS, you could also
just use SETF of SYMBOL-VALUE on the individual slot names, which is
even better...
> I get the following error:
> Couldn't find a setf expansion for (FUNCALL ACCESSOR CONCEPT).
>
> How can I fix this? O:-)
If you want to just use ANSI CL and you need DEFSTRUCT and you want
not rely on details of the MOP, the traditional way is something like:
(defmacro my-defstruct (struct-name &rest slot-specs)
(let* ((slot-names (mapcar #'car slot-specs))
(accessor-names (mapcar #'(lambda (name)
(concatenate 'string
(symbol-name struct-name)
"-"
(symbol-name slot-name)))
slot-names)))
`(progn
(defstruct ,struct-name ,@slot-specs)
,@(mapcan #'(lambda (slot-name accessor-name)
(list
(defmethod struct-slot ((struct ,struct-name)
(key (eql ',slot-name)))
(,accessor-name struct))
(defmethod (setf struct-slot)
(value
(struct ,struct-name)
(key (eql ',slot-name)))
(setf (,accessor-name struct) value))))
slot-names
accessor-names)
',struct-name)))
[I didn't test this.]