Common Lispの初心者:その場でパッケージを定義するためのマクロの質問
-
07-07-2019 - |
質問
マクロに関するベストプラクティスの理解に苦労しています。パッケージをオンザフライで定義するマクロを作成しようとしています。
(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)))
ほとんどの基本的なマクロがどのように機能するかを理解していますが、これを実装する方法は私を免れます。
解決
defpackage はマクロです。そのため、ランタイムではなくコンパイル時に拡張されます。必要なのは、新しいパッケージを作成するために実行時に呼び出されるものです。したがって、 defpackage では何もできません。
幸いなことに、 make-package : defpackage の機能を機能として提供します。 defpackage の代わりに使用します。
他のヒント
引数が評価されるべきでないときにマクロが使用されるため、ここでは失敗が予想されます。
最初の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 の最初の引数はシンボルである必要はありません。ただし、文字列指定子。
所属していません StackOverflow