tengo una clase en 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"))
quería crear una macro que simplificaría esta redundancia de escribir
(defmacro make-slot (slot-name)
`(slot-name
:initarg :,slot-name
:accessor :,slot-name
:initform (error "Must supply value")))
el tiempo me gustaría tener (defclass my-cool-class() (make-slots '(foo bar baz)) y obtener foo, bar y baz como slots automágicamente.
Pero, cuando fui a hacer un macroexpand-1
de make-slot, chico ¿cómo puedo obtener errores de lector?
El primero fue "carácter de terminación ilegal después de un colón ..." y luego continuó.
SBCL 1.0.37.
editar: los ejemplos son sintácticamente correctos en el sistema, hice algo de redacción antes de copiar.
Seis meses más tarde -
años(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))):
Dos años y medio más tarde.
Descubrí el código de seis meses en otro lugar. Aunque me siento halagado, también me recuerda actualizar esto.
Si te gusta esta idea, guardo este código guardado en: https://github.com/pnathan/defobject. Como antes, su objetivo es producir clases CLOS con el mínimo de tipeo repetitivo. Existe un sistema similar llamado DEFCLASS-STAR. Se recomienda a las partes interesadas que revisen ambas.
Hm. Pensé, por error, evidentemente, que una macro se expandiría en forma de reemplazo; por lo tanto, defclass vería la lista de slots. –
@Paul Nathan, ¿cómo debería decidir Lisp que MAKE-SLOT es una macro y no el nombre de una ranura? La sintaxis de DEFCLASS es clara, espera una lista de ranuras. No espera una función que se evalúa en una lista de ranuras. –
Ah, supongo que mi error principal es pensar cómo se expanden las macros y cuándo. –