npt-japanese

% Macro DEFPACKAGE

UP


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がシンボルのときは、その名前が使われます。

標準のオプションを下記に示します。

defpackageフォームに現れるオプションの順番は無関係です。 それらが実行される順番は下記のようになります。

  1. :shadow:shadowing-import-from
  2. :use
  3. :import-from:intern
  4. :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-packageimportexportなどの パッケージに影響を与える関数を使って、 そのようなリンクを確立することを妨げるものは何もありません。

defpackageのマクロ展開は、 通常は名前を文字列に正規化するので、 ソースファイルにランダムなシンボルが含まれるdefpackageフォームが 配置されているようなときでさえ、 コンパイルファイルにはただ文字列だけが配置されます。

よく追加で実装依存のオプションに、 キーワードそれ自身のフォームで(keyword T)という リストの省略形を表すことがあります。 この構文は、これをサポートしていない実装では、 認識できないオプションとして適切に報告されるべきです。


TOP, Github