質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.04%

プロトタイプベースのオブジェクト指向言語が広く使われていない理由は?

解決済

回答 6

投稿 編集

  • 評価
  • クリップ 19
  • VIEW 7,336
退会済みユーザー

退会済みユーザー

プロトタイプベースのオブジェクト指向言語は私の知る限り、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さんにしました。

使っている言葉は違うけど、言っていることに共通点があるというのは非常に面白いですね。

みなさんご回答ありがとうございました。非常にためになりました。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • think49

    2017/05/25 23:24

    「プロトタイプベースのオブジェクト指向言語が広く使われていない」はどのような判断基準で結論しましたか。それは事実ではなく、意見ではないのでしょうか。 stackoverflowでも主観的な質問と認識されそうな気がしますが…。

    キャンセル

  • 退会済みユーザー

    退会済みユーザー

    2017/05/25 23:36 編集

    はい、完全に個人的な意見です。 判断基準はオブジェクト指向とは何かを説明するサイトで、クラスを使って云々~とクラスベース前提の説明をしていたり、JavaScriptの文脈でクラスという言葉を使っていたり他にも例は挙げられますが、要は個人的な観測範囲内からそう結論づけたということです。 ちなみに、think49さんはこの意見に賛成ですか、反対ですか?それとも事実としてプロトタイプベースは広く使われていませんか、いますか?

    キャンセル

  • think49

    2017/05/26 00:53

    個人的には興味がありません。主題が主観的である以上、水掛け論になる事は目に見えています。プログラミング言語の消費者としては、必要な言語を必要なタイミングで習得すればよいと考えています。JavaScriptは十分に普及しており、私が必要としているから学ぶ、それだけ分かれば十分です。世の普及度を客観的な指標で求めるとすれば、プログラミング言語を作る立場になってからでしょうが、私のレベルはそこまで達していません。

    キャンセル

  • 退会済みユーザー

    退会済みユーザー

    2017/05/26 01:20

    なるほど。よく分かりました。ありがとうございました。

    キャンセル

回答 6

+15

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/31 03:57 編集

    ご回答ありがとうございます。

    > その後、「メッセージ」の概念を強く採用せずに、オブジェクト指向を再定義し、Simula風のクラスを取り入れたのがC++(1979年)です。

    これはプログラミングを勉強していてよく思うことですが、実体が違うなら名前も変えろと。私のような初学者が混乱する。Alan Kayもオブジェクト指向ではなく、メッセージング指向という名前にして欲しかったですね。確か本人もこの名前は失敗だったと言っていたような...。

    ビャーネ・ストラウストルップもSmalltalkに影響受けていないと言っていたような気がします。英語版wikipediaでも"Influenced by"のところにSmalltalkの文字は無いですし。じゃあ先にSmalltalkが名前取っちゃってるから別のにしようとは思わなかったのかと。

    _____________________________________________________________________________________________

    > 古代ギリシャの哲学者プラトンはイデア論というものを提唱しました。

    哲学に興味はあるものの疎いのであまり用語や概念を振りかざしたくありませんが、確か英語の"idea"の語源になっているヤツだったと記憶してます。

    イデア論はむしろクラスベースっぽくないかなと思うのですが、

    > イデア論は後に観念論に繋がりますが、それはどちからというとクラスベースの考え方に近い物です。

    と先におっしゃっていましたね。

    > イデア論は後の多くの哲学者に影響を与えますが、それをそのまま採用するようなことはありませんでした。

    そういえば、弟子のアリストテレスもイデア論という考え方を継承しましたよね。アリストテレスの提唱した概念は具体的にはあまり知りませんが、プラトンと違って物質的だったような気がします。つまりイデア論を批判的に継承した。

    _____________________________________________________________________________________________

    > また、プロトタイプベースしかなかったJavaScriptでクラス構文ができた理由だと思われます。

    個人的にはクラス構文ができた理由は人の物の認識にプロトタイプベースがそぐわないからではなく、「プロトタイプベースという概念はシンプル。でもJavaScriptのその実装は複雑。」だからという印象を抱いています。中途半端にクラスベースに寄せていますよね。コンストラクタという用語だったり、new演算子だったり。

    そこも、人の認識がクラスベースだから実装がそうなったということかもしれません。

    _____________________________________________________________________________________________

    > どちらも、単独で動作する汎用プログラム言語として作られたわけではありません。

    これは「なるほど。」と思いました。クラスベースの方が人気なのに、なぜわざわざプロトタイプベースを選んだのかと。

    何かとセットで使われる。だからあまり複雑にしすぎてもいけない。かといってシンプルすぎてもしょぼくなる。じゃあプロトタイプベースだ!と。(ということですかね?そのように解釈しました。)

    ここでまたES6のクラス構文の話に戻りますが、JavaScriptでバリバリ開発!となったのは比較的最近だと記憶しております。
    「JavaScriptの取り扱う範囲もゴツくなったし、ここいらでいっちょクラス構文ブチ込んどくか!」というのも理由としてあるんじゃないのかなと思いました。

    イデア論と絡めた話は非常に興味深かったですし、なぜわざわざプロトタイプベースを採用したのかの理由の考察も参考になりました。

    非常にためになりました。ありがとうございました。

    ところで、"地球上で3番目に賢い生物"でググったところ、銀河ヒッチハイク・ガイドというものが出てきました。私は常々人間はバカだと思っていますが、そういうことだったんですね。

    これを読んで(?)、宇宙に対する理解(?)を深めようと思いました(?)。
    元ネタよく知らない...。

    キャンセル

  • 2017/05/31 07:06

    今回は書きませんでしたが、クラス構文が必要になったもう一つの理由として、デザインパターンなどの設計方法の研究がクラスベースが中心であり、デザインパターンを採用するにはクラスとして扱えるようにしなければならなかったからと言うのがあると思います。

    プロトタイプベースのインタプリンタ自体の実装は単純です。また、プロトタイプベースを基本として実装すればそのコードも複雑になりません。しかし、クラスベースのクラスのように扱いたいとしたときに、複雑なコードになってしまうと思っています。

    実際は、JavaScriptでもPythonやRubyで慣れているクラスベースの考え方で作りたいよー⇒PythonやRubyっぽくクラスも使えるCoffeeScriptを作ったよ⇒CoffeScriptが流行⇒次のECMAScriptにはCoffeeScriptでよく使われている機能も採用しよう⇒ES6にクラス構文追加、という流れなのかも知れませんけど。

    キャンセル

  • 2017/06/02 02:54

    デザインパターンと絡んだ理由もあるようなのですね。

    参考になりました。コメントありがとうございます。

    キャンセル

+12

誤解を恐れず書くとするなら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/31 02:33 編集

    > 質問に対する結論としては、オブジェクト指向が流行だったときの基本となったのがクラスベースのオブジェクト指向っていうやり方だったのが大きいと思います。

    私としてもやはりそう思います。要は時代の流れだと。

    情報のソースは英語版のwikipediaですが、最初に世に出たのがC++は83年、Selfは87年なんですよね。C++の開発自体が始まったのがどうやら79年らしいですが。
    wikipediaちゃんと読んでないので、間違いがあるかもしれません。

    世に出てから4年しか差がないのに、そんなに違うものなのか。あの当時の4年というのはそんなに大きなものだったのか。という疑問はあります。一般論として、「ITめっちゃ流れ速えー!超速えー!」はあるかもしれませんが。

    > ちょっと前の3Dプリンターで例えるなら、削るより、重ねていく方式の方が流行ったので、今は重ねていくやつばっかりになったみたいな感じです。

    これは初耳です。削る方式があるなんて今まで見たことないです。メディアで取り上げられているのを見たことがありますが、そういえば重ねる方式でしたね。

    クラスベースを批判するわけではありませんが(批判できる能力もない)、一般的に言って流行っているから良いものなんだというのは早計ですね。
    流行っていてダメ、流行っていて良い、両方の可能性があると。

    参考になりました。ご回答ありがとうございました。

    キャンセル

+10

1つ間違いないところとして、「プロトタイプベースは静的型付け言語と相容れない」ということがあります。厳密な「型=クラス」を持たないプロトタイプベースでは、(Objective-Cのようにオブジェクト部分だけ動的に作ってしまうなら別として)静的型付けすることができなくなってしまいます。

あと、実はJavaScriptでも、高速化のために内部で型推論を行っています(Mozillaブログ)。プロトタイプベースであっても、結局内部で「型」という概念が登場するのなら、外からそれを扱えたほうが便利、という意味合いもあるのかもしれません。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/05/31 01:40

    ご回答ありがとうございます。

    > 「プロトタイプベースは静的型付け言語と相容れない」

    複数の回答者もおっしゃっていることですが、やはり「型」ですね...。
    TypeScriptの謳い文句の内の一つに、「大規模開発に向いてる!だって静的型付けだから!」というのがあるかと思いますが(ちゃんと勉強したことない)、やはり型があった方が何かと都合が良いんでしょうね。まだプログラミング始めて間もないですが。

    とすると私が挙げた理由の一つの、「プロトタイプベースは良くも悪くも柔軟。クラスベースは良くも悪くもプログラマーを縛る。仕事をする上で後者の方が好都合だから。」というのはあながち間違っていないかもしれませんね。

    動的型付け→静的型付けの順番でプログラミング勉強していますが、むしろ静的型付けの方が面倒臭いけど分かりやすいんじゃないか?というのは感じますね。

    > 実はJavaScriptでも、高速化のために内部で型推論を行っています(Mozillaブログ)。

    これは知らなかったです。情報ありがとうございます。

    キャンセル

checkベストアンサー

+7

すでにご自身で結論に到達しておられるように見受けられるので蛇足ですが、プロトタイプベース(の自由度、あるいはその元となったSmalltalkのメッセージングをドグマ・メタファにした遅延結合性の徹底)は、よく言われる「人類には早すぎた」類いのものだったという話に落ち着くのではないでしょうか。

「クラスベース」vs「プロトタイプベース」という対立関係にしてしまうと分かりづらくなってしまいますが、プロトタイプベースをよりプリミティブな枠組みとしてとらえ、クラスベースはそれを扱いやすくするための枠組み(より確実に制御できるレベルまで引き下げる制約の与えかた)のひとつと位置づけるといくらかすっきり整理できそうです。

同じ「人類に早すぎた」類いのものに並行・並列処理がありますが、こちらはプロセッサのマルチコア化が進む現在においては「だからといって使わないわけにはいかない」ため問題を抱えながらも、なんとかそれらを解決・回避しつつ使われています。しかしプロトタイプベースの表現の自由度は、さほど差し迫った状況も無く、クラスベースでシミュレートできる範囲で安全に使えばいいのでは…で済む程度のニーズしかないので、あまり使われていないということがありそうです。

とはいえ、クラスベースが不完全であることを問題視したり、特に静的型チェック機構と併用した場合の制約がきつすぎる(できることを抑制しすぎてしまう)と感じる人もいて、古くはインターフェースから始まりトレイト型クラス機構といったクラスの枠とらわれずに拡張や柔軟性を許す(しかしもちろん実行時エラーを発生させない)仕組みも種々考案・提案されていますから、さらに踏み込んで、もしかしたらいずれはプロトタイプベースの自由度もたやすく制御可能になり広く使われるようになる日も来るかもしれません。

追記:

  • 参考資料リンクを追加しました。
  • Smalltalk にもクラスはありますが、Simulaスタイルのクラスが導入されたのは Smalltalk-76 からで、メッセージングのアイデアの有効性が試された初期の実装である Smalltalk-72 では JavaScript のクラスのように関数ライクな振る舞いをするものでした。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/05/31 03:00 編集

    ご回答ありがとうございます。

    > あるいはその元となったSmalltalkのメッセージングをドグマ・メタファにした遅延結合性の徹底

    クラスベース VS プロトタイプベースという二項対立で語られることが非常に多いですが、実は最初のプロトタイプベースのSelfはSmalltalkを元にしているんですよね。(ソースは英語版Wikipedia。)

    Smalltalkはクラスという機能こそあるものの、クラスベースではなくメッセージング指向ですよね。うろ覚えですが、Alan Kay自身が"Object-oriented is simply about messaging."みたいなことを言っていたような気がします。そして、他のオブジェクト指向に関しては俺は知らねえ、とも。

    オブジェクト指向という概念に関してまだ勉強中ですが。

    > 「クラスベース」vs「プロトタイプベース」という対立関係にしてしまうと分かりづらくなってしまいますが、プロトタイプベースをよりプリミティブな枠組みとしてとらえ、クラスベースはそれを扱いやすくするための枠組み(より確実に制御できるレベルまで引き下げる制約の与えかた)のひとつと位置づけるといくらかすっきり整理できそうです。

    ここも「なるほど。」と思いました。時系列的にクラスベース→プロトタイプベースで尚且つ、上記でもちらっと触れましたが、Alan Kay(Smalltalk)のメッセージング指向という概念がどっか行っちゃったので、どうしても対立関係で考えがちですね。オブジェクト指向に関する巷に溢れている記事なんてほとんどAlan Kayのそれに触れない。

    プロトタイプベースは一番原始的なオブジェクト指向。だからなんでもあり。なんでもありだからこそ、こっちが上手にコントロールしないといけなく扱いが難しい。

    > クラスベースが不完全であることを問題視したり、特に静的型チェック機構と併用した場合の制約がきつすぎる(できることを抑制しすぎてしまう)と感じる人もいて、

    「クラスベースはこういうところに問題がある!じゃあプロトタイプベース使おう!」とはならずにクラスベースの言語に色々と機能を付け足し、弱点を補おうとする。そんなにプロトタイプベースを使いたくないのかと思いますね。

    インターフェースというものを初めて知ったとき、「これはもしかしてクラスの持つ階層関係に縛られずにメソッドを付けたすために作ったんじゃね?」と思いました。

    ちゃんと勉強したことありませんが、そういえば、C++やPythonなどの多重継承が許されている言語にはインターフェース、トレイトだとかいう機能は無いんじゃないんでしたっけ?

    なぜなら多重継承が出来るということは、階層関係が比較的自由なのでそんなものは必要ないと。確かそんな感じだった気がします。

    クラスベースが持つ問題をクラスベースの中で解決しようとしているということはプロトタイプベースが広まる気配はなさそうですね。

    非常にためになりました。ありがとうございました。

    キャンセル

  • 2017/06/02 02:27 編集

    参考資料の追加ありがとうございます。

    なかなか読むのに時間がかかりそうな資料ばかりなので、時間を見つけてじっくり読ませていただきます。

    キャンセル

  • 2017/06/02 09:09

    遅くなりましたがベストアンサーに選んでいただきありがとうございます。
    何かお役に立てる情報がありましたら幸いです。

    あいにくSELFの文献はプロトタイプベースをクラスベースのアンチテーゼとして位置づけ、その後の両者の対立軸に象徴される“誤解”や混乱の元凶となってしまっているため、この論調に限っては注意して切り離しつつ読んでください。

    メッセージングに固執しているところも、それが抜け落ちて久しいJavaScirptのことを考えるとあまり重視しなくて大丈夫そうです。ただ「矛盾語法か?」でケイが述べているようにメッセージングはあくまでソフトウエア工学における次善の策として彼が位置づける「(ソフトウエアの設計・実装・運用というあらゆる側面における)遅延結合の徹底」の方便であることを鑑みると、プロトタイプベースがそれをよく体現していることを学ぶには役立つと思いリンクしました。(人類には早すぎる考え方やしくみ、ということで)

    キャンセル

  • 2017/06/03 05:58 編集

    コメントありがとうございます。

    チラッと読んだところ、確かに少し"opinionated"な印象を受けました。

    オブジェクト指向について、あるいは他のパラダイムについて色々と調べていると感じるのが、"opinionated"だなということですね。

    優秀なプログラマや、経験があるだけの無能なオッサンプログラマ、計算機科学の教授までみんな一家言持っているなあと。

    個人的には、
    "(Pardon my French but) I don't give a shit about the opinions, I give a shit about the facts."
    だと思っているので、最終的には無理だったとしてもそういう態度は持ちつつ、慎重に事実だけを文献から読み取ろうとしています。

    挙げていただいた文献や資料は、なかなかネットの海を彷徨っても出てこない情報なので(単に自分の調べ方が悪いだけ?)、参考になります。

    回答、参考資料の追加、補足、ありがとうございました。

    キャンセル

+3

rubyもプロトタイプっぽい動作をするのでそれも含めたらそれなりに流行ってるといえるのではないかと思います。

それも含めて流行らないとすれば、理由は2つ考えられます。

一つは実行速度の問題だと思います。実行時にメソッドを探しに行くので実行速度がどうしても遅くなります。実行速度を上げるには、コンパイラがクラスベースに読み替える必要があります。(最近の傾向としてコンパイルっぽいことをしている動的言語がふえている気がします。)

もう一つが、インテリセンスによる入力補完など開発の手間の問題です。IDEをつかっているとコンパイルする前に実装漏れに気が付きます。TypeScriptなどはそれを目玉にしている気がします。(個人的にもこちらが気持ち良いです。)

JavaScriptの文脈で「クラスを作って、そのインスタンスを作る。」とかいう人までいますし。

この点、同意します。オブジェクト指向とはほとんど関係ない。クラスベース言語の呪いの様なものだとおもいます。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/05/31 01:58 編集

    > 実行時にメソッドを探しに行くので実行速度がどうしても遅くなります。

    MDN(https://developer.mozilla.org/ja/docs/Web/JavaScript/Guide/Inheritance_and_the_prototype_chain)からですが、「どのオブジェクトもプロトタイプと呼ばれる、他のオブジェクトへの内部的な繋がりを持っています。そのプロトタイプオブジェクトも自身のプロトタイプを持っており、あるオブジェクトのプロトタイプが null に到達するまでそれが続きます。」と書かれていますし、

    私が挙げた参考文献(https://stackoverflow.com/questions/186244/what-does-it-mean-that-javascript-is-a-prototype-based-language)の一つにも、

    "so objects are allowed to be linked together in a hierarchy. In javascript, every object has a secret link to the object which created it, forming a chain. When an object is asked for a property that it does not have, its parent object will be asked... continually up the chain until the property is found or until the root object is reached."と書かれていますね。

    実行速度が比較的遅いのは、インタプリタ型の言語だからでプロトタイプベースだからではないと思っていましたが、それも関係あるとは思いませんでした。言われて気づきましたが確かMDNのドキュメントにも、「プロトタイプチェーンをむやみにいじるとパフォーマンスに影響与えるよ。」みたいなことが書かれてあったような気がします。

    ただ実行速度に関しては、maisumakunさんが挙げて下さった情報によると、内部で型推論を行い、高速化に成功しているようですし、V8かなんかのGoogleが開発したJavaScriptエンジンも、めっちゃ速いみたいなことを見たような気がします。

    この言語のことをほとんど知りませんが、他のプロトタイプベースのLuaもCやC++と一緒に使われることが多いから、実行速度が遅いとCやC++の速度の足を引っ張って使い物にならないんじゃないのかと思いました。

    他のプロトタイプベースの言語をほとんど知らないので自分の言っていることに自信がなく、的外れの可能性が高いですが。

    ご回答ありがとうございました。

    キャンセル

+1

詳しいことは他の方々が答えていると思いますので。

私は趣味でやっています。なのであくまで可能性として。

可能性1:
プロトタイプベースの言語が少ない or 環境が限定的であるため。

可能性2:
クラスベースとごっちゃにして 勘違いし、理解できないから。または わかりにくい。

可能性3:
型があいまいだから。

可能性4:
その他の理由。 ( 思いつかない... )

かなと。

可能性1 について。
たとえば例としては適切ではないですが、
Objective-C は クラスベースらしいですが、Mac環境でしか使えないようです。
それみたいに、Macでしか使えない, Windowsでしか使えない, Pythonみたいにインストールしないといけない... とかみたいに、ユーザからしても 面倒なものとか。
もちろん、OS依存しないし, ○○をインストール... とかも関係ない っていう言語もあるかもしれませんが。

可能性2について。
これは私もだったんですが、クラスベースとプロトタイプベースでは何が違うかとか、
JavaScriptの場合、

function Test{
         var id = 100;

         this.method1 = function(){ /* 何らかの処理 */ }
}

みたいにしますよね。

C++とか Javaとかといった言語だと class っていうキーワード? があって、関数 ( サブルーチンとかも ) と違うことがわかります。

ですが JavaScript だと 初心者は「関数」なのか「プロトタイプ」なのか判断がしづらい。

可能性3について。
Javaとかだと int, long とかみたいに型が用意されています。VB系でも Integer, Long等。
ですが、JavaScriptとかだと var だけです。なので 何が入っているのかわからないとか?

私は趣味でちょっとかじったレベルなので、
もしかするとすべて言語によるのかもしれませんが。

JavaScriptだとこうだけど、Selfではこう。とか。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/05/31 01:24 編集

    > 可能性3:
    型があいまいだから。

    ↑他の回答者の方もおっしゃっていましたが、やはり「型」というのが一つのキーワードになりそうですね。

    ご回答ありがとうございました。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.04%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る