- ダックタイピングに関して : (2012/05/08)
-
ダックタイピングって動的型付けが前提みたいな旨の話をちょくちょく見かけるけど、ダックタイピングの肝であるオブジェクトの継承関係を無視して呼び出し対象メソッドのシグネチャのみに注視するというのは静的型付け言語でも可能。
具体的には型情報をパラメータ化するような機能、つまり多相型や総称型を使えば良い。
C++
#include <iostream>
class Foo {
public : void f() const { std::cout << "foo!!\n"; }
};
class Bar {
public : void f() const { std::cout << "bar!!\n"; }
};
template <typename T>
void f(T& obj) {
obj.f();
}
int main () {
Foo foo;
Bar bar;
f(foo);
f(bar);
return 0;
}
OCaml
class foo_class =
object (self)
method f = print_string ("foo!!\n")
end;;
class bar_class =
object (self)
method f = print_string ("bar!!\n")
end;;
let f : 't -> unit = (fun obj ->
obj#f
)
let foo = (new foo_class);;
let bar = (new bar_class);;
(f foo);;
(f bar);;
C++の例と対応させるため、また多相型を強調するために型変数を明示しているが、実際には省略しても型推論がしっかり解決してくれる。
さらにOCamlにはfunctorというモジュール同士を合成して新たなモジュールを作る機能がある。
これはモジュール(名前空間)をパラメータ化することで実現しているんだけど、これを利用すると名前空間を対象としたダックタイピング的なことも可能になる。
これらの例は動的型付け言語の場合と異なり、対象メソッドのシグネチャのチェックがコンパイル時点で静的に解決されるため、動的型付け言語よりも安全なダックタイピング的なことが可能になるが、厳密にこれらがダックタイピングと呼べるのかどうかは結局わからなかった。
もし静的に型情報が解決された場合ダックタイピングの定義から外れるとしたら、それは考案者が危険なプログラミングに対する皮肉を多分に含んだ概念として、ダックタイピングを提案してたということなんじゃないかと思った。