GNU Emacs 32.0.50 (9008bf64c3) のマニュアルを PLaMo 翻訳で機械翻訳したものです。誤訳を含むことがあります。原文: https://www.gnu.org/software/emacs/manual/html_node/elisp/What-Is-a-Function.html ・ emacs-doc.conao3.com

13.1 関数とは?

一般的な意味において、関数とは、引数と呼ばれる入力値を用いて計算を行うための規則のことである。計算の結果は、関数の値または戻り値と呼ばれる。また、この計算は、変数の値やデータ構造の内容に永続的な変更を加えるといった副作用を伴うこともある(副作用の定義を参照)。純粋関数とは、副作用を持たないことに加え、マシンの種類やシステム状態などの外部要因に関わらず、同じ引数の組み合わせに対して常に同じ値を返す関数のことである。

ほとんどのコンピュータ言語では、すべての関数に名前があります。しかしLispでは、厳密な意味での関数には名前がありません。関数とは、関数名として機能するシンボル(例:car)に任意で関連付けることができるオブジェクトのことです。関数の命名を参照してください。関数に名前が付けられている場合、通常はそのシンボル自体も「関数」と呼びます(例:「関数 car」と呼びます)。本マニュアルでは、関数名と関数オブジェクト自体の区別は通常重要ではありませんが、関連する箇所ではそれを明記します。

特殊形式やマクロと呼ばれる特定の関数のようなオブジェクトも、計算を実行するために引数を受け取ります。ただし、後述するように、これらはEmacs Lispにおいて関数とはみなされません。

関数および関数風オブジェクトに関する重要な用語を以下に挙げます。

ラムダ式

Lispで記述される関数(厳密な意味での、すなわち関数オブジェクト)。これらについては次節で説明する。ラムダ式を参照。

プリミティブ

Lispから呼び出し可能だが、実際にはC言語で記述されている関数。プリミティブは組み込み関数、あるいはsubrsとも呼ばれる。例として、carやappendといった関数が挙げられる。さらに、すべての特殊形式(後述)もプリミティブとみなされる。

通常、関数がプリミティブとして実装されるのは、それがLispの根幹をなす部分である(例:car)か、オペレーティングシステムのサービスへの低レベルインターフェースを提供するか、あるいは高速な動作が求められるためです。Lispで定義された関数とは異なり、プリミティブはCソースを変更してEmacsを再コンパイルすることでのみ修正や追加が可能です。Emacsプリミティブの作成を参照してください。

特殊形

関数に似ているが、すべての引数を通常の方法で評価しないプリミティブ。一部の引数のみを評価したり、通常とは異なる順序で、あるいは複数回評価したりする場合がある。例として if、and、while などが挙げられる。特殊形式を参照。

マクロ

Lispで定義される構成要素であり、元の式の代わりに評価される別の式へとLisp式を変換するという点で、関数とは異なります。マクロを用いることで、Lispプログラマは特殊形式で可能な処理を実現できます。マクロを参照してください。

コマンド

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

キーボードマクロ(文字列およびベクトル)は、関数ではありませんが、同様にコマンドでもあります。キーボードマクロを参照してください。シンボルの関数セルにコマンドが含まれている場合、そのシンボルはコマンドであると言います(シンボルの構成要素を参照)。このような名前付きコマンドは、M-xで呼び出すことができます。

クロージャ

ラムダ式に非常によく似た関数オブジェクトですが、レキシカル変数の束縛を含む環境も保持している点が異なります。クロージャを参照してください。

バイトコード関数

バイトコンパイラによってコンパイルされた関数。クロージャ関数型を参照。

オートロードオブジェクト

実関数のプレースホルダー。オートロードオブジェクトが呼び出されると、Emacsは実関数の定義を含むファイルを読み込み、その後その実関数を呼び出します。オートロードを参照してください。

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

関数: functionp object

この関数は、object が何らかの関数(すなわち funcall に渡せるもの)である場合に t を返します。なお、functionp は、関数名であるシンボルに対しては t を、マクロや特殊形式であるシンボルに対しては nil を返します。

object が関数でない場合、この関数は通常 nil を返します。ただし、関数オブジェクトの表現は複雑であり、効率上の理由から、まれに object が関数でない場合でもこの関数が t を返すことがあります。

また、任意の関数がいくつの引数を期待しているかを調べることも可能です:

関数: func-arity function

この関数は、指定された function の引数リストに関する情報を提供します。返される値は (min . max) 形式のコンスセルであり、ここで min は引数の最小数、max は引数の最大数、あるいは &rest 個の引数を持つ関数の場合はシンボル many、function が特殊形式の場合はシンボル unevalled となります。

なお、この関数は、以下のような状況において不正確な結果を返す可能性があることにご注意ください。

  • apply-partially を用いて定義された関数(apply-partially を参照)。
  • advice-add を用いてアドバイズされる関数(名前付き関数のアドバイズを参照)。
  • コードの一部として、引数リストを動的に決定する関数。

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

関数: subrp object

この関数は、object が組み込み関数(すなわち Lisp プリミティブ)である場合に t を返します。

(subrp 'message)            ; message is a symbol,
     ⇒ nil                 ;   not a subr object.
(subrp (symbol-function 'message))
     ⇒ t
関数: byte-code-function-p object

この関数は、object がバイトコード関数である場合に t を返します。例えば:

(byte-code-function-p (symbol-function 'next-line))
     ⇒ t
関数: compiled-function-p object

この関数は、object が Lisp ソースコード形式ではなく、マシンコードやバイトコードのような形式の関数オブジェクトである場合に t を返します。より具体的には、その関数が組み込み関数(いわゆる「プリミティブ」、関数とは何か? を参照)であるか、バイトコンパイル済み(バイトコンパイル を参照)であるか、ネイティブコンパイル済み(Lisp のネイティブコードへのコンパイル を参照)であるか、あるいは動的モジュールからロードされた関数(Emacs 動的モジュール を参照)である場合に t を返します。

関数: interpreted-function-p object

この関数は、object が解釈済み関数である場合に t を返します。

関数: closurep object

この関数は、object がクロージャ(関数オブジェクトの一種)である場合に t を返します。現在、すべてのバイトコード関数およびすべてのインタプリタ関数でクロージャが使用されています。

関数: subr-arity subr

これは func-arity と同様に動作しますが、組み込み関数に限り、かつシンボル間接参照なしで機能します。組み込み関数以外の場合はエラーとなります。代わりに func-arity の使用を推奨します。

関数: cl-functionp object

この関数はfunctionpと同様ですが、リストやシンボルに対してはnilを返します。

関数: primitive-function-p object

この関数は、object が C で記述された組み込みプリミティブである場合に t を返します(プリミティブ関数型 を参照)。なお、特殊形式は関数ではないため、明示的に除外されています。特殊形式も判別する必要がある場合は、subr-primitive-p を使用してください。