第一級オブジェクトとは
第一級オブジェクト(ファーストクラスオブジェクト)とは、
プログラミング言語における基本的な操作、例えば生成、代入、演算、そして関数や
プロシージャへの
引数としての受け渡しや戻り値としての利用が、制限なく可能な対象のことを指します。ここで言う「オブジェクト」は、必ずしも
オブジェクト指向プログラミングにおけるオブジェクトに限定されるものではなく、より広範な「対象物」や「客体」を意味します。第一級オブジェクトは、しばしば「第一級データ型に属する」とも表現されます。
この概念は、1960年代に
クリストファー・ストレイチーが「functions as first-class citizens(関数を第一級市民として扱う)」という文脈で初めて用いたとされています。
第一級オブジェクトの性質
第一級オブジェクトは、言語によってその詳細が異なりますが、概ね以下のような性質を持ちます。
無名のリテラルとしての表現: 名前を持たない定数として直接記述できる。
変数への格納: 変数に値を代入して保持できる。
データ構造への格納: 配列やリスト、辞書などのデータ構造に格納できる。
独立性: 名前とは独立して存在できる。
等値性の比較: 他のオブジェクトとの比較が可能である。
関数やプロシージャの引数: 関数や
プロシージャに
引数として渡せる。
関数やプロシージャの戻り値: 関数やプロシージャから戻り値として返せる。
実行時の構築: プログラムの実行中に動的に生成できる。
表示: 人間が読める形式で表示できる。
読み込み: 外部からデータを読み込んで作成できる。
プロセス間転送: 分散したプロセス間で転送できる。
プロセス外保存: 実行中のプロセスの外にファイルなどとして保存できる。
具体例
例えば、
C言語や
C++では、スカラー型(
整数、
浮動小数点数など)や
構造体(
C++ではクラス型とも呼ばれます)は、代入演算子 `=` を使用でき、関数の
引数や戻り値の型としても直接利用できます。これらは第一級オブジェクトとみなせます。しかし、C/
C++の
配列(固定長
配列)は、
配列そのものの代入や、関数の
引数・戻り値として直接使用することはできません。代わりにポインタや参照を用いる必要がありますが、これらは
配列そのものではなく、ポインタや参照のコピーに過ぎません。
配列を
構造体に含めれば、
構造体全体として代入や関数の
引数・戻り値として扱うことはできますが、この場合、対象となるのはあくまで
構造体であり、
配列そのものではありません。そのため、C/
C++の
配列は第一級オブジェクトとは言えません。同様に、C/
C++の
文字列も文字
配列で実現されているため、第一級オブジェクトではありません。また、C/
C++では関数を実行時に作成することもできません。
しかし、C/
C++では関数ポインタを使用することで、第一級オブジェクトの多くの性質を満たすことができます。そのため、C/
C++の関数は第二級オブジェクトと呼ばれることもあります。FORTRAN 66における
文字列は、変数に格納することができないため、第一級オブジェクトではありません。
一方、Smalltalkでは、無名関数(ブロック)だけでなく、関数(メソッド)もクラスと同様に第一級オブジェクトとして扱われます。Smalltalkでは、演算子(`+`、`-`など)もメソッドで実現されているため、他のメソッドと同様に第一級オブジェクトです。
まとめ
多くの
プログラミング言語において、
整数や
浮動小数点数などの基本的なデータ型は第一級オブジェクトです。一方、歴史の古い言語や、C/
C++のように
機械語に近い設計思想を持つ言語では、
配列や
文字列は第一級オブジェクトではない場合があります。これらの言語では、
配列や
文字列を直接代入したり、関数に渡したりすることができず、要素ごとに個別に扱う必要がありました。これは、計算資源が限られ、コンパイラの最適化能力も低かった時代の制約によるもので、メモリの節約が重要だったためです。しかし、現代の
プログラミング言語では、より抽象度の高いデータ型も第一級オブジェクトとして扱われることが多くなっています。