我有一个 Common Lisp 类(class):

(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 作为插槽取出。

但是,当我去做 make-slot 的 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))):

两年半后。

我在其他地方发现了六个月大的代码。虽然我很受宠若惊,但它也提醒我更新这个。

如果您喜欢这个想法,我会将这段代码保存在: https://github.com/pnathan/defobject 。和以前一样,它的目标是生成重复输入最少的 CLOS 类。存在一个类似的系统,称为 DEFCLASS-STAR。建议有兴趣的各方审查两者。

最佳答案

您不能将宏放在您想要的代码中。 阅读 CLHS 中结构的语法。

例如你不能这样做:

(defun foo (make-arg-list 'a 'b) a b)

DEFUN 需要 arglist 而不是创建 arglist 的函数。

Lisp 扩展宏,其中需要 Lisp 形式。在需要其他列表(例如插槽列表)的地方,Lisp 不会宏展开。

类似的 DEFCLASS 需要一个插槽列表,而不是一个创建插槽列表的函数。
与插槽列表类似,DEFCLASS 期望每个插槽是一个名称或一个描述插槽的列表。

查看 DEFCLASS 的语法:
http://www.lispworks.com/documentation/HyperSpec/Body/m_defcla.htm

你也不能把逗号放在你想要的地方。

也许一本基本的 Lisp 书可能会有所帮助。阅读 Lisp 语法。
:,foo

以上意义不大。

逗号运算符将项目放入反引号列表中。它不会将项目放入符号中。

如果要创建符号,则需要调用 INTERN 或 MAKE-SYMBOL。

解决方案

编写一个 MY-DEFCLASS 宏,允许使用更短的语法并扩展为 DEFCLASS。已经有 DEFCLASS* 宏在库中做类似的事情。

关于macros - defmacro 和 defclass,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/3868658/

10-11 16:29