ATSプログラミング入門: | ||
---|---|---|
Prev | Chapter 17. ジェネリックスから遅延束縛へ |
オブジェクト指向プログラミング (OOP) の意味について聞かれたとき、アラン・ケイは彼にとっての OOP はメッセージ、状態プロセスの局所的な保持, 保護, 隠蔽と全てに対する極端な遅延束縛 (late-binding) であると答えました。
ATS では、関数テンプレートは (関数呼び出しの) 遅延束縛に高度に柔軟なアプローチを提供します。 はじめに、なぜ遅延束縛が魅力的なのか知るために、単純な例を見てみましょう。 次のコードは、整数もしくは (倍精度の) 浮動小数点数を表わすような型である、データ型 intfloat を宣言しています:
型 intfloat の値を印字するために、次のような print_intfloat を実装できます:// fun print_intfloat (x: intfloat): void = ( case+ x of | INT(int) => print_int(int) | FLOAT(float) => print_double(float) ) //
// fun fprint_intfloat ( x: intfloat , print_int: int -> void , print_double: double -> void ) : void = ( case+ x of | INT(int) => print_int(int) | FLOAT(float) => print_double(float) ) //
高階関数を使用する代わりに、テンプレート関数を使って (関数呼び出しの) 遅延束縛をサポートできます。 例えば、次のコードは型 intfloat の値を印字するテンプレート関数 tprint_intfloat を実装しています:
// extern fun{} tprint_int(int): void extern fun{} tprint_double(double): void extern fun{} tprint_intfloat(intfloat): void // (* ****** ****** *) // implement tprint_int<> (x) = print_int(x) implement tprint_double<> (x) = print_double(x) // (* ****** ****** *) // implement tprint_intfloat<> (x) = ( case+ x of | INT(int) => tprint_int<> (int) | FLOAT(float) => tprint_double<> (float) ) //
// val () = ( tprint_intfloat<> (INT(0)); print_newline() ) (* end of [val] *) // val () = ( tprint_intfloat<> (FLOAT(1.0)); print_newline() ) (* end of [val] *) //
local // implement tprint_int<> (x) = print! ("INT(", x, ")") implement tprint_double<> (x) = print! ("FLOAT(", x, ")") // in (* in-of-local *) // val () = ( tprint_intfloat<> (INT(0)); print_newline() ) (* end of [val] *) // val () = ( tprint_intfloat<> (FLOAT(1.0)); print_newline() ) (* end of [val] *) // end // end of [local]
この章で紹介したコード全体とテストコードを含む intfloat.dats ファイルはオンラインから入手できます。