From: Anthony Herana
Subject: [Info req] Problem using funcall in setf
Date: 
Message-ID: <Pine.GUL.3.95.991124135026.24331A-100000@joule.ee.calpoly.edu>
Howdy,
     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.  Okay, when I try to run this in Allegro lisp, I
get:

Error: (SETF FUNCALL) does not have a function definition
  [condition type: SIMPLE-ERROR]

This boggles my mind (comments aside about the state of my mind, please
=P).  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?  Thanks for taking the time to read this. 

------------------------------------------------------------------------------
       Anthony Herana - Career Cal Poly Electrical Engineering Student
       ·······@farad.ee.calpoly.edu  or ·······@violin.aix.calpoly.edu
                    http://www.elee.calpoly.edu/~aherana
------------------------------------------------------------------------------

From: Erik Naggum
Subject: Re: [Info req] Problem using funcall in setf
Date: 
Message-ID: <3152473610386435@naggum.no>
* Anthony Herana <·······@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
From: Gareth McCaughan
Subject: Re: [Info req] Problem using funcall in setf
Date: 
Message-ID: <86zow332jd.fsf@g.local>
Anthony Herana wrote:

> Howdy,
>      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.  Okay, when I try to run this in Allegro lisp, I
> get:
> 
> Error: (SETF FUNCALL) does not have a function definition
>   [condition type: SIMPLE-ERROR]
> 
> This boggles my mind (comments aside about the state of my mind, please
> =P).  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?  Thanks for taking the time to read this. 

How do you expect the compiler to work out what to do here.
I mean, suppose that line of code gets run when PART-TYPE
happens to name, or be, a function like (say) #'sqrt ? SETF
is nice, but it can't work miracles.

If PART-TYPE is always (say) the name of a slot in the class,
you could say

    (setf (slot-value user-profile part-type) (list part-instance))

and now the compiler can tell what sort of thing it is
that you're trying to set, and should be much happier.

-- 
Gareth McCaughan  ················@pobox.com
sig under construction
From: Anthony Herana
Subject: Re: [Info req] Problem using funcall in setf
Date: 
Message-ID: <Pine.GUL.3.95.991124185311.24533A-100000@joule.ee.calpoly.edu>
 Thanks to everyone who responded.  Slot-value was exactly what I needed. 
I don't know what I was thinking in choosing funcall.  Chalk this one up
to a combination of inexperience with lisp and lack of sleep.  =)  Thanks
again for sparing me the frustration! 

------------------------------------------------------------------------------
       Anthony Herana - Career Cal Poly Electrical Engineering Student
       ·······@farad.ee.calpoly.edu  or ·······@violin.aix.calpoly.edu
                    http://www.elee.calpoly.edu/~aherana
------------------------------------------------------------------------------