Path: utzoo!utgpu!jarvis.csri.toronto.edu!cs.utexas.edu!uunet!mcsun!ukc!edcastle!aiai!jeff From: jeff@aiai.ed.ac.uk (Jeff Dalton) Newsgroups: comp.lang.lisp Subject: Re: updating random slots in (say) defstruct Message-ID: <1571@skye.ed.ac.uk> Date: 17 Jan 90 18:05:58 GMT References: <18837@bellcore.bellcore.com> <25B37814.3312@marob.masa.com> Reply-To: jeff@aiai.UUCP (Jeff Dalton) Organization: AIAI, University of Edinburgh, Scotland Lines: 54 In article <25B37814.3312@marob.masa.com> cowan@marob.masa.com (John Cowan) writes: >In article <18837@bellcore.bellcore.com> pc@flash.bellcore.com writes: >>Must i explicitly define my structure as say a list, to be able to >>replace an arbitrary component? >This is handled on page 96 of CLtL (1st ed.), which discusses setf. >That is section 7.2, (setf), seventh bullet, in case paginations differ. >It is legal to say (setf (apply #'fn args) newval). >In this case, one could say something like: > (setf instance (make-fubar :one 'a :two 'b :three 'c)) > (setf accessor #'fubar-one) ; note use of #' here > (setf (apply accessor (list instance)) newvalue) >to change the :one slot of instance to newvalue. What CLtL says is that SETF will work for a call to APPLY provided that (1) APPLY's first argument has the form #'function-name and (2) calls to function-name are recognized as places by SETF. That is, to be able to do (setf (apply #'f ...apply-args...) y) you have to be able to do (setf (f ...args...) y) In your example above, ACCESSOR would not be recognized as a place by SETF, nor do you write #'ACCESSOR. So (setf (apply accessor ...) ...) probably won't work. On the other hand, (setf (apply #'fubar-one ...) ...) looks like it ought to work. Unfortunately it doesn't in any of the Common Lisps I've tried. >The book warns that this works only if the setf method for the function >is of a normal kind, i.e. produces an update function that resembles the >access function except for having a final argument added which is the new >value. That's probably it. Presumably nothing says the SETF methods for structure slot accessors have the required property. Too bad if so. >So the solution is somewhat implementation dependent, but should work >on any "reasonable" implementation. (I have not tested it past one >implementation.) Does (SETF (APPLY ACCESSOR ...) ...) really work somewhere? -- Jeff