This is a read-only archive of lispforum.com. The forum was locked to new users and posts and is preserved here as static HTML from a database snapshot taken on 2019-09-07.

Turning variables into function names with setf

3 posts · 894 views

I seem to be having conceptual difficulty turning a variable into a function. A simple example is looping through the accessors in a class-instance.
(defclass tst ()
((id :accessor id :initarg :id :initform 0)
(name :accessor name :initarg :name :initform "test-me")))

Then if I have a list of data, I'd like to be able to just loop through the list of accessors. But if I try something like (assume a function get-data exists:
(defun test-commit (item)
(loop for fn in '(id name)
do (setf (funcall fn item) (get-data fn))))

I get a message that (setf funcall) is an undefined function and reserved by ANSI CL

Suggestions or pointers would be appreciated.

Sabra

Re: Turning variables into function names with setf

With class accessors a reader and writer are separate functions. To call the writer you need to use its name. In Common Lisp function names can be either symbols or lists of two symbols, the first of which is SETF.

What you are trying to do in your sample (note: use code tags to maintain formatting) is call a (SETF FUNCALL) function which will not work. What you want to do is call a (SETF ID) and so functions, which you can obtain with FDEFINITION and then call:
(defun test-commit (item)
  (loop for fn in '(id name)
        do (funcall (fdefinition `(setf ,fn)) 'test-data item)))
Easier way, if you don't need accessor instrumentation: use SLOT-VALUE.

Do note that if you want to treat instance slots this way, then what you actually want might be an array or a hash-table.

Re: Turning variables into function names with setf

Thank you. For most things I would use an array or hash table, but was exploring using a dao-object in postmodern and was looking for a good way for changing an object instance from a list of new data generated elsewhere in the program.