yhara.jp

Recent Posts

FGJを読む(2)

2016-10-25
Tech

ということで3章から読んでいきます。URL等は第一回を参照してください。

3. FEATHERWEIGHT GJ

FGJのサンプルプログラムがあります。コメントを足しつつ転記します。

// 2つのオブジェクトの組
class Pair<X extends Object, Y extends Object> extends Object {
  X fst; // フィールド定義
  Y snd;
  // コンストラクタ
  Pair(X fst, Y snd) { super(); this.fst = fst; this.snd = snd }
  // インスタンスメソッドsetfst
  // 引数を第一要素とする新しいペアを返す
  <Z extends Object> Pair<Z, Y> setfst(Z newfst) {
    return new Pair<Z, Y>(newfst, this.snd);
  }
}
// クラスAとBがあるとします
class A extends Object{ A() { super(); }}
class B extends Object{ B() { super(); }}

// メイン部分 (FJではメインプログラムをソースコード末尾に書きます)
new Pair<A, B>(new A(), new B()).setfst<B>(new B());

言語仕様の簡略化のためクラス定義時のextendsが省略できない、とかはFJと同じです。型パラメータ定義時のextends Objectも省略できないのでちょっとうるさい感じになっていますが、それはおいといて、「クラスもメソッドも型パラメータを持てる」ということの例のようです。クラスPairはXとYが型パラメータ、メソッドsetfstはZが型パラメータです。

それぞれの型パラメータは上界(bound)を持ちます。extends Objectというのが上界の指定ですね。

クラスAとBは型パラメータを持ちませんが、これらは0個の型パラメータを持つと考えることができます(あえて書くならA<>, B<>)。

GJとの違い

上のメインではsetfstメソッドを呼ぶときに型パラメータ<B>を明示しています。

new Pair<A, B>(new A(), new B()).setfst<B>(new B());

が、FeatherweightじゃないほうのGJではこの<B>は省略できます。自動で推論されるということですね。省略できるというか、必ず省略しなければならない(上のように書くことはできない)ので、FGJはFJの厳密なサブセットにはなっていません。型パラメータの推論は重要だけど、この論文ではGJのそれ以外の側面に注力したとのことです。

型パラメータの上界について

型変数の上界についていくつかのことが書かれています。

  • 上界は型変数であってはいけない (<X extends Y>みたいのはだめ、ということかな)
  • が、型変数を含む型式ならOK (<X extends Array<Y>> とかですかね)
  • 再帰的な定義も許される
    • <X extends Array<X>> はOK
  • 相互再帰も許される
    • <X extends Array<Y>, Y extends Array<X>> はOK

いやあ、こんな変なケースのことは全然考えてなかったですね…。これらのケースの具体例がGJの論文にあるそうですが、それはまた次回。

More posts

Posts

(more...)

Articles

(more...)

Category

Ads

About

About the author