I'm trying to write a macro in Common Lisp that defines a class with variant slots I specify. So far it's worked OK (and I've been very impressed with clisp!) for this:
(defmacro notifier (class slot)
"Defines a setf method in (class) for (slot) which calls the object's changed method."
`(defmethod (setf ,slot) (val (item ,class))
(setf (slot-value item ',slot) val)
(changed item ',slot)))
(defmacro notifiers (class slots)
"Defines setf methods in (class) for all of (slots) which call the object's changed method."
`(progn
,@(loop for s in slots collecting `(notifier ,class ,s))))
(defmacro defclass-notifier-slots (class nslots slots)
"Defines a class with (nslots) giving a list of slots created with notifiers, and (slots) giving a list of slots created with regular accessors."
`(progn
(defclass ,class ()
( ,@(loop for s in nslots collecting `(,s :reader ,s))
,@(loop for s in slots collecting `(,s :accessor ,s))))
(notifiers ,class ,nslots)))
The problem is, now I want to create not just the slots I specify in the call to the macro, but some other slots as well with variant names. In order to do that, I'd have to use an ugly "symbol-name, alter string, intern" sequence to generate the variant name as a slot name, and I've already seen answers on SO that say you should avoid doing that. So is there a better way of doing this?
"symbol-name, alter string, intern" sequence
is the standard way. Please reference the posts which deprecate it. – sds May 3 '15 at 15:12defclass
et al do! – sds May 3 '15 at 15:19(defun append-symbol (symbol appstr) (intern (concatenate 'string (symbol-name symbol) appstr)))
,(defmacro build-stat-pane (name statslist) (let ((pane-symbols (loop for (n sname) in statslist collecting (list (append-symbol n "-title") (append-symbol n "-pane") sname)))) `(define-interface ,name () () (:panes ,@(loop for (ti p n) in pane-symbols collecting `(,ti title-pane :text ,n) collecting `(,p display-pane))))))
– Mark Green May 3 '15 at 15:36