I have a list which contains some symbols and values. The goal is to setf the class slot with the accessor, whose symbol is provided by the list :
(defclass my-class ()
((attr :accessor attr)))
(let ((to-call '(attr "some-value"))
(obj (make-instance 'my-class)))
(setf `(,(car to-call) obj) (cadr to-call)))
I have tried via a macro :
(defmacro call-accessor (to-call)
`(setf (,(car to-call) obj) "some-value"))
(let ((to-call '(attr "some-value"))
(obj (make-instance 'my-class)))
(call-accessor to-call))
Which fails too, since to-call is a symbol and not a list.
evaldoes not work sinceto-callis a lexical variable;- It is not possible to do a
letover the macro to give it the list; - I have tried with
with-slotsandwith-accessorsbut the problem remains the same, because they are macros too. - I have considered macros which declares other macro, and symbol-macrolet too.
How can I setf a slot via an accessor corresponding to a symbol in my list ?
Thank you.
Calling the accessor function
An accessor is a pair of functions. You can get the part which sets the value via
FDEFINITION. The name of the function is a list(SETF accessor-name ). This is unusual: Common Lisp has in this case function names which are not symbols, but lists.Using a function
call-accessor:using SETF with APPLY to hide the FDEFINITION call
To use
setfwith a computed accessor, one might need to use anapplyform and a custom function.Something like
call-accessorwould naturally be a function, because it does runtime lookup and takes values. Trying to use a macro would be more useful if the accessor would be known at compile time.Choice of data structure
I think it's okay to compute accessor functions and similar. There may be use cases for that. CLOS was designed to be dynamic and reflective to allow these things.