Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

[Info req] Problem using funcall in setf

82 views
Skip to first unread message

Anthony Herana

unread,
Nov 24, 1999, 3:00:00 AM11/24/99
to

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
ahe...@farad.ee.calpoly.edu or ahe...@violin.aix.calpoly.edu
http://www.elee.calpoly.edu/~aherana
------------------------------------------------------------------------------


Erik Naggum

unread,
Nov 24, 1999, 3:00:00 AM11/24/99
to
* Anthony Herana <ahe...@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

Gareth McCaughan

unread,
Nov 24, 1999, 3:00:00 AM11/24/99
to
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 Gareth.M...@pobox.com
sig under construction

Anthony Herana

unread,
Nov 24, 1999, 3:00:00 AM11/24/99
to

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!
0 new messages