vieweditattachhistoryswikistopchangessearchhelp

総称関数

Generic Function

CLOSにおいてはメソッドはクラスに従属するものではなく、引数の型(≒クラス)の組み合わせごとに定義されるおのおのの関数のあつまりを総称するもの、といえる。

(method arg1 arg2) という式の場合、メソッド名 method として定義された関数のグループの中から arg1 と arg2 の型が定義と一致する関数が実行される。--SHIMADA

マルチプルディスパッチと同義かな? --戯

マルチプルディスパッチは総称関数とかを裏で支える機構のことですね。
「総称関数」というときは必ずしも複数の引数によるディスパッチとは限らず、とりあえず関数に多態性をまかせておいたやつです。CLOSではメソッドはクラスに属するのではなく、総称関数に属します。そういう関数のことです。
一方、「マルチメソッド」とか「多重メソッド」というときはまさに複数の引数の型でディスパッチされるメソッドということになります。--やまねこ

Dylanメソッドディスパッチもこれに影響を受けて作られた手法(そのもの?)ですよね。 --sumim

某システム(笑)には、総称関数ほど強力じゃないがそれなりに面白い、「selfの複数形(?)化」という機能が有る。配列(のようなもの)に複数Objectを詰めて、selfの替わりにこの配列へ(予めこの配列対応なように作ってある)メッセージを投げると、selfたち(笑)の共通クラス(なインスタンス)たちへのメッセージと見なされる(ことも出来る)というもの。マウスで複数Objectを選択してMethod呼んだときの挙動を表現する1手段。

複数選択したときの挙動としては、Method呼べなくする、単数形Methodを個々のObjectに順に呼ぶ、複数形Methodを呼ぶ、という3通りの挙動が選択可能。
--戯



MartinFowlerBloki「クラス図におけるローカル変数」に、
「あるオブジェクトがローカルに他のクラスのインスタンスを保有しているtとき、それは依存を表しています。」
という表現があるが(そして「素朴に」考えればそれに賛同できるが)、
少し考えると、これは微妙に妙だ。

ローカル変数がオブジェクトを持つとき、それを「あるオブジェクト(selfのことでしょうね)が保有してる」
と言い切っていいのだろうか?

総称関数方式じゃない(大抵の?)OOP言語では、メソッドは1つのselfとか呼ばれる主役オブジェクト(のクラス)の所有物である、と
捉えられているが、 総称関数の存在はこの捉え方に対してちょっとした警鐘を鳴らしているのではなかろうか。

というのは、メソッドというものは(恐らく大抵は)
どう見ても selfおよびそれ以外の引数のオブジェクトたちの「コラボレーション」(の台本)なのだ。
そして、それらの中の1つだけをselfつまり主役と呼び、残りを脇役と呼ぶのは、恣意に基づいている。
どのキャラの一人称で記述された台本か?が違うだけで、起きる事象は同じ、という異本は、なんぼでも(?)書けてしまう。

つまりだ。ローカル変数に保有されたオブジェクトが、
主役に依存してるのか、自分以外の脇役に依存してるのか、その他大勢の群集に依存してるのか、は
(その処理の内容を読まないと)一概にどうとは言い切れないのではないか?と。

#なお、依存の関係は逆向きかも知れないが、それでも「依存が存在する場所」の議論としては同じことだし、
#「依存の矢印の向き」という新たな謎が増えた(可能性の数は2倍になった)だけである。 --戯


マルチプルディスパッチについて非常に鋭いところをついてますね。

selfは日常的にもmeだけじゃなくてusだったりもします。縦割り行政な役所でたらい回しにされたとき感じる不満は、適切なかたまりがメソッドを持っていなかったときと同じでしょう。相手にしたいオブジェクト群の中のひとつひとつに対して細かい指示を出してようやく達成できる仕事があったとして、それをオブジェクト群の外に放り出した記述のままにせず、関係するオブジェクト群に結びつけた適切なメソッドとして仕立て上げることがOOPです。

しかし関係するオブジェクト群があっても、実体として何かのかたまりがあるとは限りません。それでも一般的なOOP言語は必ずオブジェクトの実体にもとづいてメソッドを用意します。一方、CLOSは最初から実体の主体性をあてにせず、関数主体でOOPのメカニズムを実現しました。また、SlateのようなPMDを実装した言語では実体にメソッドを結びつけるけれども、それは単一の実体にだけ結びつくとは限らないというメカニズムを持っています。

いずれにしても、オブジェクトはインターフェイス(とりあえずドキュメントに示すだけのものでもいい)を持つべきです。じゃなかったらオブジェクト群の「インタラクション」は明示されず、もっと混沌としたプログラムになるでしょう。

ところで、インタラクションとかコラボレーションとかいっても所詮はプログラムですから、すべて予測通りに動いてほしいわけです。つまり最初から「やらせ」なわけです。でもプログラマはプログラムを変更するかもしれない。だから、プログラマにとって「インタラクション」というのはプログラミング過程のすべてを含めてこそ出てくる発想なのです。プログラムの実行時のことはどうせ「やらせ」なんだから、どんなやりかたでやろうと結果が同じならかまわないということになるでしょう。

このこともまたインターフェイスを設計する動機になります。特に多態性はうまく設計すればプログラムの拡張性をかなり大きくします。
しかし、CLOSにはObjective-Cのプロトコルのようなものがありません。そのほうがLispらしいともいえるけれども、オブジェクト群の実体とメソッドとの距離が遠くなった分、プロトコルの必要性が大きくなったように思います。
まぁ、クラスにメソッドが属するわけじゃないのならプロトコルはどうなるの?という素朴な疑問もあるでしょうが・・・逆に、そこらへんを徹底して考え直してみることで、「オブジェクト群」がいかに記述されるべきかが見えてくるでしょう。そのときこそが「やらせ」臭さが抜けるときです。
(などと、すでに答えをすべて見抜いたかのように書いているが、まだ研究中^^;)--やまねこ

このページを編集 (5267 bytes)


Congratulations! 以下の 11 ページから参照されています。

This page has been visited 9023 times.