計算機科学において、第一級関数(だいいっきゅうかんすう、英: first-class function、ファーストクラスファンクション)とは、関数を第一級オブジェクトとして扱うことのできるプログラミング言語の性質、またはそのような関数のことである。その場合その関数は、型のある言語では function type(en:Function type)などと呼ばれる型を持ち、またその値は関数オブジェクトなどになる。具体的にはプログラムの実行時に生成され、データ構造に含めることができ、他の関数の引数として渡したり、戻り値として返したりすることのできる関数をいう。この概念はメタプログラミングとは異なり、コンパイラ呼び出しやeval関数によって生成された関数は含まれない。無名関数も参照。
第一級関数は関数型言語には必要不可欠であり、高階関数のような形で日常的に用いられる。例として、関数とリストを引数に取り、リストの各要素に関数を適用した結果のリストを返すmap (mapcar) 関数が挙げられる。map関数をサポートするプログラミング言語は、何らかの形で関数を関数の引数として渡すことを許容しなければならない。
Schemeでの例:
スタックベースのプログラミング言語では、高階関数の実装における自由変数の取り扱いに関して困難な問題が生じる。これはFunarg問題("function argument" の略称、英: funarg problem)として知られている。
型理論では、型 の値を受け取り、型 の値を返す関数を (もしくは )と書く。これは と似ているが実は同じもので、カリー・ハワード対応(カリー・ハワード同型対応、英: Curry-Howard correspondence)によれば、関数型は論理包含に関係しており、ラムダ抽象は自然演繹における仮説、関数の適用はモーダスポネンスに相当する。また多くのプログラミング言語の機能として、型理論は第一級関数が連想配列などのデータ構造をモデルするのにも用いられる。
圏論においては、第一級関数は閉圏に相当する。たとえば単純型付きラムダ計算(英: simply typed lambda calculus)は、カルテシアン閉圏(デカルト閉圏)の言語に相当する。
利用
HaskellやLisp、ML、Schemeのような関数型言語は第一級関数を全面的にサポートしている。他に第一級関数をサポートしているプログラミング言語としては、ECMAScript (ActionScript、JavaScript)、Io、Lua、Nemerle、Perl、PHP、Python、Ruby、Scala、Tclなどが挙げられる。
C言語やC 、Pascalなどのプログラミング言語は関数へのポインタをサポートしており、データ構造に含めたり他の関数に引数として渡したりすることができる。しかし、関数ポインタによって第一級関数をサポートしているとみなされてはいない。
C はoperator()を含むユーザ定義演算子をサポートしており、operator()を持つクラスは関数オブジェクトとして扱うことができる。関数オブジェクトはC では他の第一級オブジェクトと同じように操作することができる。また、C 11では無名関数がサポートされている。
各言語での例
C
D
Erlang
Scheme
Lisp
Lua
この例では第一級関数はIPアドレスのテーブルのソート戦略を指定するのに使われている。
テーブルのホスト名を辞書順の逆でソートするには、次のように書く。
ALGOL 68
PROC newton = (REAL x, error, PROC (REAL) REAL f, f prime) REAL: # ニュートン法 # IF f(x) <= error THEN x ELSE newton (x - f(x) / f prime (x), error, f, f prime) FI; print(( newton(0.5, 0.001, (REAL x) REAL: x**3 - 2*x**2 6, (REAL x) REAL: 3*x**2 - 4**x), newline ));
JavaScript
JavaScriptは第一級関数をサポートする。関数はレキシカルスコープを作り出す。
arguments.calleeプロパティを使うとJavaScriptでも無名再帰関数を書くことができる。なお、ECMAScript5のstrict modeではarguments.calleeの使用は禁じられている。
Perl
これはPerlにおける第一級関数だけでなく、クロージャの例にもなっている。また留意すべきこととして、オブジェクト指向Perlにおいてはクラスに関数のリファレンスをblessすることが可能である。
Python
Pythonではdef文またはlambda式によって関数を生成する。第一級関数としては十分柔軟であるが、lambda式によって定義できる関数の本体は式に限られ、文を含む関数を生成することはできない。
C#
C# 2.0から匿名メソッド (anonymous method) を、またC# 3.0からラムダ式を、それぞれサポートする。
Ruby 1.9
Scala
Haskell
PHP 5.3
関連項目
- 無名関数
- クロージャ
- 関数オブジェクト
- 第一級オブジェクト
参考文献
外部リンク
- Rosetta CodeにおけるFirst-class functions




![]()