Next: , Previous: , Up: Top   [Contents][Index]


6 宣言

Common Lispは、特別の変数に格納されるデータの型や、それらの変数や 関数がどのように使われるかについて特殊なヒントをコンパイラに 与えることを許す、複雑で強力な“宣言”メカニズムを含む。この パッケージは、declarelocallyproclaimdeclaimtheといったすべてのCommon Lisp宣言フォームの 版を定義する。

Common Lisp宣言のほとんどは、現在はEmacs Lispでは有用ではない。 バイトコードシステムは型情報から利益を得る機会をほとんど 提供していないし、special宣言は完全に動的スコープのLispでは 冗長だからである。しかし、いくつかの宣言はEmacs 19の最適化 バイトコンパイラが使われるときに意味がある。以前の非最適化 コンパイラでは、これらの宣言は実際には無視される。

Function: proclaim decl-spec

この関数は、decl-specによって指定された“グローバル”宣言を 記録する。proclaimは関数なので、decl-specは評価され、 したがって通常は引用符をつけるべきである。

Special Form: declaim decl-specs…

このマクロはproclaimに似ているが、decl-spec引数を 任意個数取ることと、引数は評価されず引用符はつけない点が異なる。 declaimマクロはまた、実行時と同様にコンパイル時にも 登録されるように、宣言の周りに (eval-when (compile load eval) ...)を置く(このことはきわめて 重要である。宣言は通常、declaimフォームを含むファイルの残りを コンパイラが扱う方法に影響するように意図しているからである)。

Special Form: declare decl-specs…

このマクロは、関数や他のコード内で宣言するために使われる。Common Lisp はさまざまな場所で、一般にLisp文法を通じて、関数本体やlet本体、 その他のような多くの“暗黙のprogn”の始まりで宣言を許す。現在 declareによって理解される唯一の宣言はspecialである。

Special Form: locally declarations… forms…

このパッケージでは、locallyprognと相違はない。

Special Form: the type form

theによって提供される型情報はこのパッケージでは無視される; 言い替えれば、(the type form)formと 同等である。最適化バイトコンパイラの将来の版はこの情報を 利用するかもしれない。

たとえば、mapcarはリストと配列の両方にマップできる。 列がリストか配列か前もってわからない限り、コンパイラが コンパイラがmapcarをインラインループへ展開することは難しい。

(mapcar 'car (the vector foo))に対して、将来のコンパイラは、 ループをインラインに展開するための十分な情報を持つかもしれない。 今のところ、Emacs Lispは上記のコードを(mapcar 'car foo)と正確に 同等に扱う。

proclaimdeclaimdeclareのそれぞれの decl-specは、どんな種類の宣言かを言うシンボルで始まる リストであるべきである。このパッケージは、現在はspecialinlinenotinlineoptimizewarn宣言を 理解する(warn宣言は標準Common Lispへの拡張である)。typeftypeのような他のCommon Lisp宣言は無言で無視される。

special

Emacs Lispのすべての変数は(Common Lispの意味で)“スペシャル” であるので、special宣言は単なる助言である。それらは単に、 指定された変数は意図的に関数本体で束縛されずに参照されることを最適化 バイトコンパイラに告げる。コンパイラは通常、そのような参照に警告を 発するが、それは局所変数への参照の誤記である可能性があるためである。

宣言(declare (special var1 var2))は最適化 コンパイラでは(defvar var1) (defvar var2)と 同等であり、より古いコンパイラ(非局所参照を警告しない)ではまったく 何とも同等ではない。

トップレベルコンテキストでは、(declaim (special var))より も(defvar var)と書く方が一般に優れている。defvarは あなたの意図をより明らかにするからである。しかし古いバイトコンパイラは、 関数の内部に現れるdefvarを扱えないが、 (declare (special var))はすべてのコンパイラで正しく 働くよう注意が払われる。

inline

inline decl-specは、コンパイラが準備できるときはいつでも、 その本体を呼び出す関数に“インライン”に展開すべき1つまたはそれ以上の 関数をリストする。たとえば、Common Lisp関数cadrは、1回の (比較的高価な)関数呼び出しを省くために、フォーム(cadr x) はユーザ関数で呼び出される際に直接(car (cdr x))に 展開されるように、このパッケージによってinlineと宣言される。

下記の宣言はすべて同等である。defsubstフォームは関数を定義して それをインラインにするのをすべて1度に行なう便利な方法だが、Emacs 19で しか利用できないことに注意せよ。

(declaim (inline foo bar))
(eval-when (compile load eval) (proclaim '(inline foo bar)))
(proclaim-inline foo bar)      ; Lucid Emacs only
(defsubst foo (...) ...)       ; instead of defun; Emacs 19 only

注意せよ: この宣言は、含んでいるソースファイルが終わった後も 効果を残す。あなたが定義した関数がインラインになるべきと要求するために 使うことは正しいが、外部関数のインライン化を要求するために使うことは 無作法である。

Common Lispでは、ある関数への特別な呼び出しが単にその呼び出しを インラインにする前に、(declare (inline …))を使うことが 可能である; 現在のバイトコンパイラは、これを実装する方法を 提供していないので、(declare (inline …))は現在はこの パッケージによって無視される。

notinline

notinline宣言は、結局インラインにすべきでない関数をリストする; それは以前のinline宣言を取り消す。

optimize

この宣言は、どのくらいの最適化がコンパイラによってなされるかを制御する。 当然、それは初期の非最適化コンパイラでは無視される。

optimizeには、(speed 3)(safety 2)のように 任意の数のリストが続く。Commons Lispは、いつくかの最適化“品質”を 定義する; このパッケージは、speedsafety以外はすべて 無視する。品質の値は0から3までの整数であるべきである。 0は“重要でない”を、3は“とても重要である”を意味する。両者の品質の 既定レベルは1である。

このパッケージ中では、Emacs 19の最適化コンパイラの場合、speed 品質はbyte-compile-optimizeフラグに結びつけられ、 (speed 0)の場合はnilが、より高い設定の場合はtが 設定される; また、safety品質はbyte-compile-delete-errors フラグに結びつけられ、(safety 3)の場合はtが、より 低いすべての設定の場合はnilが設定される(後者のフラグは、その 副作用のみがエラーを通知する可能性があるようなコードを最適化し 去るかどうか(たとえばfooが実行時に束縛されるかどうかが未知の 場合に(progn foo bar)barに書き直す)を制御する)。

(safety 0)でコンパイルしてさえ、Emacsのバイトコードシステムは、 真に害になることが起こらないようにするための十分なチェックを 提供することに注意せよ。たとえば、Emacs自身に重大なバグがなければ、 Emacsは単に完全に最適化されたLispプログラム中のエラーのために セグメント違反でクラッシュすることはない。

optimize宣言は、通常はファイルのトップレベルのproclaimdeclaimで使われる; Common Lispは、与えられたフォームに局所的な 最適化のレベルを設定するために、declareと一緒に使われることを 許すが、これは最適化コンパイラの現在の版では正しく動作しないだろう (declareは新たな最適化レベルを設定するだろうが、そのレベルは、 囲むフォームが終わった後に自動的には設定解除されないだろう)。

warn

この宣言は、どんな種類の警告がバイトコンパイラによって生成されるかを 制御する。再度言うと、最適化コンパイラだけが警告を生成する。 語warnには、最適化品質に似た形式の任意個数の“警告品質”が 続く。現在サポートされている警告の型は、redefinecallargsunresolvedfree-varsである; 現在の システムでは、0の値はそれらの警告を無効にし、それ以上のすべての値は 有効にする。詳細は最適化バイトコンパイラの文書を見よ。


Next: , Previous: , Up: Top   [Contents][Index]