プログラミング言語/プラットフォームで「ファーストクラスの市民」と見なされる機能はいつですか?


61

「この機能を言語/プラットフォームの第一級市民にしてください」のような声明を何度も見ました。たとえば、C#/。netの列挙型について言われています。それでは、いつ機能がプログラミング言語/プラットフォームで「ファーストクラスの市民」と見なされるのでしょうか。

回答:


40

定義

次の場合、オブジェクトはファーストクラスです。

  • 変数とデータ構造に保存できます
  • サブルーチンにパラメーターとして渡すことができます
  • サブルーチンの結果として返すことができます
  • 実行時に構築できます
  • 固有のIDを持っている(名前に依存しない)

「オブジェクト」という用語はここでは大まかに使用され、必ずしもオブジェクト指向プログラミングのオブジェクトを指すわけではありません。整数や浮動小数点数などの最も単純なスカラーデータ型は、ほとんど常にファーストクラスです。

http://en.wikipedia.org/wiki/First_class_object


1
では、何が.net / C#の2番目のクラスオブジェクトを列挙型にしているのでしょうか?
グルシャン

7
@Gulshan-固有のアイデンティティーの欠如を主張することができます-C#列挙型は、基本的に整数値の単なる構文上の砂糖(つまり「与えられた名前」)です。列挙型がそれ自体でオブジェクトであるJavaと比較してください。
ミケラ

.NET列挙型の@mikeraは、それ自体が値です。Javaには値がなく、オブジェクトだけがありますが、それが唯一の違いです。
SKロジック

@mikera:ただし、Javaの列挙型には、ビットフィールドを表すことができるなどの優れたプロパティがありません。実装はおそらくよりファーストクラスですが、ほとんどのAPIにはまだ多くの整数(または文字列)定数があり、それらの多くの用途は列挙型に簡単に置き換えることはできません。
ジョーイ

列挙型は実行時に.Netで構築できるとは思わないでしょうか?それらは常に定数だと思いました。
トラビス

33

プログラミング言語の「ファーストクラスの市民」または「ファーストクラスの要素」という概念は、1960年代にイギリスのコンピューター科学者Christopher Stracheyによってファーストクラスの機能のコンテキストで導入されました。この原理の最も有名な定式化は、おそらくジェラルド・ジェイ・サスマンとハリー・アベルソンによるコンピュータープログラムの構造と解釈にあります

  • 変数によって名前を付けることができます。
  • これらは、プロシージャへの引数として渡すことができます。
  • 手順の結果として返される場合があります。
  • それらはデータ構造に含まれる場合があります。

基本的に、このプログラミング言語要素を使用して、プログラミング言語の他のすべての要素で実行できるすべての操作を実行できることを意味します。

それはすべて「平等な権利」に関するものです。たとえば、整数を使用して上記のすべてを行うことができます。

上記の定義は、プログラムのオブジェクトであることに関連するファーストクラスの側面についてのみ実際に言及しているという意味で、少し制限されています。もっと一般的な定義は、もしあなたがそれですべてをすることができれば、あなたは同様の種類の他のものでもできるということはファーストクラスであるということです。

たとえば、Java演算子とJavaメソッドは似たようなものです。新しいメソッドを定義したり、独自のメソッドの名前を(ある程度)自由に選択したり、メソッドをオーバーライドしたり、メソッドをオーバーロードしたりできます。ジェームズゴスリングもオペレーターですべてを実行できますが、あなたと私はできません。私は、人気の信念に反し意味、Javaはありませんサポート演算子のオーバーロードを:たとえば、+オペレータがオーバーロードされbyteshortintlongfloatdoubleそしてStringまたのために、とIIRCは、Java 7にBigIntegerし、BigDecimal(そしておそらく、私は忘れてしまったカップルが)、それがあることだけだそれに影響を与えないでください。これは明らかに、この2番目の定義に従って演算子を2番目にクラスにします。ただし、最初の定義によると、メソッドは依然としてファーストクラスのオブジェクトではないことに注意してください。(それはオペレーターをサードクラスにしますか?)


6

通常、これはパラメーターとして渡すことができる構造体を指し、関数からの戻り値の型として定義するか、値を割り当てることができます。通常、実行時にそれらを構築できる必要があります。たとえば、クラスのインスタンスはc ++またはjavaのファーストクラスの市民ですが、Cの関数はそうではありません。


c ++でクラスをファーストクラスの市民にするものは何ですか?
ビャルケフロイントハンセン

2
@bjarkef:そのような音は、前の文で提供された説明と一致することですでに答えられました。
-doppelgreener

@ジョナサン:はい、申し訳ありませんが、「実行時にそれらを構築する」と読み間違えました。はい、実行時にクラスのインスタンス(オブジェクト)を構築できますが、クラス自体は構築できません。それは私を混乱させたものです。
Bjarkeフロイント・ハンセン

1
パラメータで渡すだけではまだ十分ではありません。C / C ++では、関数を2番目のクラスの市民と見なします。パラメータとして渡すことができ、他のオブジェクト内に配置された結果として返されます。ただし、他の構造の助けなしでは操作できません(パラメータを関数にバインドするにはstd :: bindなどが必要です)。
マーティンヨーク

@Martin関数がC / C ++の第一級市民であると言ったことは一度もありません。
ペムダス

1

言語のみで実装されている機能は、ファーストクラスの市民であると言えます。
すなわち、その機能を実装するために複数の言語機能または標準ライブラリを必要としません。

例:

C / C ++では、関数をファーストクラスの市民とは考えていません(他の人はそうかもしれません)。
これは、言語で直接サポートされているが、他の言語機能の使用を必要とする関数を操作する方法があるためです。関数へのパラメーターのバインドは直接サポートされていないため、この機能を実装するにはファンクターを作成する必要があります。


1
バインドされた関数(または「クロージャー」)がファーストクラスではないのに、関数自体はそうではありませんか?0xのクロージャのサポートは分析にどのように影響しますか?
フレッドナーク

@Fred Nurk:それはすべて言語に依存します。一部の言語では、クロージャーはファーストクラスのシステムです。他ではない。私はまだ明示的なコメントをするほどC ++ 0xに精通していません。
マーティンヨーク

あなたの答えのように、言語がCまたはC ++(0xではない)であるとしましょう。「ファーストクラス」の定義は、バインドされた関数(または「クロージャ」)をファーストクラスではなく、関数自体であるのではないでしょうか?
フレッドナーク

@Fred Nurk:関数でできることをそれらをクロージャーにすることだけに制限するなら、それは確かです。しかし、私にとっては、ライブラリをインポートすることによってのみプラットフォームで整数の加算がサポートされるかどうかを言っているようなものです。整数はファーストクラスの市民ですが、整数の追加は考慮されません。私のビューでは、クロージャーは、新しい関数を効果的に返す関数で実行できる操作です(ただし、定義方法によって異なります)。しかし、クロージャとバインディングは、議論から除外している他のいくつの操作にすぎません(それが疑問であったかどうかはわかりません)。
マーティンヨーク

@マーティン:私は自分自身を明確に説明してはいけません。「機能が言語のみで実装されている場合、機能はファーストクラスの市民」であるとすると、CとC ++の両方の関数は言語のみで実装されるため、ファーストクラスになります。バインドされた関数(「クロージャ」とも呼ばれる)は、バインドパラメータなどで話しているものですが、それは別の機能です。
フレッドナーク

-1

既に提供されている回答に例を追加するには:

WCF / C#では、現在、クラスオブジェクトをサービスコントラクト属性でマークして、サービスとして動作させる必要があります。次のようなものはありません。

public **service** MyService (in relation public **class** MyClass). 

クラスは、サービスがそうではないc#のファーストクラスの市民です。

お役に立てれば

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.