defmacro与defclass

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.建议有兴趣的人士审核.

Rai*_*wig 5

您不能将宏放在您想要的代码中.阅读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*宏在库中执行类似的操作.