オーバーロードあれこれ

例えば、o * dとd * oが全く別の意味をあらわすことはありうる。これが掛け算ならば良いけれど、たとえば除算であれば順序を変えることが大きな意味をもつだろう。順序を変えることで型が変わることも想定しなくてはならない。
そうなると、一律にa * bという演算であれば、この演算はaの所属するクラスやら型の部分に記述する、もしくはbの側に記述する、というようなことが考えられる。っていうか普通の考えとしてはそうなのだろう。
しかし、それはそれで問題が発生する。o * dはそれでいいとして、d * oに別の意味を持たせたい場合にはどうするのだろうか。Primitiveであるdの型定義周辺をいじるのだろうか?たとえばRubyにはそういう機構があるけれど、本当にそれって大丈夫なのだろうか。
では、a * bの演算をaの型定義でもbの型定義でもどちらでもかけるようにしたらどうだろうか?それも問題で、両方に記述された場合などはもうどこにバグがあるのか探せなくなる。少なくとも探しにくくなる。また、優先順序などを決めるわけだが、はっきり言ってわけがわからない言語仕様になること間違いない。
それならば仕方がない。aの型定義ともbの型定義とも違うところ、トップレベルのどこかに記述できるとした場合はどうなるのだろうか。そうすると、型定義は必ずトップレベルでなければできないことになる(JavaのInnerクラスなどが作れないことになる)が、まあそれは良いとして、そもそもそれってどこに書けばよいのだろうか。やはりぐちゃぐちゃにならないだろうか。その演算が既に定義されているとして、どこを探せばよいのだろう?
根本的な話として、演算子オーバーロードを認めないという手法もある。まさしくJavaの取っている手法だが、演算子オーバーロードを害悪としてみなすということだ。かなり不評もあるみたいだけれど、ある程度しっかりはしているような気がする。

うーん、どうすべきなのかなあ。