Ho una classe in Common Lisp:defmacro con defclass
(defclass my-cool-class()
((variable1
:initarg :variable1
:accessor variable1
:initform (error "Must supply value to variable1"))
(variable2
:initarg :variable2
:accessor variable2
:initform (error "Must supply value to variable2"))
ho voluto creare una macro che semplificherebbe questa ridondanza di digitare
(defmacro make-slot (slot-name)
`(slot-name
:initarg :,slot-name
:accessor :,slot-name
:initform (error "Must supply value")))
Alla fine mi piacerebbe avere (defclass my-cool-class() (make-slot '(foo bar baz)) e ottenere foo, bar e baz come slot automagically.
Ma, quando sono andato a fare un macroexpand-1
di make-slot, ragazzo howdy ho avuto errori di lettura.
Il primo era "carattere di chiusura illegale dopo un colon ..." e poi ha continuato.
SBCL 1.0.37.
modifica: gli esempi sono sintatticamente corretti sul sistema, ho fatto qualche redazione prima di copiare.
sei mesi più tardi -
anni(defun build-var (classname var)
(list var
:initform nil
:accessor (intern (concatenate 'string (string classname) "-"
(string var)))
:initarg (intern (string var) :keyword)))
(defun build-varlist (classname varlist)
(loop for var in varlist
collect (build-var classname var)))
(defmacro defobject (name &rest varlist)
"Defines a class with a set of behavior.
Variables are accessed by name-varname.
(defobject classname v1 v2 v3)
"
`(defclass ,name()
,(build-varlist name varlist))):
Due anni e mezzo più tardi.
Ho scoperto il codice di sei mesi in natura altrove. Mentre sono lusingato, mi ricorda anche di aggiornare questo.
Se ti piace questa idea, tengo questo codice a: https://github.com/pnathan/defobject. Come prima, il suo obiettivo è quello di produrre classi CLOS con il minimo di digitazione ripetitiva. Esiste un sistema simile chiamato DEFCLASS-STAR. Le parti interessate sono invitate a rivedere entrambi.
Hm. Ho pensato - erroneamente evidentemente - che una macro si sarebbe espansa in modo sostitutivo; quindi, defclass vedrebbe la lista di slot. –
@Paul Nathan, come dovrebbe Lisp decidere che MAKE-SLOT è una macro e non il nome di uno slot? La sintassi DEFCLASS è chiara, si aspetta un elenco di slot. Non si aspetta una funzione che valuti in una lista di slot. –
Ah, immagino che il mio errore principale qui sia il mio modo di pensare su come le macro vengono espanse e quando. –