多重ディスパッチ(マルチメソッド)について

でも最初は「すげー」と思ったけどどういうときに役に立つんだろう。すべての基底クラス的なオブジェクトがあれば(仮にObjとする)、(defmethod method((x Obj) (y Foo) ...)で「レシーバが何かにかかわらず引数yがFooなら同じ処理」ってのができるわけなのだけど、それってFooのメソッドにすべきな気がするし。

カウンタを作った - 西尾泰和のはてなダイアリー

たとえば、Wikipediaの例なんてどうでしょ。多重ディスパッチ - Wikipedia

あと、CLOS系の多重ディスパッチの嬉しいところは、実行時に型をみてディスパッチしてくれるところらしいす。実際に使ったことない、というかHaskell Hackathonで使おうとして時間切れになった。細かい議論は下記のLingrのログがくわしい。

http://www.lingr.com/room/parsing/archives/2007/11/07#msg-17832175

たとえば、Fooというクラスを継承した2つのクラスBarがあるとして、次のようなJavaっぽい疑似コードをかんがえる。

void hoge(Foo foo){ println("Foo!"); } // hoge1
void hoge(Bar bar){ println("Bar!"); } // hoge2
...
Bar bar_bar = new Bar();
Foo foo_bar = new Bar();
hoge(bar_bar); // hoge2がよばれる
hoge(foo_bar); // hoge1がよばれる

Javaの場合、コンパイル時に型をみてディスパッチするので、hoge(foo_bar)はhoge1が呼びだされる。しかし、foo_barの中身は実行時にはBarのインスタンスなのだから、hoge2がよびだされるとうれしい。CLOSの多重ディスパッチの場合、そもそも型宣言がないので実行時にオブジェクトを見て、ディスパッチする先を決めてくれるから、hoge2に相当するメソッドを呼びだせる、らしい(入れ知恵)。

実際に役立つ場面としては、構文木をあつかうときとかですかね。Cとかだと、typeとかいうメンバを構造体にもたせて、それをswitchなんてことをしたりするけど、CLOSではそのtypeの情報をクラス自身に持たせることができる。Exprというクラスを継承する OperatorExpr, FuncallExpr とかがあって、それぞれに対してメソッドを定義しておけばswitchを長々とかかなくてもよい。

なんかすごい適当な知識で適当にかいたので、つっこみ希望。