5

マクロに関してベストプラクティスが何であるかを理解するのにまだ苦労しています。その場でパッケージを定義するマクロを書き込もうとしています。

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

私はほとんどの基本的なマクロがどのように機能するかを理解していますが、これを実装する方法は私を免れます。

4

2 に答える 2

8

defpackageはマクロです。そのため、実行時ではなくコンパイル時に展開されます。必要なのは、新しいパッケージを作成するために実行時に呼び出されるものです。したがって、defpackageは何もできません。

幸いなことに、defpackageの機能を関数として提供する make-packageもあります。defpackageの代わりに使用してください。

于 2008-11-11T08:03:54.473 に答える
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であることがわかります。

于 2008-11-11T01:08:46.823 に答える