プログラミング言語における無名関数(英語: anonymous functionあるいはnameless function)とは、名前付けされずに定義された関数のことである。無名関数を表現するための方法には様々なものがあるが、近年主流となっているのはラムダ式による記法である。無名関数を表現するリテラル式は、関数リテラル (function literal) とも呼ばれる。値がある場合は関数オブジェクトであるものが多い。
ラムダ式
ラムダ式 (lambda expression) はラムダ計算と関係が深く、関数型言語で特によく採用されている。
Haskellにおける例を示す。バックスラッシュ '\' がギリシャ文字のラムダ 'λ' のように見えることから、Haskellではラムダ式を表す構文に採用されている。
Haskellでは変数にバインドせずにラムダ式を直接引数に作用させることもできる。
以下のように高階関数の引数にラムダ式を渡すこともできる。
関数型ではないプログラミング言語においても、ラムダ式を言語機能として取り入れる動きが活発である。
C#ではC# 3.0にて導入された。以下に例を示す。
C ではC 11にて導入された。以下に例を示す。
JavaではJava 8にて導入された。以下に例を示す。
C#の無名関数
C#には大きく分けて2種類の無名関数(匿名関数)の記法が存在する。一つは、C# 2.0で導入された匿名メソッド (anonymous method) である。もう一つは、C# 3.0で導入されたラムダ式である。通例、ラムダ式のほうが簡潔であり、またラムダ式は式木として扱うこともできるため、基本的にC# 3.0以降ではラムダ式を用いる。
C#のラムダ式と匿名メソッドを比較した場合に唯一匿名メソッドが勝っている点は、パラメーターリストを省略できることである。
なお、ラムダ式や匿名メソッドがデリゲートパラメータとして渡される場合、内部的にはコンパイラによって自動的に命名された(C#開発環境では通常命名できない名前の)クラスが生成され、ラムダ式・メソッドはそのメンバーメソッドとして自動的に命名された後、コンパイルが実行される。つまり、IL化された時点で定義済みの名前付きメソッドのデリゲートを生成して渡す操作へと置換されるため、コンパイル後は通常の(名前付きメソッドの)デリゲート呼び出しと挙動的にはほぼ変わらない扱いとなる。
例えば(実用的ではないものの)リフレクションを介して無名関数の「名前」を見つけ出せば、再度呼び出すことも可能である。
JavaScriptの無名関数
JavaScriptではfunctionというキーワード(予約語)を用いて記述する。
ECMAScript 2015を用いる場合は、「アロー関数」という記法を用いることもできる。
Luaの無名関数
Luaにおける関数は第一級オブジェクトであり、すべての関数が本質的に無名関数である。名前付きの関数とは、関数オブジェクトへの参照を保持する変数にすぎない。
というコードは、次のコードに対する糖衣構文である。
Pythonの無名関数
Pythonではlambdaというキーワードを使う。Python特有の注意点として、lambdaの内容には式のみが書け、文は書けない点が挙げられる。
注意)Pythonではlambda式の変数へのバインドは非推奨。ここでは他の言語の例との比較を目的として行っている。
無名関数の特徴
メリット
- 一度しか使わない関数の名前を付けなくて済む。名前の衝突を考えなくて済む。
- 関数の引数などに直接渡せる。
特にC ではアルゴリズム関数テンプレートにおける述語 (predicate) としての関数オブジェクトの明示的な定義が不要になり、簡潔なコードを記述しやすくなる。
C 14での例を示す。
デメリット
- 名前で参照できないため、再帰のためには何らかのテクニックがほぼ必要になる(無名再帰を参照)。
言語にもよるが、ラムダ式には通常の関数あるいはメソッドよりも機能制限がある。C# 7.0ではラムダ式の欠点を補うことのできるローカル関数が導入された。
脚注
参考文献
- Anonymous function - HaskellWiki
- 匿名関数 (C# プログラミング ガイド)
関連項目
- ラムダ計算
- 高階関数




