macros - 在 Common Lisp 中,编写定义类的宏的最佳方法是什么?

标签 macros common-lisp symbols

我正在尝试在 Common Lisp 中编写一个宏,它定义一个具有我指定的变体槽的类。到目前为止,一切正常(clisp 给我留下了深刻的印象!):

(defmacro notifier (class slot) 
  "Defines a setf method in (class) for (slot) which calls the object's changed method."
   `(defmethod (setf ,slot) (val (item ,class))
     (setf (slot-value item ',slot) val)
     (changed item ',slot)))

(defmacro notifiers (class slots)
  "Defines setf methods in (class) for all of (slots) which call the object's changed method."
  `(progn 
     ,@(loop for s in slots collecting `(notifier ,class ,s))))

(defmacro defclass-notifier-slots (class nslots slots)
  "Defines a class with (nslots) giving a list of slots created with notifiers, and (slots) giving a list of slots created with regular accessors."
  `(progn
     (defclass ,class () 
       ( ,@(loop for s in nslots collecting `(,s :reader ,s)) 
         ,@(loop for s in slots collecting `(,s :accessor ,s))))
     (notifiers ,class ,nslots)))

问题是,现在我想要创建的不仅仅是我在宏调用中指定的插槽,还有一些其他具有变体名称的插槽。为了做到这一点,我必须使用一个丑陋的“符号名称,改变字符串,实习生”序列来生成变体名称作为插槽名称,并且我已经看到了答案,说你应该避免这样做那。那么有更好的方法吗?

最佳答案

在宏或其辅助函数之一中构造新符号没有任何问题。

每当您多次需要某项内容或需要以某种方式记录它时,请编写一个函数。

由于我们需要使用可能的新符号,因此确保该符号位于正确的包中是有意义的。这里我们假设前缀符号的包是正确的包。

(defun make-suffix-symbol (prefix suffix)
  (check-type prefix symbol)
  (check-type suffix (or string symbol))
  (when (symbolp suffix)
    (setf suffix (symbol-name suffix)))
  (intern (concatenate 'string
                       (symbol-name prefix)
                       suffix)
          (symbol-package prefix)))

CL-USER 12 > (make-suffix-symbol 'http-user::foo "BAR")
HTTP-USER::FOOBAR

或使用格式:

(defun make-suffix-symbol (prefix suffix &optional (format-string "~A~A"))
   (check-type prefix symbol)
   (check-type suffix (or string symbol))
   (when (symbolp suffix)
     (setf suffix (symbol-name suffix)))
   (intern (format nil
                   format-string
                   (symbol-name prefix)
                   suffix)
           (symbol-package prefix)))

CL-USER 14 > (make-suffix-symbol 'http-user::foo "BAR" "~a-~a")
HTTP-USER::FOO-BAR

关于macros - 在 Common Lisp 中,编写定义类的宏的最佳方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30015170/

相关文章:

lisp - CONS 对象可以用作哈希表的键吗?

terminal - 重音符号 (`) 在终端中的作用是什么

Rust 递归宏不适用于生成结构

macros - 如何改进用于照应 -> 或 ->> 宏的 Racket 代码?

c - 如何创建具有不同定义的静态链接库的两个实例?

lisp - 如何从 lisp 中的函数返回控制权

lisp - 关闭普通 lisp 中的结果打印

VB.Net 日期时间类 '#' 符号

c - C 中 union 后的 "++"是什么意思?

macros - 编写包含匹配主体的宏