Subject: Re: [Info req] Problem using funcall in setf From: Erik Naggum <erik@naggum.no> Date: 1999/11/24 Newsgroups: comp.lang.lisp Message-ID: <3152473610386435@naggum.no> * Anthony Herana <aherana@farad.ee.calpoly.edu> | I have this line of code: | | (setf (funcall part-type user-profile) (list part-instance)) | | where part-type contains a symbol that I want to now use as an accessor of | a pre-defined class, user-profile is the class instance, and part-instance | is an object I want to put into a list and assign that list to the data | member in user-profile. I'm not sure I follow you. are you trying to write into different slots of the instance of a known class through variable accessors? may I recommend that you use these forms instead: (slot-value <instance> <slot-name>) (setf (slot-value <instance> <slot-name>) <new-value>) and not go through the accessor? if you already considered and discarded this, I'd like to hear your reason. | The expression with the funcall works when I run it separately, as does | the list expression. It's only when I put them into the setf expression | that lisp barks at me. Could someone please enlighten me as to what I am | doing incorrectly? SETF is a macro, so it needs to resolve the argument at compile-time, whereas what you observe to work happens solely at run-time. so to make this work, you need to figure out what SETF would have produced in the constant case. assuming you have built the accessor with an :ACCESSOR slot option, it is actually a list of the form (SETF x), where x is the name of the reader. (this is called a "function name".) that is, if (foo-slot-accessor foo-instance) is the access form, then (setf (foo-slot-accessor foo-instance) new-value) will expand into (funcall (function (setf foo-slot-accessof)) new-value foo-instance). ordinarily, you would have to use (FUNCTION (SETF x)) to get at this function, but this is a quoted constant, so you lose with a variable x. however, the accessor FDEFINITION will accept a function name constructed at run-time. (fdefinition (list 'setf <getter>)) will return the setter function. so you could write (funcall (fdefinition (list 'setf part-type)) (list part-instance) user-profile) and lose in both categories "elegance" and "performance", because this is not only ugly, it's defeating optimization opportunities left and right. so you would probably end up using SLOT-VALUE directly to save yourself. what's wrong with accessors if this is what you have to do? nothing, of course, but they are intended for human-readable code where the name of the accessor is communicating some form of intent. inside a function that just reads and sets slots, such concerns have very limited value when they detract from a working solution. [ I have used (function X) instead of the abbreviated form #'X to avoid any possible confusion. FUNCTION is a quoting form like QUOTE, and as 'x is identical to (quote x), #'x is identical to (function x). ] #:Erik, who enjoyed figuring this one out and hope this helps