3 ms·
> I was boggled by all the repetitions: why do we have foo and :foo, and so on. For what it's worth, here is my "defclass-easy" macro which will create a clas
by flavio81 9y ago
> I was boggled by all the repetitions: why do we have foo and :foo, and so on.
For what it's worth, here is my "defclass-easy" macro which will create a class with the slots you want, it also has a "required-slots" list as a parameter. Slots that are in both "slot-list" and "required-slots" will have an ":initarg" of the same name as the slot, and will raise an error if not supplied when making an object.
Enjoy!
(defmacro defclass-easy (class-name slot-list required-slots)
;;required-slots should be a list as well
`(defclass ,class-name ()
,(mapcar (lambda (x)
(if (null(member x required-slots))
(list x)
(list x :initarg
(read-from-string (concatenate 'string ":" (string x))) ;creates :initarg :<slot name>
:initform `(error ,(concatenate 'string "initarg required: " (string x)))))) ; (error "initarg required: xxxx")
slot-list)))
- kazinator 9y agoIt's interesting to note that Lisp has some "def easys", just not for classes. There is a defsetf for simple situations, so you don't have to use define-setf-expander. defsetf's simplicity isn't one-size-fits-all either; it has a short form and a longer form. In the same area of functionality, there is define-modify-macro which handles simple cases, freeing the user from calling get-setf-expansion and dealing with its return values. P.S. (read-from-string (concatenate 'string ":" (string x))) ==> (intern (string x) 'keyword) `(error ,(concatenate 'string "initarg required: " (string x)) ==> `(error "initarg required: ~s" ',x)