コンテンツにスキップ

「プロトタイプベース」の版間の差分

出典: フリー百科事典『ウィキペディア(Wikipedia)』
削除された内容 追加された内容
Sycgln (会話 | 投稿記録)
Sycgln (会話 | 投稿記録)
1行目: 1行目:
{{出典の明記|date=2015年12月}}
{{出典の明記|date=2015年12月}}


'''プロトタイプベース''' ({{lang-en-short|Prototype-based}}) は、[[オブジェクト指向プログラミング]](OOP)のスタイルのひとつであり、[[オブジェクト (プログラミング)|オブジェクト]]の生成に既存[[オブジェクト (プログラミング)|オブジェクト]]のクローン(複製)を用いるスタイルを指している。インスタンスベース(Instance-based)とも呼ばれている。これと対比されるOOPスタイルに[[クラスベース]]がある。[[クラス (コンピュータ)|クラス]]の[[インスタンス]]化と、オブジェクトのクローンは、明確に異なる概念だったのでスタイル分けされる必要があった。プロトタイプベースOOPの原点は[[Smalltalk]]方言の[[Self]]であり、Smalltalkのクラスベース設計を平易化する試みから1987年に誕生している。他には[[Lua]]、NewtonScript、[[JavaScript]]、[[Etoys]]、[[ECMAScript]]、[[Io (プログラミング言語)|Io]]、[[TypeScript]]などがあるが、クラスベースOOPに比べると採用言語が少ないマイノリティに留まっている。
'''プロトタイプベース''' ({{lang-en-short|Prototype-based}}) は、[[オブジェクト指向プログラミング]](OOP)のスタイルのひとつであり、[[オブジェクト (プログラミング)|オブジェクト]]の生成に既存[[オブジェクト (プログラミング)|オブジェクト]]のクローン(複製)を用いるスタイルを指している。これには直後にメンバを拡充するための空オブジェクトの複製も含まれている。このスタイルはインスタンスベース(Instance-based)とも呼ばれている。これと対比されるOOPスタイルに[[クラスベース]]がある。[[クラス (コンピュータ)|クラス]]の[[インスタンス]]化と、オブジェクトのクローンは、明確に異なる概念だったのでスタイル分けされる必要があった。プロトタイプベースOOPの原点は[[Smalltalk]]方言の[[Self]]であり、Smalltalkのクラスベース設計を平易化する試みから1987年に誕生している。他には[[Lua]]、NewtonScript、[[JavaScript]]、[[Etoys]]、[[ECMAScript]]、[[REBOL]]、[[Io (プログラミング言語)|Io]]、[[TypeScript]]などがあるが、クラスベースOOPに比べると採用言語が少ないマイノリティに留まっている。


プロトタイプとは、クローン元になった[[オブジェクト (プログラミング)|オブジェクト]]を意味しており、クローン先のオブジェクトから見てそう呼ばれる。プロトタイプは同時にそのオブジェクトの暗黙の[[委譲]]先になり、これは[[継承 (プログラミング)|継承]]におけるスーパークラス相当として扱われる。プロトタイプベースは[[動的型付け]]に準拠していることから、オブジェクトの情報隠蔽に伴なう[[カプセル化]]は軽視されていることが多い。[[ポリモーフィズム]]は[[動的型付け]]による[[動的束縛|動的バインディング]]と、プロトタイプ[[委譲]]チェーン上のネームマスキング({{仮リンク|ドミナンス|en|Dominance (C++)}}とも)が主体である。プロトタイプベースで[[オーバーライド|メソッドオーバーライド]]と説明される機能は、正確にはネームマスキングである。
プロトタイプとは、クローン元になった[[オブジェクト (プログラミング)|オブジェクト]]を意味しており、クローン先のオブジェクトから見てそう呼ばれる。プロトタイプは同時にそのオブジェクトの暗黙の[[委譲]]先になり、これは[[継承 (プログラミング)|継承]]におけるスーパークラス相当として扱われる。プロトタイプベースは[[動的型付け]]に準拠していることから、オブジェクトの情報隠蔽に伴なう[[カプセル化]]は軽視されていることが多い。[[ポリモーフィズム]]は[[動的型付け]]による[[動的束縛|動的バインディング]]と、プロトタイプ[[委譲]]チェーン上のネームマスキング({{仮リンク|ドミナンス|en|Dominance (C++)}}とも)が主体である。プロトタイプベースで[[オーバーライド|メソッドオーバーライド]]と説明される機能は、正確にはネームマスキングである。
16行目: 16行目:
5, The class holds the shared behavior for its instances (in the form of objects in a program list).(クラスはそのインスタンス共有の振る舞いを持つ)
5, The class holds the shared behavior for its instances (in the form of objects in a program list).(クラスはそのインスタンス共有の振る舞いを持つ)


6, To eval a program list, control is passed to the first object and the remainder is treated as its message.}}(4)は[[数学的帰納法|数学的帰納]]な文章であり、オブジェクト=インスタンスのひな型であるクラスもまたメタクラスのインスタンス化であり、そのメタクラスもまた他のメタクラスのインスタンス化と解釈される。(3)で記憶はクラスとインスタンス双方にあるが、(5)で振る舞いはクラスのみとされており、これが混乱を招きやすいネックになっていた。Smalltalkの元祖クラスベース設計は公開後間もなくして開発陣からも不評になり、それは概ねクラスとインスタンスに対する振る舞い(behavior)の在り方の差異に起因していた。その改善策としての、オブジェクトからクラスとインスタンスの概念を撤廃してしまおうという案が、プロトタイプベースの原点になっている。ここでは(1)の遵守が第一にされていた。
6, To eval a program list, control is passed to the first object and the remainder is treated as its message.}}(4)は[[数学的帰納法|数学的帰納]]な文章であり、オブジェクト=インスタンスのひな型であるクラスもまたメタクラスのインスタンス化であり、そのメタクラスもまた他のメタクラスのインスタンス化と解釈される。(3)で記憶はクラスとインスタンス双方にあるが、(5)で振る舞いはクラスのみとされており、これが混乱を招きやすいネックになっていた。[[Smalltalk]]の元祖クラスベース設計は公開後間もなくして開発陣からも不評になり、それは概ねクラスとインスタンスに対する振る舞い(behavior)の在り方の差異に起因していた。その改善策としての、オブジェクトから[[クラス (コンピュータ)|クラス]][[インスタンス]]の概念を撤廃してしまおうという案が、プロトタイプベースの原点になっている。この案は言語実装視点では、クラスを無くしてインスタンスに一律化するとも解釈できるので、インスタンスベースと別称された。[[Self]]はこの案に沿って制作されたSmalltalk方言であった。ここでは(1)の遵守が第一にされていた。


なお、[[C++]]/[[Python]]以降のクラスベース設計では、[[クラス (コンピュータ)|クラス]]と[[インスタンス]]が型と値の役割に固定されてインスタンス化の相互再帰が無くなったことから、インスタンスのみがオブジェクトになっている。[[メタクラス]]はクラス構成の動的変更機能になっている。これは(1)の事実上の撤廃であった。
なお、[[C++]]/[[Python]]以降のクラスベース設計では、[[クラス (コンピュータ)|クラス]]と[[インスタンス]]が型と値の役割に固定されてインスタンス化の相互再帰が無くなったことから、インスタンスのみがオブジェクトになっている。[[メタクラス]]はクラス構成の動的変更機能になっている。これは(1)の事実上の撤廃であった。
23行目: 23行目:


== 概要 ==
== 概要 ==
[[Self]]とは少し別の切り口から、[[Smalltalk]][[クラスベース]]設計の平易化を図った{{仮リンク|ダグラス・クロックフォード|en|Douglas Crockford}}は、[[JavaScript]]のプロトタイプベースをこのように概略している<ref>{{cite web|last=Crockford|first=Douglas|title=Prototypal Inheritance in JavaScript|url=http://crockford.com/javascript/prototypal.html|access-date=22 June 2021}}</ref>。{{Quotation|You make prototype objects, and then … make new instances. Objects are mutable in JavaScript, so we can augment the new instances, giving them new fields and methods. These can then act as prototypes for even newer objects. We don't need classes to make lots of similar objects… Objects inherit from objects. What could be more object oriented than that?<br/>(あなたはプロトタイプ・オブジェクトと新しいインスタンスを作る。オブジェクトは変幻自在でフィールドとメソッドを加えて拡充できる。これもまた新生オブジェクトのプロトタイプになる。クラスは必要ない。オブジェクトも同様に継承できるからだ。これ以上のオブジェクト指向があるだろうか?)}}プロトタイプベースはプログラマに、オブジェクトをどう振る舞わせるかということのみに集中させて、オブジェクトが実際に振る舞えるかどうかの疑問を後回しにできる環境を提供する<ref>{{Cite journal|last=Taivalsaari|first=Antero|last2=Noble|first2=James|date=1998|title=Thinking with prototypes|url=http://dx.doi.org/10.1145/346852.346949|journal=Addendum to the 1998 proceedings of the conference on Object-oriented programming, systems, languages, and applications (Addendum) - OOPSLA '98 Addendum|publisher=ACM Press|location=New York, New York, USA|doi=10.1145/346852.346949}}</ref>。振る舞いとは[[メソッド (計算機科学)|メソッド]]である。疑問の後回しとは[[動的型付け]]の[[ダックタイピング]]を意味している。プロトタイプベースは[[静的型付け]]の実装を排除してる訳ではないが、その特性と利点を最大限に活かすための[[動的型付け]]が好まれている。
[[Self]]とは少し別の切り口から、[[Smalltalk]][[クラスベース]]設計の平易化を図った{{仮リンク|ダグラス・クロックフォード|en|Douglas Crockford}}は、[[JavaScript]]のプロトタイプベースをこのように概略している<ref>{{cite web|last=Crockford|first=Douglas|title=Prototypal Inheritance in JavaScript|url=http://crockford.com/javascript/prototypal.html|access-date=22 June 2021}}</ref>。{{Quotation|You make prototype objects, and then … make new instances. Objects are mutable in JavaScript, so we can augment the new instances, giving them new fields and methods. These can then act as prototypes for even newer objects. We don't need classes to make lots of similar objects… Objects inherit from objects. What could be more object oriented than that?<br/>(あなたはプロトタイプ・オブジェクトと新しいインスタンスを作る。オブジェクトは変であり、新フィールドとメソッドを加えて拡充できる。これもまた新生オブジェクトのプロトタイプになる。クラスは必要ない。オブジェクトも同様に継承できるからだ。これ以上のオブジェクト指向があるだろうか?)}}プロトタイプベースはプログラマに、オブジェクトをどう振る舞わせるかということのみに集中させて、オブジェクトが実際に振る舞えるかどうかの疑問を後回しにできる環境を提供する<ref>{{Cite journal|last=Taivalsaari|first=Antero|last2=Noble|first2=James|date=1998|title=Thinking with prototypes|url=http://dx.doi.org/10.1145/346852.346949|journal=Addendum to the 1998 proceedings of the conference on Object-oriented programming, systems, languages, and applications (Addendum) - OOPSLA '98 Addendum|publisher=ACM Press|location=New York, New York, USA|doi=10.1145/346852.346949}}</ref>。振る舞いとは[[メソッド (計算機科学)|メソッド]]である。疑問の後回しとは[[動的型付け]]の[[ダックタイピング]]を意味している。プロトタイプベースは[[静的型付け]]の実装を排除してる訳ではないが、その特性と利点を最大限に活かすための[[動的型付け]]が好まれている。


プロトタイプベースのオブジェクトは総じて、スロットの[[可変長配列]]として実装されている。スロットとは「シンボル+コンテンツ」のペアデータである。シンボルは[[プロパティ (プログラミング)|プロパティ]]名や[[メソッド (計算機科学)|メソッド]]名を表わし、コンテンツはプロパティ値や[[コードブロック]]参照を表わす。プロパティスロットはプロトタイプ参照や[[This (プログラミング)|this]]参照(self参照)の容器にもなる。[[Self]]ではメソッドスロットがメッセージ式で送られるセレクタの受け手になる。
プロトタイプベースのオブジェクトは総じて、スロットの[[可変長配列]]として実装されている。スロットとは「シンボル+コンテンツ」のペアデータである。シンボルは[[プロパティ (プログラミング)|プロパティ]]名や[[メソッド (計算機科学)|メソッド]]名を表わし、コンテンツはプロパティ値や[[コードブロック]]参照を表わす。プロパティスロットはプロトタイプ参照や[[This (プログラミング)|this]]参照(self参照)の容器にもなる。[[Self]]ではメソッドスロットがメッセージ式で送られるセレクタの受け手になる。


オブジェクトの構築は、クローンかエクスニヒロで行われる。クローン(clone)は既存オブジェクトを複製する方式であり、複製後にプロパティ/メソッドの自由な取り付け取り外しもできる。エクスニヒロ(ex nihilo)はプロパティ無しメソッド無しの空オブジェクトを生成する方式であり、生成後にプロパティ/メソッドの自由な取り付けができる。[[構造体]]に似た書式でプロパティ/メソッドを初期設定して生成する方式もエクスニヒロに分類されている。[[クラス (コンピュータ)|クラス]]概念がないのでテンプレート処理的なオブジェクト構築は不可であるが、[[クラスベース]]構文が導入された言語では代替的に可能にされている。の代替はエクスニヒロ方で解釈されている。
オブジェクトの構築は、クローン方式かエクスニヒロ方式で行われる。クローン(clone)は既存オブジェクトを複製する方式であり、複製後にプロパティ/メソッドの自由な取り付け取り外しもできる。エクスニヒロ(ex nihilo)はプロパティ無しメソッド無しの空オブジェクトを生成(または複製)する方式であり、生成後にプロパティ/メソッドの自由な取り付けができる。[[構造体]]に似た書式でプロパティ/メソッドを初期設定して生成する方式もエクスニヒロに分類されている。[[クラス (コンピュータ)|クラス]]概念がないのでテンプレート処理的なオブジェクト構築は不可であるが、[[クラスベース]]構文が導入された言語では代替的に可能にされており、はエクスニヒロ方で解釈されている。


クローンで構築されたオブジェクトのプロトタイプ・スロットには、クローン元になったオブジェクトの参照が自動代入される。プロトタイプ・スロットは再代入可能であり、エクスニヒロで構築されたオブジェクトにも、そのプロトタイプにするオブジェクトを自由に追加変更削除できる。プロトタイプは暗黙の[[委譲]]先になり、オブジェクトがアクセス要求されたプロパティ/メソッドを持っていない場合は、そのプロトタイプへと丸投げされる。これは[[継承 (プログラミング)|継承]]相当の機能になる。
クローンで構築されたオブジェクトのプロトタイプ・スロットには、クローン元になったオブジェクトの参照が自動代入される。プロトタイプ・スロットは再代入可能であり、エクスニヒロで構築されたオブジェクトにも、そのプロトタイプにするオブジェクトを自由に追加変更削除できる。プロトタイプは暗黙の[[委譲]]先になり、オブジェクトがアクセス要求されたプロパティ/メソッドを持っていない場合は、そのプロトタイプへと丸投げされる。これは[[継承 (プログラミング)|継承]]相当の機能になる。
33行目: 33行目:
== 脚注 ==
== 脚注 ==
{{Reflist}}
{{Reflist}}

== 参考文献 ==
* {{cite book|first=Martin|last=Abadi|author-link=Martin Abadi|author2=Luca Cardelli|author2-link=Luca Cardelli|title=A Theory of Objects|publisher=Springer-Verlag|year=1996|isbn=978-1-4612-6445-3}}
* [http://www.laputan.org/reflection/warfare.html Class Warfare: Classes vs. Prototypes], by Brian Foote.
* {{cite book|editor1-last=Noble|editor1-first=James|editor2-last=Taivalsaari|editor2-first=Antero |editor3-last=Moore|editor3-first=Ivan|year=1999|title=Prototype-Based Programming: Concepts, Languages and Applications|publisher=Springer-Verlag|isbn=981-4021-25-3}}
* [http://web.media.mit.edu/~lieber/Lieberary/OOP/Delegation/Delegation.html Using Prototypical Objects to Implement Shared Behavior in Object Oriented Systems], by Henry Lieberman, 1986.


== 関連項目 ==
== 関連項目 ==
44行目: 50行目:


{{プログラミング言語の関連項目}}
{{プログラミング言語の関連項目}}

{{DEFAULTSORT:ふろとたいふへえす}}
{{DEFAULTSORT:ふろとたいふへえす}}
[[Category:オブジェクト指向]]
[[Category:オブジェクト指向]]
[[Category:型理論]]

2021年8月29日 (日) 09:28時点における版

プロトタイプベース (: Prototype-based) は、オブジェクト指向プログラミング(OOP)のスタイルのひとつであり、オブジェクトの生成に既存オブジェクトのクローン(複製)を用いるスタイルを指している。これには直後にメンバを拡充するための空オブジェクトの複製も含まれている。このスタイルはインスタンスベース(Instance-based)とも呼ばれている。これと対比されるOOPスタイルにクラスベースがある。クラスインスタンス化と、オブジェクトのクローンは、明確に異なる概念だったのでスタイル分けされる必要があった。プロトタイプベースOOPの原点はSmalltalk方言のSelfであり、Smalltalkのクラスベース設計を平易化する試みから1987年に誕生している。他にはLua、NewtonScript、JavaScriptEtoysECMAScriptREBOLIoTypeScriptなどがあるが、クラスベースOOPに比べると採用言語が少ないマイノリティに留まっている。

プロトタイプとは、クローン元になったオブジェクトを意味しており、クローン先のオブジェクトから見てそう呼ばれる。プロトタイプは同時にそのオブジェクトの暗黙の委譲先になり、これは継承におけるスーパークラス相当として扱われる。プロトタイプベースは動的型付けに準拠していることから、オブジェクトの情報隠蔽に伴なうカプセル化は軽視されていることが多い。ポリモーフィズム動的型付けによる動的バインディングと、プロトタイプ委譲チェーン上のネームマスキング(ドミナンス英語版とも)が主体である。プロトタイプベースでメソッドオーバーライドと説明される機能は、正確にはネームマスキングである。

来歴

プロトタイプベースは、Smalltalkクラスベース設計を平易化する試みから考案されたスタイルなので、Smalltalkを知らないとそれが作られた理由も分からなくなる。Smalltalkの設計はアラン・ケイによって以下の六項目に概略されており、ここではクラスベースに関連した要点のみを和訳する[1]

1, EverythingIsAnObject.(全てはオブジェクトである)

2, Objects communicate by sending and receiving messages (in terms of objects).

3, Objects have their own memory (in terms of objects).(オブジェクトは自身の記憶を持つ)

4, Every object is an instance of a class (which must be an object).(全てのオブジェクトはクラスのインスタンスであり、クラスもオブジェクトである)

5, The class holds the shared behavior for its instances (in the form of objects in a program list).(クラスはそのインスタンス共有の振る舞いを持つ)

6, To eval a program list, control is passed to the first object and the remainder is treated as its message.

(4)は数学的帰納な文章であり、オブジェクト=インスタンスのひな型であるクラスもまたメタクラスのインスタンス化であり、そのメタクラスもまた他のメタクラスのインスタンス化と解釈される。(3)で記憶はクラスとインスタンス双方にあるが、(5)で振る舞いはクラスのみとされており、これが混乱を招きやすいネックになっていた。Smalltalkの元祖クラスベース設計は公開後間もなくして開発陣からも不評になり、それは概ねクラスとインスタンスに対する振る舞い(behavior)の在り方の差異に起因していた。その改善策としての、オブジェクトからクラスインスタンスの概念を撤廃してしまおうという案が、プロトタイプベースの原点になっている。この案は言語実装視点では、クラスを無くしてインスタンスに一律化するとも解釈できるので、インスタンスベースと別称された。Selfはこの案に沿って制作されたSmalltalk方言であった。ここでは(1)の遵守が第一にされていた。

なお、C++/Python以降のクラスベース設計では、クラスインスタンスが型と値の役割に固定されてインスタンス化の相互再帰が無くなったことから、インスタンスのみがオブジェクトになっている。メタクラスはクラス構成の動的変更機能になっている。これは(1)の事実上の撤廃であった。

現在では、C++/Python発のクラスベース設計が多くの言語で採用されており、Self発のプロトタイプベースは少数派になっている。のみならずプロトタイプベースの代表格JavaScriptECMAScriptではクラスベース構文が導入されるに到っており、TypeScriptはクラスベースとプロトタイプベースの折衷にされている。プロトタイプベースはやや汎用性に欠けてオブジェクト指向の主流にはなり得なかったという結論になる。

概要

Selfとは少し別の切り口から、Smalltalkクラスベース設計の平易化を図ったダグラス・クロックフォード英語版は、JavaScriptのプロトタイプベースをこのように概略している[2]

You make prototype objects, and then … make new instances. Objects are mutable in JavaScript, so we can augment the new instances, giving them new fields and methods. These can then act as prototypes for even newer objects. We don't need classes to make lots of similar objects… Objects inherit from objects. What could be more object oriented than that?
(あなたはプロトタイプ・オブジェクトと新しいインスタンスを作る。オブジェクトは可変であり、新フィールドと新メソッドを加えて拡充できる。これもまた新生オブジェクトのプロトタイプになる。クラスは必要ない。オブジェクトも同様に継承できるからだ。これ以上のオブジェクト指向があるだろうか?)

プロトタイプベースはプログラマに、オブジェクトをどう振る舞わせるかということのみに集中させて、オブジェクトが実際に振る舞えるかどうかの疑問を後回しにできる環境を提供する[3]。振る舞いとはメソッドである。疑問の後回しとは動的型付けダックタイピングを意味している。プロトタイプベースは静的型付けの実装を排除してる訳ではないが、その特性と利点を最大限に活かすための動的型付けが好まれている。

プロトタイプベースのオブジェクトは総じて、スロットの可変長配列として実装されている。スロットとは「シンボル+コンテンツ」のペアデータである。シンボルはプロパティ名やメソッド名を表わし、コンテンツはプロパティ値やコードブロック参照を表わす。プロパティスロットはプロトタイプ参照やthis参照(self参照)の容器にもなる。Selfではメソッドスロットがメッセージ式で送られるセレクタの受け手になる。

オブジェクトの構築は、クローン方式かエクスニヒロ方式で行われる。クローン(clone)は既存オブジェクトを複製する方式であり、複製後にプロパティ/メソッドの自由な取り付け取り外しもできる。エクスニヒロ(ex nihilo)はプロパティ無しメソッド無しの空オブジェクトを生成(または複製)する方式であり、生成後にプロパティ/メソッドの自由な取り付けができる。構造体に似た書式でプロパティ/メソッドを初期設定して生成する方式もエクスニヒロに分類されている。クラス概念がないのでテンプレート処理的なオブジェクト構築は不可であるが、クラスベース構文が導入された言語では代替的に可能にされており、それはエクスニヒロの方で解釈されている。

クローンで構築されたオブジェクトのプロトタイプ・スロットには、クローン元になったオブジェクトの参照が自動代入される。プロトタイプ・スロットは再代入可能であり、エクスニヒロで構築されたオブジェクトにも、そのプロトタイプにするオブジェクトを自由に追加変更削除できる。プロトタイプは暗黙の委譲先になり、オブジェクトがアクセス要求されたプロパティ/メソッドを持っていない場合は、そのプロトタイプへと丸投げされる。これは継承相当の機能になる。

脚注

  1. ^ The Early History Of Smalltalk”. 2019年1月閲覧。
  2. ^ Crockford, Douglas. “Prototypal Inheritance in JavaScript”. 2021年6月22日閲覧。
  3. ^ Taivalsaari, Antero; Noble, James (1998). “Thinking with prototypes”. Addendum to the 1998 proceedings of the conference on Object-oriented programming, systems, languages, and applications (Addendum) - OOPSLA '98 Addendum (New York, New York, USA: ACM Press). doi:10.1145/346852.346949. http://dx.doi.org/10.1145/346852.346949. 

参考文献

  • Abadi, Martin; Luca Cardelli (1996). A Theory of Objects. Springer-Verlag. ISBN 978-1-4612-6445-3 
  • Class Warfare: Classes vs. Prototypes, by Brian Foote.
  • Noble, James; Taivalsaari, Antero; Moore, Ivan, eds (1999). Prototype-Based Programming: Concepts, Languages and Applications. Springer-Verlag. ISBN 981-4021-25-3 
  • Using Prototypical Objects to Implement Shared Behavior in Object Oriented Systems, by Henry Lieberman, 1986.

関連項目