プロトタイプベースのオブジェクト指向言語は私の知る限り、JavaScriptぐらいしか広く使われているものはないんじゃないかと思います。
しかもJavaScriptもES6からclass構文というシンタックスシュガーを導入しましたし、altJSの一種のTypeScriptも広く使われていますし。
プロトタイプベースという概念を勉強している時に、「この概念、クラスベースと違って難しすぎね?」という感情を抱いていて、今もそれは変わらないです。
ただ勉強を進めているうちに、実はプロトタイプベースの方が概念としてはすごくシンプルで柔軟性があるのではないかという思いも募ってきました。
でも明らかにみんなプロトタイプベースでプログラミングをしたがっていませんよね?それどころかプロトタイプベースという概念を理解していない、しようともしていない人が多いように思います。JavaScriptの文脈で「クラスを作って、そのインスタンスを作る。」とかいう人までいますし。こういった説明は私のような初学者を混乱させるので本当にやめてほしいです。
JavaScript以外のSelfやLuaやIoといった他のプロトタイプベースのオブジェクト指向言語が広く使われていない理由で個人的に考えている理由は以下です。
- 単純に時代の流れ。たまたまクラスベースが流行っただけ。
- 概念的にクラスベースの方が優れているから。
- プロトタイプベースは良くも悪くも柔軟。クラスベースは良くも悪くもプログラマーを縛る。仕事をする上で後者の方が好都合だから。
ぶっちゃけやろうとしていることはどちらもあんまり変わらないし、こんなこと考えている暇があるならコード書いて何か物作れって話ですが、勉強している最中に疑問に思ったので質問しました。
参考文献
Object-oriented programming
Self
Prototype-based programming
What does it mean that Javascript is a prototype based language?
以下補足です。
1.この質問はタイトルの通り、プロトタイプベースのオブジェクト指向言語が広く使われていない理由を聞いているものです。どちらの概念の方が優れているかといった質問ではないです。宗教論争をするつもりは一切ありません。
2.質問が質問ですし、究極的にはそれらの区別ができないのは分かっていますが、回答の際はできるだけ明示的に事実と意見の区別をしていただければ幸いです。
3.回答の際に参考文献を併せて明記していただけると助かります。
4.私が自分で載せた参考文献はもちろん読みましたが全部読んだ訳では無いので、「てめえの載せた参考文献に書いてあるだろうが読めや。」的な回答を、必要ならして頂けるとありがたいです。
補足、修正は適宜行います。じゃんじゃんご指摘ください。ご回答よろしくお願いします。
追記(5/31 4:13)
ベストアンサーは悩みましたが、sumimさんにしました。
使っている言葉は違うけど、言っていることに共通点があるというのは非常に面白いですね。
みなさんご回答ありがとうございました。非常にためになりました。
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。

退会済みユーザー
2017/05/25 14:37 編集
2017/05/25 15:53

退会済みユーザー
2017/05/25 16:20

回答6件
0
JavaScriptもLuaも広く使われているメジャーなプログラミング言語の部類に入るとは思うのですが、TIOEBO Inedx等のプログラミング言語ランキングの上位層でプロトタイプベースのオブジェクト指向がその二つぐらいしか無いというのは同意します。IoはTIOBE Indexで100位圏内ですが、50位以上にはならず、メジャーとは言えませんし。
そもそもプロトタイプベースであったJavaScriptに対して、altJSであるCoffeeScritがなぜクラス構文を採用していたのか、ECMAScript6からなぜクラス構文を追加したのか、そういった所にも繋がる疑問だと思います。
では、歴史から哲学まで含めて、分析してきたいと思います。そして、とても長いです。
###最初はクラスベースだったから?
一番最初のオブジェクト指向言語はSimula(1962年)と言われています。しかし、当時はオブジェクト指向という概念はなく、「クラス」という概念を用いることが採用されたに過ぎません。このSimulaに対してアラン・ケイが「メッセージ」という概念を組み合わせて提唱されたのがオブジェクト指向です。アラン・ケイの提唱に基づき作られたのがSmalltalk(1972年)になります。その後、「メッセージ」の概念を強く採用せずに、オブジェクト指向を再定義し、Simula風のクラスを取り入れたのがC++(1979年)です。この後は、Smalltalk風のオブジェクト指向(Objective-C、Ruby、Scala等)とC++風のオブジェクト指向(Java、C#、PHP等)がオブジェクト指向の主流となっていきます。この時点ではどれもこれもクラスベースです。
最初のプロトタイプベースオブジェクト指向であるSelf(1987年)は歴史的にも遅れることになります。オブジェクト指向はまだ発展途上であったとは言え、開発者や研究者の関心はSmalltalkやC++であり、クラスベースという流れは変えられなかったのではないかと思われます。
プロトタイプベースは出遅れただけだ。確かにそれはあるでしょう。しかし、それで終わってしまってはつまらないので、もう少し分析しましょう。
###オブジェクト指向とは何か?
ずっと前のteratailでの回答を清書したものですが、私は下記記事のように考えています。
人は物事を純粋に見ることはできません。何かしらのカテゴライズを行います。クラスを用いた型システムは人の認識の仕方に非常にマッチします。"abc"という文字列を「文字列」という型で捉えることは自然なことです。そう、クラスベースは普段の人の考え方にマッチしていると言えます。
###プロトタイプベースはイデア論?
では、プロトタイプベースはどうなるのでしょうか?あるオブジェクトAにはそのプロトタイプになったオブジェクトPが存在するという関係です。このとき、AはPの一種みたいなことは言えるのでしょうか?AとPはレベルは同じオブジェクトであり、私達に混乱を招かないでしょうか?
古代ギリシャの哲学者プラトンはイデア論というものを提唱しました。全ての物事には、その物事そのもの(イデア)が存在し、私達が知覚しているのはそのイデアの影に過ぎないという物です。私は、プロトタイプベースはこのイデア論に近い物だと考えています。つまり、AのプロトタイプであるPはAのイデアなのです。イデアは永遠不滅の何かであり、周りにある物事の本質です。同様に、Aの本質はPであり、Aがどのような物であるかを決める何かなのです。
イデア論は後の多くの哲学者に影響を与えますが、それをそのまま採用するようなことはありませんでした。イデア論は後に観念論に繋がりますが、それはどちからというとクラスベースの考え方に近い物です。プラトンはイデアを実際に存在する何か(それを直接知覚することはできず、それこそ神のみが知るものかもしれない)と捉えていたようですが、そのような物が実際に存在するという保証はどこにもありません。実はそんな何かがあると言うよりも、逆に、何かしらの観念に当て嵌めてしか物事を見ることができないという考え方が主流となっていきます。(もう、ここら辺はうろ覚えなので、自信が無いですが、カント以降は特にそうであるはず)
###クラスとプロトタイプの違いとは何か?
さて、オブジェクト指向に戻りましょう。クラスとプロトタイプの違いは顕著です。
- クラス: オブジェクトAはクラスCのインスタンスである。つまり、クラスCという上位の観念によって、オブジェクトAを捉え、クラスCの一種としてオブジェクトAが存在する。
- プロトタイプ: オブジェクトAはプロトタイプPを元に作られたオブジェクトである。つまり、プロトタイプPというオブジェクトが元になっていると、オブジェクトAを捉え、プロトタイプPの似姿としてオブジェクトAが存在する。
「太郎くん」と「人間」の関係で言うと、
- クラス: 太郎君は人間である。
- プロトタイプベース: 太郎君は真なる人間(人間のプロトタイプ)をまねた物(影)である。
といえます。プロトタイプベースのような考え方で普段から物事を考えている人はいるのでしょうか?プラトンならそのように考えていそうですが、そして、人間のイデアとは何か探求しそうですが、そうではない人の方が多いと思います。そう、真なる人間、人間のプロトタイプ、人間のイデア、そんな物で人間とは何かと考えたり、人間と人間以外を区別したりするのはいささか奇妙です。実際は、人の認知は逆であり、人間という観念に当て嵌めて太郎君を見てしまっているのです。
つまり、私は、クラスベースは人の認知に非常に似た考え方をしていると考えています。だからこそ、クラスベースでプログラミングをすることは、自然であり、違和感もなく、受け入れやすいと考えています。逆に、プロトタイプベースでは、不自然さが拭いきれず、その理解は難しいと言っても良いのではないかと考えてます。
「オブジェクト指向とは認識の限界である。」であると私は上で紹介した記事で書いています。そして、人の認識はクラスベースです。だからこそ、クラスベースが主流になっており、また、プロトタイプベースしかなかったJavaScriptでクラス構文ができた理由だと思われます。
###それでもプロトタイプベースを採用したのはなぜか?
ここで終わりません。クラスベースの方が良いのではないかとなったところで、研究のための実験的な言語であるSelfやIoは別としても、ではなぜ、実用的なJavaScriptやLuaはプロトタイプベースを採用したのでしょうか?
JavaScriptとLuaには一つの共通点があります。言語仕様としての共通点という話ではなく、その使われ方や目的です。JavaScriptはブラウザに組み込んででHTMLを動的に変化させるために作られました。LuaはCなどに組み込んで使われることを目的に作られました。どちらも、単独で動作する汎用プログラム言語として作られたわけではありません。このことは他の多くの言語とは一線を画すことになります。
その目的に合うように、どちらも軽量かつ高速であることが重要でした。かといって、Cのような単純な命令型では柔軟なプログラムを作ることが難しくなってしまいます。そこで、柔軟かつ強力な表現を持ちながら、その仕組みが単純であるが故に、軽量・高速化が容易であるプロトタイプベースを採用したと考えられます。
クラスベースに比べると、プロトタイプベースは非常に単純です。ES6やCoffeeScriptのクラス構文がトランスパイルによってプロトタイプベースになった場合、複雑怪奇なコードができあがるのを見たことがあるかと思います。クラスベースで作成した場合、その複雑怪奇なコードをインタプリンタエンジンに組み込む必要があったと言うことです。
そう、クラスベースはその仕組みが複雑なのです。初期のRubyが(Perl等の比べて)あまりにも遅くて使い物にならなかったのは有名な話ですが、クラスベースにしてしまったが故の弊害の一つかも知れません。C++は構造体の拡張という誤魔化しで速度を落とすことは避けましたが、その代わり仕様自体が複雑になってしまいました。クラスベースは人の認識に合わせたはずなのですが、3000年経っても解けない人の認識の仕方など、そう単純であろうはずがありません。思っているよりも、私達は複雑に物事を見過ぎてしまっているのです。
つまり、プロトタイプベースは実装面で非常に優れていたと言ってもいいと思います。また、その仕組みの理解についても、極めて単純であるが故に、容易であると言ってもいいと思います。けれど、人の認識はそのように単純に考えられるようにはできていません。仕組みが単純であると言うこととプログラミングが容易であると言うことは違います。人はそれほど賢くなく、地球上で3番目に賢い生物に過ぎないのです。そんな私達が、プロトタイプベースを完全に使いこなす日は永遠に来ないのかも知れません。
投稿2017/05/26 14:18
総合スコア21741
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。

退会済みユーザー
2017/05/30 19:02 編集

退会済みユーザー
2017/06/01 17:54

0
誤解を恐れず書くとするならC++の所為です。
Cはオブジェクト指向の書き方を持たないため、大規模開発には人間の認識の限界に挑戦しているような問題がありました。そんな時代に颯爽と現れたのが、オブジェクト指向の元祖となるプログラム言語Simulaです。でも残念ながらSimulaの狙いこそは良かったのですが、実際に使うとなると実物は遅くて使い物にないっていう問題がありました。そこで、CをSimulaライクに魔改造したのがC++です。すべての元凶です。
さて、オブジェクト指向を実現させる方法の具体例となったクラスベースオブジェクト指向ですが、C++の影響で勢いが止まりません。
C++からjavaやらC#やら今のメジャーな言語が派生しました。(私はこいつらをCの系譜と勝手に呼んでます。)もちろん、それらは、C++から大規模開発に便利なクラスベースのオブジェクト指向という設計を引き継ぎました。
pythonは開発段階には無かったクラスっていう考えを取り入れました。pythonの開発者に友人がC++のクラスがあると便利だと言ったからだとかいう逸話を何処かで見ました。
Perlは無理やりパッケージをクラスってことにしました。なぜなら他の多くの言語でクラスってのが使われているから。
PHPも後付で流行りのクラスって機能を付けました。PHP5のアップグレードの目玉はオブジェクト指向対応の強化ってくらい、クラスベースのオブジェクト指向を高評価してます。そんな時代です。
Rubyもクラスを持ちます。ええ、perlをまともに直したっていうRubyの誕生の逸話を考えれば当然ですね。
(Python、Perl、PHP、Rubyのオブジェクト指向が正規のクラスベースなのかという疑問はありますが、クラスを使う私が知っている言語ってことで書きました。)
ということで、感染したかのようにクラスベースのオブジェクト指向言語がいっぱいになりました。(他にもいっぱいありますよね)
時代的にプロトタイプベースのオブジェクト指向言語(Self)が出て来る前に、クラスベースのオブジェクト指向がサクッとシェアを独占したので、それがオブジェクト指向の基本となってしまった感じです。(たしかプロトタイプベースの言語が出るのはクラスベースの言語の10年くらい後です。)その後のオブジェクト指向っていうものは、クラスベースがデフォルトであり、それ以外は異端なのです。
90年台後半のWindowsOSがシェアを9割くらい獲って、PCといえばWindowsみたいな環境だったのと同じです。(PC?Windows以外があるの?みたいな)
そんな環境に逆らうように、プロトタイプベースのオブジェクト指向を始めたSelfとか、それを取り入れたJavascriptは挑戦的ですね。格好いいです。当時のMac感がします。
質問に対する結論としては、オブジェクト指向が流行だったときの基本となったのがクラスベースのオブジェクト指向っていうやり方だったのが大きいと思います。(当時、クラスベースに対するライバルはいたのでしょうか?私は知りません。)
ITの技術革新っていうか、そういうのって流行りの時期に誰が勝ったかが重要で、ちょっと前の3Dプリンターで例えるなら、削るより、重ねていく方式の方が流行ったので、今は重ねていくやつばっかりになったみたいな感じです。
オブジェクト指向の黎明期にプロトタイプベースの言語があれば別の言語体系が流行ってる世界になっていたかもしれません。
※この文章はふんわりとした情報と、ふんわりとした脳みそ具合(飲酒)で書いている部分もあるため、正確性は保証しません。でも、概ねC++の所為だってのは当たっていると思います。
投稿2017/05/25 17:12
編集2017/05/25 17:17総合スコア1895
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。

退会済みユーザー
2017/05/30 19:07 編集

0
1つ間違いないところとして、「プロトタイプベースは静的型付け言語と相容れない」ということがあります。厳密な「型=クラス」を持たないプロトタイプベースでは、(Objective-Cのようにオブジェクト部分だけ動的に作ってしまうなら別として)静的型付けすることができなくなってしまいます。
あと、実はJavaScriptでも、高速化のために内部で型推論を行っています(Mozillaブログ)。プロトタイプベースであっても、結局内部で「型」という概念が登場するのなら、外からそれを扱えたほうが便利、という意味合いもあるのかもしれません。
投稿2017/05/25 13:43
総合スコア146506
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。

退会済みユーザー
2017/05/30 16:40

0
ベストアンサー
すでにご自身で結論に到達しておられるように見受けられるので蛇足ですが、プロトタイプベース(の自由度、あるいはその元となったSmalltalkのメッセージングをドグマ・メタファにした遅延結合性の徹底)は、よく言われる「人類には早すぎた」類いのものだったという話に落ち着くのではないでしょうか。
「クラスベース」vs「プロトタイプベース」という対立関係にしてしまうと分かりづらくなってしまいますが、プロトタイプベースをよりプリミティブな枠組みとしてとらえ、クラスベースはそれを扱いやすくするための枠組み(より確実に制御できるレベルまで引き下げる制約の与えかた)のひとつと位置づけるといくらかすっきり整理できそうです。
同じ「人類に早すぎた」類いのものに並行・並列処理がありますが、こちらはプロセッサのマルチコア化が進む現在においては「だからといって使わないわけにはいかない」ため問題を抱えながらも、なんとかそれらを解決・回避しつつ使われています。しかしプロトタイプベースの表現の自由度は、さほど差し迫った状況も無く、クラスベースでシミュレートできる範囲で安全に使えばいいのでは…で済む程度のニーズしかないので、あまり使われていないということがありそうです。
とはいえ、クラスベースが不完全であることを問題視したり、特に静的型チェック機構と併用した場合の制約がきつすぎる(できることを抑制しすぎてしまう)と感じる人もいて、古くはインターフェースから始まりトレイトや型クラス機構といったクラスの枠とらわれずに拡張や柔軟性を許す(しかしもちろん実行時エラーを発生させない)仕組みも種々考案・提案されていますから、さらに踏み込んで、もしかしたらいずれはプロトタイプベースの自由度もたやすく制御可能になり広く使われるようになる日も来るかもしれません。
追記:
- 参考資料リンクを追加しました。
- Smalltalk にもクラスはありますが、Simulaスタイルのクラスが導入されたのは Smalltalk-76 からで、メッセージングのアイデアの有効性が試された初期の実装である Smalltalk-72 では JavaScript のクラスのように関数ライクな振る舞いをするものでした。
投稿2017/05/26 03:20
編集2017/05/31 00:38総合スコア29
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。

退会済みユーザー
2017/05/30 18:03 編集

退会済みユーザー
2017/06/01 17:28 編集

退会済みユーザー
2017/06/02 21:02 編集

0
rubyもプロトタイプっぽい動作をするのでそれも含めたらそれなりに流行ってるといえるのではないかと思います。
それも含めて流行らないとすれば、理由は2つ考えられます。
一つは実行速度の問題だと思います。実行時にメソッドを探しに行くので実行速度がどうしても遅くなります。実行速度を上げるには、コンパイラがクラスベースに読み替える必要があります。(最近の傾向としてコンパイルっぽいことをしている動的言語がふえている気がします。)
もう一つが、インテリセンスによる入力補完など開発の手間の問題です。IDEをつかっているとコンパイルする前に実装漏れに気が付きます。TypeScriptなどはそれを目玉にしている気がします。(個人的にもこちらが気持ち良いです。)
JavaScriptの文脈で「クラスを作って、そのインスタンスを作る。」とかいう人までいますし。
この点、同意します。オブジェクト指向とはほとんど関係ない。クラスベース言語の呪いの様なものだとおもいます。
投稿2017/05/25 15:44
総合スコア2884
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。

退会済みユーザー
2017/05/30 17:08 編集

0
詳しいことは他の方々が答えていると思いますので。
私は趣味でやっています。なのであくまで可能性として。
可能性1:
プロトタイプベースの言語が少ない or 環境が限定的であるため。
可能性2:
クラスベースとごっちゃにして 勘違いし、理解できないから。または わかりにくい。
可能性3:
型があいまいだから。
可能性4:
その他の理由。 ( 思いつかない... )
かなと。
可能性1 について。
たとえば例としては適切ではないですが、
Objective-C は クラスベースらしいですが、Mac環境でしか使えないようです。
それみたいに、Macでしか使えない, Windowsでしか使えない, Pythonみたいにインストールしないといけない... とかみたいに、ユーザからしても 面倒なものとか。
もちろん、OS依存しないし, ○○をインストール... とかも関係ない っていう言語もあるかもしれませんが。
可能性2について。
これは私もだったんですが、クラスベースとプロトタイプベースでは何が違うかとか、
JavaScriptの場合、
JavaScript
1function Test{ 2 var id = 100; 3 4 this.method1 = function(){ /* 何らかの処理 */ } 5}
みたいにしますよね。
C++とか Javaとかといった言語だと class っていうキーワード? があって、関数 ( サブルーチンとかも ) と違うことがわかります。
ですが JavaScript だと 初心者は「関数」なのか「プロトタイプ」なのか判断がしづらい。
可能性3について。
Javaとかだと int, long とかみたいに型が用意されています。VB系でも Integer, Long等。
ですが、JavaScriptとかだと var だけです。なので 何が入っているのかわからないとか?
私は趣味でちょっとかじったレベルなので、
もしかするとすべて言語によるのかもしれませんが。
JavaScriptだとこうだけど、Selfではこう。とか。
投稿2017/05/27 08:04
総合スコア4962
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。

退会済みユーザー
2017/05/30 16:35 編集

あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。