オブジェクトは OCaml の鬼子 #2

ちょと長いんで、コメントじゃなくて、トラックバックにします。
http://d.hatena.ne.jp/syd_syd/20080907/p1

camlimagesでは使われているけれど、これがひょっとして苦い経験だったりするんでしょうか。それとも成功例?

camlimages、、、そんなのもありましたね(笑)。あれはまず、非OOのライブラリを書いた上で、OOのラッパを作りました。OOでにっちもさっちも行かなくなったら、非OOにいつでも戻れますよ、という感じ。しかし、あのOOレイヤも苦労したんですよ、3回位書き直したかな?どうも自分にはOO脳がないようです。

o#m というバグを引き起こすメソッド呼び出しがあったとして、ではバグを起こすメソッド m はいったいどこで定義されているのか、o の型を見ても何も語ってくれません。

これって高階関数でも同じじゃないですかねえ。 バグを引き起こす doit : unit -> unit みたいな関数があったとして、それが定義されている場所を探すのって データフローを追いまくらないと無理じゃないの…みたいな。 オブジェクトは何ら静的解析をしやすくするわけではない、という意味ではそうかもしれないと思う…とその道のプロに私が何を言ってもという感じですが

その道のプロになるのを止めたので、気軽に はてな に書き出しましたよ。
高階関数にも同じ問題があるのは御指摘の通りで、関数ポインタとか、高階関数とかなければ、プログラムの静的解析はもっと楽になりますね。もちろんプログラムを書く人がしんどくなるけれど。
o#m で私が指摘したかったのは、o#m が必要以上に高階かもしれない、ということです。言い替えれば、もしこれがOOで書いてなかったとすれば、大体の場合、実は M.m o (o は単相のレコード) と書けてしまって、関数の正体がすぐ判っちゃう。

プログラムの抽象度の高さと、静的解析性は、大体反比例するんだけど、結局はトレードオフで、どこまで使うか、ということになりますね。あまりそれを意識せずに「時代は OO ですよ」*1って OCaml で OO に突入しちゃうと、OOで得られる恩恵より、デメリットの方が大きくなっちゃって、はまっちゃう罠。でも、あまりそこんとこちゃんと指摘されてなかったみたいなので、指摘してみました。

ちなみに、多相レコードの双対概念である多相バリアント(polymorphic variant, `Hoge とか)ですが、これはよく使ってます。こいつもエラーメッセージがわかりにくくなるというデメリットがあるけれども、オブジェクトよりはまだ扱い易い。多相バリアントのタグの実装はなかなかhackyですが、そのおかげで単相バリアント(None, Some v とか)と似たような内部表現だから、オーバヘッドもほとんどないのがよいですね。こいつの subtyping を使って phantom type とか作ると色々便利です。

*1:いつの時代だよ