Next: Defining Functions, Previous: Lambda Expressions, Up: Functions
ほとんどの計算機言語では、各関数には名前があります。
名前のない関数という考えは本質的ではありません。
Lispでは、もっとも厳密にいえば、関数には名前はありません。
関数は、先頭要素が単にlambda
であるリスト、
バイトコード関数オブジェクト、あるいは、基本関数のsubrオブジェクトです。
しかしながら、シンボルは関数の名前として働きます。 シンボルの関数セル(function cell、see Symbol Components)に 関数を入れると、このようになります。 そうすると、シンボルそのものは正当な呼び出し可能な関数となり、 関数セルが参照するリストやsubrオブジェクトと等価になります。 関数セルの内容をシンボルの関数定義(function definition)とも呼びます。 シンボルのかわりにシンボルの関数定義を使う処理を シンボルの関数間接(symbol function indirection)と呼びます。 See Function Indirection。
実用上、ほとんどすべての関数には、このようにして名前が付いていて、
その名前で参照します。
たとえば、シンボルcar
は、
その関数セルに基本関数のsubrオブジェクト#<subr car>
が格納してあるので、
その動作を行う関数として動作します。
関数に名前を与えるのは、Lisp式からその名前で参照できると便利だからです。
#<subr car>
のような基本関数のsubrオブジェクトでは、
名前はそれらを参照する唯一の方法です。
そのようなオブジェクトには入力構文はありません。
Lispで書いた関数では、明示的なラムダ式より名前を使うほうがより便利です。
また、関数に名前があればそれを参照できます。
つまり、再帰呼び出しができます。
関数の名前をその定義そのものに書くことは、
関数定義がそれ自身を指すようにする
(これは不可能ではないにしても、実用上はさまざまな欠点がある)よりは、
とても便利です。
関数を指名するシンボルで関数をしばしば識別します。
たとえば、しばしば『関数car
』といって、
シンボルcar
と関数定義である基本関数のsubrオブジェクトとを区別しません。
ほとんどの目的には、区別する必要はありません。
たとえそうであっても、関数に一意な名前は必要ないことを
心に留めておいてください。
関数オブジェクトは普通1つのシンボルの関数セルだけに現れますが、
これは単なる便法です。
fset
を使って、複数のシンボルに格納するのは簡単です。
そうすると、各シンボルは同じ関数を同等に指名します。
関数名として使うシンボルは、変数としても使えます。 シンボルのこれら2つの使い方は独立していて衝突しません。 (SchemeなどのLispの方言のなかには、 シンボルの値とその関数定義を区別しないものもある。 変数としてのシンボルの値は、その関数定義でもある。) シンボルに関数定義を与えていないと、そのシンボルを関数としては使えません。 これは、シンボルに変数としての値があるかどうかには関係しません。