Journal InTime


2007-07-10 (Tue)

_ [言語] A Theory of Objects読書会

A Theory of Objects (Monographs in Computer Science)(Martin Abadi/Luca Cardelli)

松江オープンソースラボでA Theory of Objectsの読書会。 といっても、Aさんとまつもとさんと私の3人だけだけど。

Reviewの"2. Class-Based Languages"までAさんに解説してもらったけど、Reviewまでは何とかついていけそう。 Part I以降は式ばっかりでコードが出て来ないのでつらそうだな。

covariance/contravariance/invarianceについて、ある型について

  • getのみだったらcovariance
  • setのみだったらcontravariance
  • get/set両方あったらinvariance

という整理はすっきりしていると思った。

だからメソッドの場合は、戻り値についてはcovarianceを、引数についてはcontravarianceを適用する(つまりSather方式)のが、型システムの安全性を考えると一番自然である。

あとで思い出したけど、Javaの配列型はget/set両方あるのにcovariantなので(本当はinvariantであるべき)型安全性が破綻しているんだな。 配列型で型安全性が破綻していること自体はずっと前に気付いてたんだけど、理論的に整理されてすっきりした。今まで感覚的にsubtype is-a supertypeであるためには…と考えてたんだけど。

この話をパラメタ付型(generic type)に一般化すると、ある型パラメタについて、型パラメタがgetにしか使われない(メソッドの戻り値にしか現れない)ならcovariant、setにしか使われない(メソッドの引数(正確にはin引数)にしか現れない)ならcontravariant、get/set両方ならinvariantであるべきということなんじゃないだろうか。 Reviewをざっと眺めたところではそういう話はなかったけど、後の方で出て来るのかな。 実際にはinvariantな言語が多い気がするけど、そういう言語ってあったっけ。

あと、Betaのinner(superの逆)も面白そう。CLOSのメソッドコンビネーションのaroundみたいな使い方になるらしい。でも単一継承だと(mixinできないので)設計が難しそうだな。

何はともあれ、今回の勉強会が今までの勉強会で一番ラボっぽかった気がする。 次回は7/24(火)なので参加したい人がいたら私に連絡ください。 ついてくのはしんどいと思いますが。

本日のツッコミ(全1件) [ツッコミを入れる]
_ みずしま (2007-07-13 (Fri) 18:21)

> そういう言語ってあったっけ。
Java Genericsでは型のユーザがvarianceを指定できるように
なっています。

(1) invariant
普通のgenericな型はinvariantです。
List<Number> ints = new ArrayList<Integer>(); // NG

(2) covariant
型パラメータを? extends Tという形で記述することによって、
covariantな型になります。

List<Integer> ints = new ArrayList<Integer>();
ints.add(1);
List<? extends Number> nums = ints; // OK
nums.add(2); // NG
nums.add(null); // これはOK. nullはあらゆる型のサブタイプとみなせる
Number n = nums.get(0); // OK

(3) contravariant
型パラメータを? super Tという形で記述することによって、
contravariantな型になります。

List<Object> objs = new ArrayList<Integer>();
objs.add(1);
List<? super Number> nums = ints; // OK
nums.add(2); // OK
Number n = nums.get(0); // NG
Object o = nums.get(0); // 型パラメタに記述できる型はObjectのサブタイプであることが保証されているので、これはOK

本日のリンク元