Next: , Up: 関数   [Contents][Index]


13.1 関数とは?

一般的な意味では関数とは引数(arguments)と呼ばれる与えられた入力値の計算を担うルールです。計算の結果は関数の値(value)、またはreturn値(return value)と呼ばれます。計算は変数の値やデータ構造の内容を変更する等の副作用をもつこともできます(Definition of side effectを参照)。純粋関数(pure function)とは、それらに加えて副作用をもたず、機種別やシステム状態のような外部要因とは無関係に同じ条件の引数にたいして常に同一の値をリターンする関数のことです。

ほとんどのコンピューター言語では、関数はそれぞれ名前をもちます。しかしLispでは厳密な意味において関数は名前をもちません。関数はオブジェクトであり、関数の名前の役割を果たすシンボルに関連づけることができますが(たとえばcar)、それはオプションです。関数の命名を参照してください。関数が名前を与えられたとき、通常はそのシンボルを“関数”として参照します(たとえば関数carのように参照する)。このマニュアルでは、関数名と関数オブジェクト自身との間の区別は通常は重要ではありませんが、それが意味をもつような場合には注記します。

スペシャルフォーム(special form)マクロ(macro)と呼ばれる関数likeなオブジェクトがいくつかあり、それらも引数を受け取って計算を行います。しかし以下で説明するようにEmacs Lispではこれらは関数とはみなされません。

以下は関数と関数likeなオブジェクトにたいする重要な条件です:

lambda expression

Lispで記述された関数(厳密には関数オブジェクト)。これらについては以降のセクションで説明します。 ラムダ式を参照のこと。

primitive

Lispから呼び出すことができるが実際にはCで記述されている。プリミティブはビルトイン関数(built-in functions)とかサブルーチン(subr)のようにも呼ばれる。それらの例には関数likeなcarappendが含まれる。加えてすべてのスペシャルフォーム(以下参照)もプリミティブとみなされる。

関数はLispの基礎となる部分(たとえばcar)であり、オペレーティングシステムのサービスにたいして低レベルのインターフェースを与え、高速に実行される必要があるために、通常はプリミティブとして実装されている。Lispで定義された関数と異なり、プリミティブの修正や追加には、Cソースの変更とEmacsのリコンパイルが必要となる。Emacsプリミティブの記述を参照のこと。

special form

プリミティブは関数と似ているが、すべての引数が通常の方法で評価されない。いくつかの引数だけが評価されるかもしれず、通常ではない順序で評価されるか、複数回評価されるかもしれない。プリミティブの例にはifandwhileが含まれる。スペシャルフォームを参照のこと。

macro

あるLisp式をオリジナルの式のかわりに評価される別の式に変換する、関数とは別のLispで定義された構文。マクロはスペシャルフォームが行う一連のことを、Lispプログラマーが行うのを可能にする。マクロを参照のこと。

command

プリミティブcommand-executeを通じて呼び出すことができるオブジェクトで、通常はそのコマンドにバインドされたキーシーケンスをユーザーがタイプすることにより呼び出される。インタラクティブな呼び出しを参照のこと。コマンドは通常は関数である。その関数がLispで記述されていれば、関数の定義内のinteractiveフォームによってコマンドとなる(コマンドの定義を参照)。関数であるコマンドは他の関数と同様、Lisp式から呼び出すこともできる。

キーボードマクロ(文字列かベクター)は関数ではないが、これらもコマンドである。キーボードマクロを参照のこと。シンボルの関数セルにコマンドが含まれてれば、わたしたちはそのシンボルをコマンドと言う(シンボルの構成要素を参照)。そのような名前つきコマンド(named command)M-xで呼び出すことができる。

closure

ラムダ式とよく似た関数オブジェクトだが、クロージャーはレキシカル変数バインディングの環境にも囲われている。クロージャーを参照のこと。

byte-code function

バイトコンパイラーによりコンパイル済みの関数。バイトコード関数型を参照のこと。

autoload object

実際の関数のプレースホルダー。autoloadオブジェクトが呼び出されると、Emacsは実際の関数の定義を含むファイルをロードした後に実際の関数を呼び出す。autoloadを参照のこと。

関数functionpを使用して、あるオブジェクトが関数かどうかテストできます:

Function: functionp object

この関数はobjectが任意の種類の関数(funcallに渡すことができる)ならtをリターンする。functionpは関数を名づけるシンボルにたいしてはt、スペシャルフォームにたいしてはnilをリターンすることに注意。

任意の関数が期待する引数の個数を調べることもできます:

Function: func-arity function

この関数は指定されたfunctionの引数リストに関する情報を提供する。リターン値は(min . max)という形式のコンスセル。ここでminは引数の最小個数、maxは引数の最大個数、または&rest引数をもつ関数ではmanyfunctionがスペシャルフォームならシンボルunevalled

以下のようにある状況下ではこの関数は不正確な結果をリターンすることに注意:

functionpと異なり、以下の3つの関数はシンボルをそれの関数定義としては扱いません

Function: subrp object

この関数はobjectがビルトイン関数(たとえばLispプリミティブ)ならtをリターンする。

(subrp 'message)            ; messageはシンボルであり、
     ⇒ nil                 ;   subrオブジェクトではない
(subrp (symbol-function 'message))
     ⇒ t
Function: byte-code-function-p object

この関数はobjectがバイトコード関数ならtをリターンする。たとえば:

(byte-code-function-p (symbol-function 'next-line))
     ⇒ t
Function: subr-arity subr

これはfunc-arityと同様だがシンボルインダイレクションなしのビルトイン関数にたいしてのみ機能する。非ビルトイン関数にたいしてはエラーをシグナルする。かわりにfunc-arityの使用を推奨する。