Pau*_*han 7 lisp macros common-lisp
我有一个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"))
Run Code Online (Sandbox Code Playgroud)
我想创建一个可以简化这种打字冗余的宏
(defmacro make-slot (slot-name)
`(slot-name
:initarg :,slot-name
:accessor :,slot-name
:initform (error "Must supply value")))
Run Code Online (Sandbox Code Playgroud)
最终我想(defclass my-cool-class()(make-slots'(foo bar baz))并自动将foo,bar和baz作为插槽.
但是,当我去做一个macroexpand-1制作插槽的时候,男孩我怎么会得到读者错误.
第一个是"结肠后非法终止性格......"然后它继续前进.
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))):
Run Code Online (Sandbox Code Playgroud)
两年半之后.
我在其他地方发现了这个有六个月历史的代码.虽然我受宠若惊,但它也提醒我更新这个.
如果您喜欢这个想法,我会将此代码保留在以下网址:https://github.com/pnathan/defobject.和以前一样,它的目标是以最少的重复输入生成CLOS类.存在类似的系统,称为DEFCLASS-STAR.建议有兴趣的人士审核.
您不能将宏放在您想要的代码中.阅读CLHS中构造的语法.
例如,您不能这样做:
(defun foo (make-arg-list 'a 'b) a b)
Run Code Online (Sandbox Code Playgroud)
DEFUN期望arglist而不是创建arglist的函数.
Lisp扩展了宏,Lisp格式是预期的.如果需要其他列表(例如插槽列表),Lisp不会宏扩展.
类似的DEFCLASS需要一个插槽列表,而不是一个创建插槽列表的函数.类似于插槽列表,DEFCLASS希望每个插槽都是名称或描述插槽的列表.
请参阅DEFCLASS的语法:http: //www.lispworks.com/documentation/HyperSpec/Body/m_defcla.htm
你也不能把逗号放在你想要的地方.
Probabaly是一本基本的Lisp书可能有所帮助.阅读有关Lisp语法的内容.
:,foo
Run Code Online (Sandbox Code Playgroud)
以上没有意义.
逗号运算符将项放入反引号列表中.它不会将项目放入符号中.
如果要创建符号,则需要调用INTERN或MAKE-SYMBOL.
解
编写一个MY-DEFCLASS宏,允许更短的语法并扩展到DEFCLASS.已经有DEFCLASS*宏在库中执行类似的操作.