У меня есть класс в Common Lisp:
(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"))
Я хотел создать макрос, который упростил бы эту избыточность ввода
(defmacro make-slot (slot-name)
`(slot-name
:initarg :,slot-name
:accessor :,slot-name
:initform (error "Must supply value")))
В конце концов я 'хотел бы иметь (defclass my-cool-class () (make-slots' (foo bar baz)) и автоматически получать foo, bar и baz как слоты.
Но когда я пошел, чтобы сделать macroexpand-1
make-slot, мальчик, привет, я получил ошибки чтения.
Первым был «недопустимый завершающий символ после двоеточия ...», а затем он продолжал работать.
SBCL 1.0 .37.
править: примеры синтаксически верны в системе, я немного отредактировал, прежде чем скопировать.
Шесть месяцев спустя -
(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))):
Два с половиной года спустя.
Я обнаружил код шестимесячной давности в дикой природе в другом месте. Хотя я польщен, он также напоминает мне обновить это.
Если вам нравится эта идея, я храню этот код по адресу: https://github.com/pnathan/defobject . Как и прежде, его цель - создавать классы CLOS с минимумом повторяющейся типизации. Аналогичная система существует под названием DEFCLASS-STAR. Заинтересованным сторонам рекомендуется ознакомиться с обоими.