Common Lisp的初学者:动态定义包的宏问题

时间:2008-11-11 00:47:44

标签: macros lisp common-lisp

仍在努力了解有关宏的最佳做法。我正在尝试编写一个动态定义包的宏。

(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)))

我理解大多数基本宏是如何工作的,但是如何实现这个宏却让我感到厌烦。

2 个答案:

答案 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