15

「型とプログラミング言語」を読んで、クロージャーとレコードのサブタイピングを使用したオブジェクトの実装に感銘を受けました (第 18 章)。OCaml がレコードのサブタイピングをサポートしていない特別な理由はありますか (オブジェクトがサポートしていることは知っています)? 実際、これをサポートする言語は見つかりません。

4

2 に答える 2

23

技術的には、OCaml のオブジェクトは、通常の意味でのサブタイピングを実際にはサポートしていませんが、行のポリモーフィズムをサポートしています。行ポリモーフィズムには、サブタイピングよりも多くの利点があります。特に、表現力が高く、型推論でうまく機能します (サブタイピングと型推論はまったくうまく混ざりません)。

すべてのレコードに対して構造的サブタイピングまたは行ポリモーフィズムを使用する場合の主な問題は、非常に複雑なランタイム実装が必要であり、その結果、コストも高くなることです。単純なレコードは単純なタプルに簡単に変換できますが、フィールド アクセスは単なるインデックス付けであり、構造的サブタイピングまたは行ポリモーフィズムでは、オブジェクトを透過的に「スライス」する機能、つまり、ランダムなフィールドが削除されたスーパータイプでオブジェクトを表示する機能が必要です。一般に、これには、ハッシュによるフィールド ルックアップ (Ocaml のオブジェクトなど) か、関数またはその呼び出し先のいずれかによって使用されるすべてのフィールドのインデックスを、実際の引数に加えて隠し引数として渡す必要がある証拠渡し技術が必要です。レコード (たとえば、SML# が行っていること) です。

いずれにせよ、Ocamlにはポリモーフィック レコードがあり、それらは単にオブジェクトと呼ばれます。ただし、不要な場合は、それらの周りのすべてのクラスの混乱を無視できます。

于 2013-03-06T07:11:38.643 に答える
9

レコードのサブタイピングは、タイピングの観点から非常に危険です。

a、b、c の 3 つのフィールドを持つレコードがあるとします。そして、a と c の 2 つのフィールドだけを持つレコードを作成したいとします。コンパイラは、レコード全体の読み取りが完了するまで、使用している型を認識しません。最後に、間違いを犯した場合、たとえば b フィールドを忘れた場合は役に立ちません。

この観点が異論の余地があることには完全に同意しますが、それが ocaml を書いている人々の考え方だと思います。

于 2013-03-06T07:03:56.450 に答える