Next: Forms, Previous: Evaluation, Up: Evaluation
Lispインタープリタ、つまり、エバリュエータは、 与えられた式の値を計算するプログラムです。 Lispで書いた関数を呼び出すと、エバリュエータは、その関数本体内の 式を評価することで関数の値を計算します。 したがって、どんなLispプログラムの実行でも、 Lispインタープリタを実行することを意味します。
エバリュエータによるオブジェクトの扱い方は、 主にオブジェクトのデータ型に依存します。
評価することを意図したLispオブジェクトを 式(expression)とかフォーム(form)と呼びます。 式はデータオブジェクトであり単なるテキストではないという事実は、 Lisp様言語と典型的なプログラム言語との基本的な違いの1つです。 どんなオブジェクトでも評価できますが、実用上は、 数、シンボル、リスト、文字列を評価することが多いのです。
Lisp式を読み取りその式を評価することはとても一般的なことですが、
読み取りと評価は別々の動作であり、それぞれを別々に実行することもできます。
読み取り自体では、なにも評価しません。
Lispオブジェクトの表示表現をオブジェクトそのものに変換します。
このオブジェクトを評価すべきフォームとするか、
まったく別の目的に使うかは、read
の呼び出し側で決まります。
評価とコマンドキーの解釈を混同しないでください。
エディタコマンドループは、有効なキーマップを用いて
キーボード入力をコマンド(対話的に呼び出し可能な関数)に変換し、
call-interactively
を使ってコマンドを起動します。
コマンドがLispで書いてあれば、
コマンド自体の実行には評価が関わってきますが、
そのことは、コマンドキーの解釈自体には含まれていません。
評価は再帰的な処理です。
つまり、フォームの評価では、
eval
を呼び出してそのフォームの一部分を評価することもあります。
たとえば、関数呼び出しの評価においては、まず、
関数呼び出しの各引数を評価してから、関数本体の各フォームを評価します。
(car x)
の評価を考えてみましょう。
まず最初にx
を再帰的に評価する必要があります。
その値を関数car
の引数として渡せるようにするのです。
関数呼び出しの評価においては、最終的に指定した関数を呼び出します。 See Functions。 関数の実行そのものも、関数定義を評価する場合もあります。 あるいは、関数はC言語で実装されたLisp基本関数かもしれませんし、 バイトコード関数かもしれません(see Byte Compilation)。
フォームの評価は、環境(environment)と呼ばれる文脈において 行われます。 環境とは、すべてのLisp変数の現在値と束縛です 1。 フォームが新たな束縛を作らずに変数を参照する場合には、 現在の環境におけるその変数の束縛の値を使います。 See Variables。
フォームを評価すると、変数(see Local Variables)を束縛して、
再帰的評価のための新たな環境を作ることがあります。
これらの環境は一時的なもので、そのフォームの評価を完了すると
消えてしまいます。
フォームは恒久的な変更を行ってもかまいません。
このような変更を副作用(side effects)と呼びます。
副作用を持つフォームの例は、(setq foo 1)
です。
フォームの各種類ごとの評価の意味の詳細は、 以下で説明します(see Forms)。