% Macro DEFPACKAGE
Macro DEFPACKAGE
defpackage defined-package-name [[option]] => package
option::= (:nicknames nickname*)* |
(:documentation string) |
(:use package-name*)* |
(:shadow {symbol-name}*)* |
(:shadowing-import-from package-name {symbol-name}*)* |
(:import-from package-name {symbol-name}*)* |
(:export {symbol-name}*)* |
(:intern {symbol-name}*)* |
(:size integer)
defined-package-name - 文字列指定子
package-name - パッケージ指定子
nickname - 文字列指定子
symbol-name - 文字列指定子
package - package-nameという名前のパッケージ
defpackageは指定されたパッケージを作成し、
そのパッケージを返却します。
もしdefined-package-nameがすでに存在しているパッケージを示していたら、 その名前とパッケージのマッピングの対応は変更されません。 もし新しい定義がパッケージの現在の状況と変わっていたときは、 その結果は定義されていません。 実装によっては、新しい定義を反映するよう、 既存のパッケージを修正するか選択するかもしれません。 もしdefined-package-nameがシンボルのときは、その名前が使われます。
標準のオプションを下記に示します。
:nicknames
:nicknamesの引数はパッケージのニックネームに指定した名前をセットします。
:documentation
:documentationの引数は、ドキュメント文字を指定します。
それはパッケージのドキュメント文字に割り当てます。
ひとつのdefpackageフォームに
最大ひとつの:documentationオプションを記載することができます。
:use
:use引数は、package-nameという名前のパッケージが継承するように、
パッケージに対して設定を行います。
:shadow
:shadow引数は、symbol-namesという名前のシンボルを
パッケージ内に作成するように定義します。
それらのシンボルは、shadowによるもののように
効果的にshadowingシンボルのリストに追加されます。
:shadowing-import-from
find-symbolによるもののように検索が実行されます)。
その結果のシンボルがそのパッケージ内にimportされるように定義し、
shadowing-importによるもののように
shadowingシンボルのリストに配置されます。
:import-from
importされます。
どのような場合でも、定義されているパッケージ以外の
パッケージでシンボルを作成してはいけません。
:export
exportします。
継承されるシンボルが作成されるのではなく使用されるとき、
:exportオプションは:useオプションと互いに作用します。
importされるシンボルが作成されるのではなく使用されるとき、
:exportオプションは:import-fromおよび
shadowing-import-fromオプションと互いに作用します。
もし:exportオプションの引数が
use-packageによって(継承された)内部シンボルとして
アクセス可能であるとき、
symbol-nameという名前のシンボルは、
最初に定義されているパッケージにimportされ、
そのあとそのパッケージからexportされます。
:intern
:internオプションは:useオプションと互いに作用します。
:size
:sizeオプションの引数は、予想されるパッケージ内の
シンボルの数の近似値を宣言します。
これはただの効率化のヒントであり、実装によっては無視されるかもしれません。
defpackageフォームに現れるオプションの順番は無関係です。
それらが実行される順番は下記のようになります。
:shadowと:shadowing-import-from:use:import-fromと:intern:export:useオプションが処理されるときに
衝突による偽りの名前をブロックする必要があるため、
最初にshadowを確立させます。
:useオプションが次に実行されるので、
:internと:exportオプションが継承されたシンボルを普通に参照できます。
:exportオプションが最後に実行されるとき、
それは他のオプションの何かによって作成された
シンボルを参照することができます。
とくにshadowingシンボルとimportシンボルを
外部シンボルにすることができます。
もしdefpackageフォームがトップレベルフォームとして現れたとき、
ロード時にこのマクロによって実行される全ての通常のアクションは、
コンパイル時にもまた実行されなければいけません。
(defpackage "MY-PACKAGE"
(:nicknames "MYPKG" "MY-PKG")
(:use "COMMON-LISP")
(:shadow "CAR" "CDR")
(:shadowing-import-from "VENDOR-COMMON-LISP" "CONS")
(:import-from "VENDOR-COMMON-LISP" "GC")
(:export "EQ" "CONS" "FROBOLA")
)
(defpackage my-package
(:nicknames mypkg :MY-PKG) ; Common Lispの大文字小文字の慣習を思い出そう
(:use common-lisp) ; シンボルの慣習
(:shadow CAR :cdr #:cons)
(:export "CONS") ; これはshadowされる
)
存在するパッケージ
:nicknamesで指定したひとつが
すでに既存のパッケージで参照されていたときは、
型package-errorのエラーが発生します。
もし:sizeか:documentationが複数現れていたときは
型program-errorのエラーが発生します。
実装が拡張のオプションを許すとき、
あるオプションが実際にはその実装でサポートされていないものとして現れたとき、
型program-errorのエラーが発生します。
オプションの:shadow, :intern, :import-from, :shadowing-import-fromに
指定されたsymbol-name引数の集まりは、
全てが互いに素でなければいけません。
加えて、:exportと:internのに指定されたsymbol-name引数は
互いに素でなければいけません。
この文脈での互いに素というのは、
2つのsymbol-namesが互いにstring=で
等しくないものとして定義されます。
このどちらかの条件に違反していたときは、
型program-errorのエラーが発生します。
:shadowing-import-fromと:import-fromオプションについて、
package-nameという名前のパッケージに
引数symbol-namesのうちのひとつが
アクセス可能なシンボルではないとき、
修正可能な型package-errorのエラーが発生します。
名前の衝突エラーは、
make-package, use-package, import, exportの
基本的な呼び出しによって捕捉されます。
11.1. パッケージの説明をご確認ください。
documentation,
11.1. パッケージの説明,
3.2. コンパイル
いくつかの他のパッケージの作成に続くdefpackageの呼び出しで、
:import-fromか:shadowing-import-fromオプションを用いて
それらのシンボルをアクセス可能な状態にしたいものの
外部シンボルにする必要はないときは、
:internオプションが便利です。
パッケージの全体の定義を一か所に配置し、
全てのパッケージの定義のプログラムを
ひとつのファイルにしたいとき
defpackageの使用をお勧めします。
このファイルは、
これらのパッケージに依存する他の何かを
ロードしたりコンパイルしたりする前に
ロードすることができます。
このようなファイルは
初期状態の異常を回避するために、
COMMON-LISP-USERパッケージで読み込むことができます。
defpackageは、2つの「互いに再帰的」なパッケージを
作成するときには使えません。
例えば次の通り。
(defpackage my-package
(:use common-lisp your-package) ;最初にyour-packageの存在が必要
(:export "MY-FUN"))
(defpackage your-package
(:use common-lisp)
(:import-from my-package "MY-FUN") ;最初にmy-packageの存在が必要
(:export "MY-FUN"))
しかし、defpackageをより標準的に使ったあとで、
use-package、import、exportなどの
パッケージに影響を与える関数を使って、
そのようなリンクを確立することを妨げるものは何もありません。
defpackageのマクロ展開は、
通常は名前を文字列に正規化するので、
ソースファイルにランダムなシンボルが含まれるdefpackageフォームが
配置されているようなときでさえ、
コンパイルファイルにはただ文字列だけが配置されます。
よく追加で実装依存のオプションに、
キーワードそれ自身のフォームで(keyword T)という
リストの省略形を表すことがあります。
この構文は、これをサポートしていない実装では、
認識できないオプションとして適切に報告されるべきです。