Oh 脳《140》続々・Java の常識は OOP の非常識

記事一覧Oh 脳: after ZERO《其之佰肆拾》

続々・Java の常識は OOP の非常識
将来(生涯)プログラマーを目指すなら

《監修》小泉ひよ子とタマゴ倶楽部
第0版♪2009/11/30

セミナーの枕で紹介した小ネタ集です。息抜きや話題作りにどうぞ (^.^)

純粋な OOP の世界では、

  • (1) a < b (2) b > a

が同じ結果になる保証はありません。そのため、
これらを演算子ではなく「メッセージ」として実現するときには注意が必要です。


ライブラリーを利用する SE と、それを提供するプログラマーとでは、
それぞれに立場も違うので、一概には言えませんが、
将来(生涯)プログラマーを目指すみなさんは、
利用者(SE)が意識する必要もない、その深層に至る理解が必須になります。


... zap ...
伝統的なプログラミングの世界では、
演算子が「主」たる存在であり、被演算子はその名に象徴されるように「従」でした。
OOP の世界では「主従」関係が逆転して、
オブジェクト(被演算子)が「主」たる存在であり、演算子は「従」になります。
そのため「演算子」という着想から脱却して、
「メッセージ」の意義を理解することが、OOP への第一歩になります。


純粋な OOP の世界では、すべてを統一した概念モデルで記述できる利点とは裏腹に、
ときに、Java/C# などハイブリッド型 OOP の常識が通用しない場面で混乱を招きます。


「夜になると暗くなるのは何故か」の逸話が象徴するように、
ともすると、限られた経験の中だけで、その世界観を描いてしまいがちです。


太陽系の外(宇宙全体)に目を向けるまでもなく、
「月火水木金土」と順に探ってみるだけでも、
「夜になると暗くなる」という地球の「常識」が通用しないことから、
むしろ自分たちは少数派であり「非常識」が日常になっていることに気付きます。


Java では、演算子オーバーロードを認めていないので、
無縁の世界と思われがちですが、演算子 + がその典型で、
整数、実数、そして文字列と、実質的に「演算子の多義性」を認めています。
ただし、その権利をプログラマーには開放していないので、
C# とは違って、Java のアンフェアな部分が露呈します。


C# では、一歩踏み出して、この問題解決を図るフレームワークを提供して、
そこにプログラマーが介入する権利を認めているので、
Java とは違って、C# のフェアな姿勢が垣間見えます。
Python では、さらに一歩踏み出して、
ちょうど、演算子とメッセージとの中庸といった感じになります。


演算子オーバーロード」という着想こそが、
未だに、演算子を「主」たる存在と見なしている証であり、
OOP を理解するときに、最初に越えなければならない壁のひとつでもあり、
そこには「天動説 vs. 地動説」に象徴される、コペルニクス的転回が必要です。


※ 詳細は、以下を参照してください。
http://d.hatena.ne.jp/kotsubu-chan/20020113#Vector


ただし、C#, Python では、フレームワーク「自身」に介入したくても、
その権利をプログラマーには開放していないので、
Smalltalk とは違って、そこにアンフェアな部分が見え隠れします。


Smalltalk では、自由に介入する権利が与えられる代わりに、自己責任が問われます。
つまり (1)(2) が同じ結果になるかどうかは、プログラマーの裁量に委ねられます。
逆に (1)(2) が等価でない世界観を実現したいときには、この機能が必須になります。


... zap ...
ところで「日月火水木金土」を同列に描こうとした背景には、
恒星/惑星/衛星という区別がない時代の世界観が垣間見えます。


世界史の教科書には「アメリカ大陸発見」と記述されていますが、
コロンブスが発見する前から、その大陸は存在していたわけで、
西欧を中心に据えた「世界観」に支配されていたことが分かります。
ときに、コロンブス自身は、そこをインドだと認識していたことから、
広大なアメリカ大陸ですら存在しない狭い世界観で、
世界を一周したという充実感に浸ったものと想像できます。
また、世界地図を描くときも、北を上に向けるという慣例からは、
北半球を中心に据えた「世界観」に支配されていたことが分かります。


過去の歴史から学べるように、
Java/C#OOP を学んだ人にありがちな落とし穴のひとつが、
その言語で実現可能な限られた世界観で OOP を俯瞰してしまうことです。


... zap ...
純粋な OOP 言語である Smaltalk では、
「オブジェクトにメッセージを送る」という統一された概念モデルで、
すべての世界観を表現できるように工夫されています。
そのため、クラスやメソッドを定義するときも、
他のオブジェクトと同様に「オブジェクトにメッセージを送る」だけです。
そのため、class/def などの冗長な構文規則は不要になり、
すべてを統一した概念モデルで表現でき、その言語仕様は簡潔かつ強力です。


また「すべてがオブジェクト」なので、
first-class object をことさら強調する必要もないわけです。
ハイブリッド型 OOP 言語の典型である Java/C# で、
first-class object に言及するのは「すべてがオブジェクトではない」証です。
では、Ruby/Python が純粋な OOP 言語かというと、
Java/C# と比べて純度は高いものの、ときに不純な部分が見え隠れします。


私がよく、OOP 言語の「純度」を比較するメタファーとして、
Java/C#Ruby/Python、そして Smalltalk の違いを端的に説明するときに、
金メッキ、18K、24K の違い…とするのはそのためです。


... zap ...
Java/C# で表現できる限定された世界観から脱して、
広範な OOP の世界観を描けるようになるかは、受講者のみなさん次第です。

Last updated♪2009/12/01