言語ゲーム

とあるエンジニアが嘘ばかり書く日記

Twitter: @propella

なぜ結合法則が重要なのか?

やっと、自分の中で結合法則の重要性に納得して嬉しいので、うっとおしいかも知れないけど書きます。結合法則というのは、例えば Squeak で言うとこういう事です。

"整数"
((3 + 4) + 5) = (3 + (4 + 5))

"分数"
((3/4 + 4) + 5) = (3/4 + (4 + 5))

"複素数"
((3 + 4i + 4) + 5) = (3 + 4i + (4 + 5))

"配列"
((#(3 4 5) + 4) + 5) = (#(3 4 5) + (4 + 5))

"座標"
(((3@4) + 4) + 5) = ((3@4)+ (4 + 5))

"文字列"
(('3 apples' + 4) + 5) = ('3 apples'+ (4 + 5))

整数はともかく、複素数とか、配列とか、座標とかに + が使えるのは珍しいでしょう。+ がオーバーライド出来る Smalltalk ならではです。ここで重要なのは、どれも ( (3 + 4) + 5) = (3 + (4 + 5) ) のように計算の順序を変えても答えが同じ事です。これを結合法則と言います。Squeak の事ですから多分ただの偶然だと思いますが、それにしても重要な事です。

なぜかと言うと、最適化のために 3 + (4 + 5) のように、4 + 5 を先に計算しておいて、頭にどんな数字が来てもさっと計算したいという事がよくあるからです。というか、最適化というのは結局メモリと計算の順序あれこれいじる以外方法が無いわけで、逆に結合法則の効かない計算は最適化のしようが無いという話になります。

Squeak の例のように、オブジェクトの構造がどれだけ違っても結合法則が成り立つというのは非常に面白い特徴で、内容に関係なく外部の構造に着目する事を構造主義と言います。原住民の社会の数学的構造が解明された!というあれです。でも関係無い話なので省略します。

ふと思ったのが、必ずどんなメソッドでも結合法則を満たすようにクラスライブラリを設計すれば、SmalltalkRuby のようなレイジーバインディングな言語でもソースレベルの機械的な最適化が出来るのでは??という事です。これこそ Haskellモナドそのものですが、そうとばれないように密かに調べたいと思います。