オブジェクト指向の概念の発明者は誰ですか?(改訂版)

忙しい人のためのまとめ

  • 一般に「オブジェクト指向プログラミング」と呼ばれる考え方には発案者が異なる二系統がある。(ただし簡単のため、次のうち前者から批判的に派生して生じたプロトタイプベースのオブジェクト指向はここには含めていない)
    • アラン・ケイによる、変化に強い長期運用可能な遅延結合システムを SIMULA67 にあった「オブジェクト」をメッセージの受け手とすることで実現(オブジェクトにメッセージ送信)するアイデアに基づく「メッセージングのオブジェクト指向」と、
    • ビアルネ・ストラウストラップ(前後して抽象データ型を発案したリスコフ本人、オブジェクトクラスを考えたニガードらSIMULA陣営、Eiffelのメイヤーらも同様の着想を得ている)による、ユーザー定義型(抽象データ型)を SIMULA67 にあった「クラス」という言語機能を使って実現(カプセル化、継承、多態性)するアイデアに基づく「抽象データ型のオブジェクト指向」。
  • この二つの「オブジェクト指向」は、オブジェクト指向という呼称、「クラス」や「オブジェクト」といった SIMULA67 由来の言語機能を共に使用してはいるものの、考え方の方向性が全く異なっており本来きちんと区別すべきものである。
    • もちろん SIMULA67 でも、前二者のオブジェクト指向を(限定的ながら)実践することは可能だが、SIMULA67 をもって「初のオブジェクト指向言語」としてしまうのは(ニガードやダールがまるで「オブジェクト指向」を考案したり「クラス」や「オブジェクト」をそのために設けたかのような)誤解や混乱を与える可能性があるので控えるべき。
  • 残念ながら、教科書的な記述の多くはこれら二つを書き手に都合のよい解釈でごちゃまぜにしてしまっており、しばしば学習者に対して無用な混乱を生じさせている。
  • 「クラス」や「オブジェクト」といった言語機能を備えたいわゆる「オブジェクト指向言語」はこれら二系統のどちらかを比較的厚くサポートすることが多いが、完全にはサポートできてはいない(SmalltalkC++ も例外ではないことに注意)。また、たいていはどちらかに重きをおきつつつ双方を不完全ながらサポートする言語が多いため、ユーザー(この場合、プログラマー。為念)がまず先に概念を理解しどちらの考え方でプログラミングをするかを決めないと機能の間違った使い方になってしまう。
  • 同じ理由で、オブジェクト指向という概念を特定の言語の(俗に「オブジェクト指向」向けと称される)機能から外挿して学ぶのは難しいし、間違った「オブジェクト指向」を創造してしまう危険がある。少し遠回りに思えても、それぞれの考案者自らがその主張を綴った論文を読んで理解を試みるほうがいい。


ああ…、こんなおあつらえ向きの質問が、しかも はてなにあったのに、気がつかなかった…。orz もはや回答は締め切られているので、ここにメモ。


ひと言でいうと、たしかに「オブジェクト指向」を考え出したのはアラン・ケイ。でも、そう言い切っておしまいにするには、ちょっと(いや、かなり…)問題があります。


というのも、「オブジェクト指向」は「オブジェクト指向プログラミング」の意味に限っても、現在まで、少なめに見積もった場合でも3つ(ここでは取り上げていない比較的新しめの「プロトタイプベースのオブジェクト指向」を含めて。単にオブジェクトとクラスを使ったプログラミング…という論外なのを含めれば4つ以上)の違った切り口を持つようになってきているからです。

ここでは説明者が意識しながらも、ほとんど区別されることがなく、混乱の元にになっている2つの「オブジェクト指向」の紹介します。

  1. “メッセージングによる可能な限り動的な処理・実装・設計”(メッセージ指向とも)
  2. “抽象データ型のスーパーセット”“継承によるプログラミング”(クラス指向とも)

▼ケイの「メッセージングの」オブジェクト指向

アラン・ケイが 1970年代初頭までに考え出し、暫定ダイナブック環境である Smalltalk システムで実践、そこで用いることができる Smalltalk 言語にサポートさせようとしたのは“1”の「オブジェクト指向」です。(この考え方はプログラミングのみならず、今でいうところの設計、分析のようなものも含みます) 「メッセージ指向」というのは、ケイ自身は覚えていないようですが、彼の共著の論文で使われている表現です(もしかしたら、共著者のアデル・ゴールドバーグが用いたのかも…)。

端的にはコンピューティングに関わるすべてを「“オブジェクト”と、それに対する“メッセージ送信”で表現すべし」というドグマにより成り立たせようとする世界観で、そこで目指すべきイメージとしては、高速のネットワークで接続された小さな(しかし万能の)計算機の挙動にたとえられます。また、生命科学における細胞の営み、哲学でいえばライプニッツモナド論に通じるところもあります。ちなみに、ケイのこの考え方にインスパイアされて提案されたのがカール・ヒューイットの「アクターモデル」。(逆なのでは?と思う人は こちらを

誤った傾向として、よく、「すべてがオブジェクト」であることのみが強調されがちですが、この文脈における「オブジェクト指向」で重要なのはむしろ“メッセージング”のほうです。クラスはおろか、オブジェクトですら飾りに過ぎません。偉い人にもそれがわかっとらん人がけっこう多いのです。w


なお、このケイのメッセージングのオブジェクト指向を学ぶのに Smalltalk が役に立つことはありますが、だからといって Smalltalk がその考え方をまるごと体現できているわけではないので、けっして「ケイの」を「Smalltalk の」と言い換えてはいけません。念のため。


▼ストラウストラップの「ユーザー定義型の」オブジェクト指向

しかし、現在「オブジェクト指向」を説明する人が(たいていは意識せずに)前提としているのは、C++ の設計者として知られるビアルネ・ストラウストラップが、C++ の設計を通じて 1980年代半ばまでに体系付けた“2”の「オブジェクト指向」です。カプセル化/情報隠蔽、継承、多態性…とかのいわゆる「三点セット」は、おそらくここで言われる「抽象データ型 + 継承と仮想関数による動的性(つまるところ「クラス」の機能)」が変形させられたものだと思って間違いないでしょう。(これ以前に発表された論文で、三点を網羅したものは見あたらないので…)

端的には、「抽象データ型(ユーザー定義のデータ型)」を実現するのに「(SIMULA の)クラス」を用いる…という考え方なので、クラスは必須です。また、主だっては「データ型」を定義する作業をするわけですから、プログラミング言語におけるデータ型の役割、それをユーザーが定義できることのメリットを把握していないと、会得したぞ!感やシアワセ感がいまひとつ薄くなると思います。逆に、データ型を定義するだけなら C 言語でもできる(工夫や解釈次第で継承や動的性実現も…)わけなので、そんなことにわざわざ言語機能のサポートなんぞ期待しない…と言い切れるスキルを有する人にとって、この「オブジェクト指向」の存在価値は皆無と言えましょう。

なお、この文脈の「オブジェクト指向」において、メッセージングはぜんぜん関係ない無用のもの and/or 動的性実現のための(仮想関数より効率の悪い)実装のひとつに過ぎない…ということを強く意識する必要があります。ケイの影響で「オブジェクト指向=メッセージ」と脳に染みついている人には酷かもしれませんが、いっそ排除して考えたほうがすっきりしますし、可能な限りそうすべきです。しがらみのない初学者へのレクチャーに際しては、ぜひとも「オブジェクトにメッセージを送って…」とか「世の中のあらゆるものを(ry」なんて説明は後々無用な混乱を招くだけなので、やめて欲しいと思います。まずは“データ型”とは何か?という議論からはじめるべきでしょう。(そのデータ型で、あえて、犬、猫、牛、鳥…をどーしても表現したいのであれば、止める理由はありませんが…(^_^;))


あと、「ケイの」を「Smalltalk の」と言い換えてはいけないのと同様に、「ストラウストラップの」を「C++ の」とは置き換えない方がいいと思います。後にも述べましたが、C++ がマルチパラダイムを目指した言語ということもありますし。


まあとにかく、あるアイデアの発案者が直接開発にかかわった言語だからといって、その言語の仕様のみから元となるアイデアや考え方を学べる and/or 他の人にそのアイデアがどんなものだったのかを伝えられるとは思わないほうがよいと思います。やはりその人自身がそのアイデアについて言及した文書を読むのが一番でしょう。言語学習のみでは、概念や背景を学ぶことはできません。きっぱり。



以上、それぞれに付したリンク先の論文や書簡文で、その概要を知ることができるでしょう(くどいようですが、これらの文書を読まずに、ただ、ここで名前の挙がった言語の仕様や利用のされ方から、おのおのの主張の子細を類推するのだけはやめてください)。



一般に語られる「オブジェクト指向」はたいてい、この出自も文脈も目的も本質も異なる2つが、ただオブジェクト(あるいはクラス)という言語機能を共通に活用するというだけの理由でごっちゃにされて非常に合点のゆきにくいものになっています。教科書レベルの記述すら例外ではありません。個人的には、「メッセージ」 and/or “三点セット”だのを持ち出しておきながら、ケイ and/or ストラウストラップの主張への言及無しに「オブジェクト指向」を語ろうとする文章は、どんな偉い人、どんなに有名な人が書いていても(ノウハウとして役立つ内容であるかどうかはともかく、こと「オブジェクト指向」の紹介としては…)“眉唾もの”だと思って差し支えないと思っています。



また調べているうちに、過去に幾度となく繰り返されてきた言語間の“宗教戦争”のほとんどが、このどれに軸足を置くかの違いでしかない、という単純な話に帰着できそうなことにも気がつきました。この点、非常に興味深いところです。たとえば、どれを選ぶかで、オブジェクト指向言語における“元祖”や“純粋”の意味するところもガラリと変わってしまうことは、そのよい例でしょう。

“1”ならもちろん Smalltalk 、“2”なら SIMULA (SIMULA 67)または最初から意識して作られたものとしては Eiffel(元祖ではありませんが Java は比較的純粋なものの代表格…)といった具合です。ここで重要なのは、たとえ“1”で至れり尽くせりの Smalltalk であっても、“2”の切り口ではお世辞にも優秀な言語…というわけにはいかないということです。たとえば Java について、逆もまたしかり。ただ限定的になら Smalltalk で“2”の実践も可能ですし、Java で“1”も同様に問題ありません。EJB のように Smalltalk のなんちゃってメッセージングよりさらに踏み込んだフレームワークもあるくらいです。


C++ についても気をつけないといけません。C++ はよくオブジェクト指向言語として紹介されたり、批判に晒されることが多いのですが、上述のことに絡めてこうした姿勢にはちょっと問題アリと言えそうです。というのも、あくまで同言語は「手続き型」、「抽象データ型」に加えて(もちろん上の“2”の)「オブジェクト指向*も*可能なマルチパラダイム言語として作られたものにすぎないからです。全然関係ない“1”の切り口の「オブジェクト指向」に照らして、C++ を揶揄するのはお門違いもいいところ。まして、例の三点セットを(その出典も知らずに)持ち出してきて C++ を云々するのは天にツバするようなもの…と言えなくもありません。くわばら、くわばら。



(このエントリーは、折を見て、ちょこちょこ加筆しています。どうぞあしからず。)

[改訂#2013/6] 当初は三番目にクックの「手続きによる抽象化」(Object-Oriented Programming Versus Abstract Data Types (PDF))を挙げていましたが、その後の学習で、これは新たなオブジェクト指向の提唱ではなくリスコフの抽象データ型の再定義(整理・分割)であるとの解釈が可能であること、つまり、データ(オブジェクト)に手続きを内包した場合を「オブジェクト指向」、そうでない場合をこれまでどおり「抽象データ型」と呼べばいい…という比較的単純な主張であったと遅まきながら気づくことができました。したがって、二番目の大枠である「型を意識したOO」のバリエーションのひとつとしてこれに含めてよいと判断し思い切ってばっさり削除しました。三番目に翻弄された方、ごめんなさい。その代わりと言ってはなんですが、もともとは一番目の「メッセージングを意識したOO」からの派生ではありますが、その後変化して、現状では前二者のいずれにも含めることができない俗に「プロトタイプベースのOO」と呼ばれるOOを加えるかたちで改めて三系統とする再整理を試みましたので興味のあるかたはこちらも併せてお読みださい。→ id:sumim:20080415:p1