仍在努力了解有关宏的最佳做法。我正在尝试编写一个动态定义包的宏。
(defmacro def-dynamic-package (name)
`(defpackage ,(intern (string-upcase name) "KEYWORD")
(:use :common-lisp)))
仅适用于以下表达式:
(def-dynamic-package "helloworld")
但是对于这样的事情惨遭失败:
(defun make-package-from-path (path)
(def-dynamic-package (pathname-name path)))
或
(defun make-package-from-path (path)
(let ((filename (pathname-path)))
(def-dynamic-package filename)))
我理解大多数基本宏是如何工作的,但是如何实现这个宏却让我感到厌烦。
答案 0 :(得分:8)
defpackage 是一个宏。因此,它在编译时扩展,而不是在运行时扩展。你想要的是在运行时调用以生成新包的东西。因此, defpackage 无法为您做任何事情。
幸运的是,还有 make-package ,它提供了 defpackage 的功能。使用它代替 defpackage 。
答案 1 :(得分:0)
这里可能会出现失败,因为在不应评估其参数时会使用宏。
在你的第一个make-package-from-path中,def-dynamic-package将接收一个与以下表达式的值相等的列表作为参数:
(list 'pathname-name 'path)
在您的情况下,您只需要一个功能:
(defun def-dynamic-package (name)
(defpackage (string-upcase name)
(:use :common-lisp)))
顺便说一句,如果您查看CLHS,您会看到defpackage的第一个参数不必是符号,而是string designator。