プロトタイプベース・オブジェクト指向 at TECH
[2ch|▼Menu]
1:デフォルトの名無しさん
03/12/08 21:30
オブジェクトを複製または継承によって生成を行う言語,
プロトタイプベース・オブジェクト指向言語について語りましょうよ.

関連リンク >>2


2:デフォルトの名無しさん
03/12/08 21:31
2

3:デフォルトの名無しさん
03/12/08 21:32
プロトタイプベース・オブジェクト指向とは
URLリンク(sumim.no-ip.com:8080)

Google Directory Prototype-based
URLリンク(directory.google.com)

Self
URLリンク(research.sun.com)

Cecil
URLリンク(www.cs.washington.edu)
URLリンク(www.kmonos.net)

Cel
URLリンク(www.redwoodsoft.com)

Io
URLリンク(www.iolanguage.com)

soopy
URLリンク(soopy.sourceforge.jp)


4:デフォルトの名無しさん
03/12/08 21:32
Water
URLリンク(www.waterlanguage.org)

OScheme
URLリンク(koala.ilog.fr)

Agora
URLリンク(prog.vub.ac.be)

Brain
URLリンク(brain.sourceforge.net)

Obliq
URLリンク(www.luca.demon.co.uk)


5:デフォルトの名無しさん
03/12/08 21:32
えへへ

6:デフォルトの名無しさん
03/12/08 21:34
>>2
プロトタイプベースが普及しない理由を述べよ


7:2
03/12/08 21:36
>>6
俺が使ってないから。

8:デフォルトの名無しさん
03/12/08 21:47
OSchemeってのはなんか面白そう

9:デフォルトの名無しさん
03/12/08 22:18
世の中には「やわらかい言語」と「カタイ言語」がある.
やわらかい言語は動的で自由度が高い言語だ.
カタイ言語は静的で制限を設けることによって安全性と効率を得ている.
どっちも一長一短だ.
プロトタイプベースはクラスベースよりやわらかい.


10:デフォルトの名無しさん
03/12/08 22:19
プロトタイプベースはクラスベースより純粋なオブジェクト指向を実現している.
クラスってあまり綺麗な概念じゃないと思うんだけどどうよ?
全てオブジェクトでいいじゃん.
というとクラスもオブジェクトですって答えが返ってくるかもしれないが,
その構造が初心者を混乱させている.
クラスはオブジェクトで,でもオブジェクトはクラスに属している…


11:デフォルトの名無しさん
03/12/08 22:24
クラスのインスタンスをオブジェクトと呼ぶからややこしくなるのだ。

12:デフォルトの名無しさん
03/12/08 22:40
>>11
いや,用語なんかよりもっと根本的問題だと思う.
URLリンク(www.ogis-ri.co.jp)
これが,Smalltalkのクラス構造…
こんなんで,everything is an object, it's beautiful! とか言ってんの.もう見てらんない.


13:デフォルトの名無しさん
03/12/08 22:56
循環構造とトートロジーは違うんですか?

14:デフォルトの名無しさん
03/12/08 23:18
市販 PDA のメイン言語だった NewtonScript が抜けてるじょ。。
あと ECMA Script も。
(こういう商売っ気あるのは面白くないのはわかるけど)。


15:デフォルトの名無しさん
03/12/08 23:21
Singleton みたいに単一インスタンスしか作らないクラスなんかを書いていると、
プロトタイプベースの方が現象を純粋に抽象化してるって感じがする。

クラスの概念はモデル化ではなくって(効率を維持した)アルゴリズム記述の容易さ
のためにあるような気がする。

16:デフォルトの名無しさん
03/12/08 23:21
>>6
ECMA Script (JavaScript) なんか非常に普及していると思うけど。

17:デフォルトの名無しさん
03/12/08 23:28
でもプロトタイプベース言語としてのJavaScriptじゃないっしょ?


18:デフォルトの名無しさん
03/12/08 23:35
>>15
そう.
クラスってイデアみたいなもんだよね.
モデルのモデルについて記述しているわけだ.
まぁイデア論は話としては面白いけど空想なわけで,現実のモデル化にクラスはいらないだろう.
もちろん素直なモデル化を妨げるとしても捨てられない利点があるから使われるんだけど.
俺は言語ヲタなので概念的な美しさを第一に考えちゃう.
C < Pascal
C++ < Java
CommonLisp < Scheme
Smalltalk < Self
と思うわけですよ.この気持わかるでしょ?

19:デフォルトの名無しさん
03/12/09 01:01
>>14 こんなもんでしょうか.
JavaScript デス
スレリンク(tech板)

ECMAScript
URLリンク(www.ecma-international.org)

NewtonScript
URLリンク(wsmith.best.vwh.net)
URLリンク(www.cc.gatech.edu)

ECMAScriptの実装ってけっこうあるんだね.勉強せねば.


20:デフォルトの名無しさん
03/12/09 01:07
ECMAScriptは独自のオブジェクトを生成できるのか?
JavaScriptをみたところではとてもそんな機能があったようには見えないのだが・・・。
ECMAScriptになってから変わったと?

21:デフォルトの名無しさん
03/12/09 08:22
面白そうなスレ、乙>1

>>20
ずっと前からあるよ。
ECMAになってから大きい変化は例外かな?

function MyObject(name)
{
this.name = name;
}
MyObject.prototype.hello = function(){ return "hello"; }
o = new MyObject("hoge");
o.hello();

他にも静的スコープ、クロージャはあるし、関数もオブジェクトで
さまざまなプロパティがあったりと、けっこう面白いよ。

22:デフォルトの名無しさん
03/12/09 16:39
>>17
Mozillaの中身はそれっぽい使いかたしてるな。

23:デフォルトの名無しさん
03/12/09 22:23
soopyがシンプルでちょっといい感じだ。

24:soopy
03/12/10 22:43
{
fun main(){do: println "Hello, World!";};
} main();

上の文は、{ と }に囲まれた部分がオブジェクトを表していて、
そのオブジェクトにmainというシンボルを送っています。
オブジェクトにシンボルが送られると、そのオブジェクト内の
同じ名前の要素が返されます。この場合、mainという名前の
関数(実際にはクロージャ)が返ってきます。
 そして、返ってきた関数にさらに()=ヌル・オブジェクトを
メッセージとして送ることにより、関数が実行されます。
(URLリンク(soopy.sourceforge.jp))

かっこいい!
メッセージモデルが素直に説明できる.
一般的なOOPLのメソッド起動も引数指定もメッセージに統一されてる〜


25:デフォルトの名無しさん
03/12/11 01:59
>>18
でもSelfってスロットのモデルがすっきりしないんだよね。
SmalltalkのClass, Metaclass周りのグジャグジャと同じぐらいグジャグジャ。

26:デフォルトの名無しさん
03/12/11 18:28
あまり言及されてないけど、
>soopyの構文は非常に単純です。大きくわけると次の5種類だけです。
とあるのに、結局は
>do:
とかの特殊な意味付けの構文(プロパティ?)が色々あるのって、
なんか騙されてる気がするのだが(w
大別してifとloopの2種類ってことらしいけど、
制御構造はまだまだ考慮の余地が残されてる様な。
まそれはおいといて、
メソッド周りの作りは良くまとまってると思った。

27:デフォルトの名無しさん
03/12/11 18:56
>>26
>>do:
>とかの特殊な意味付けの構文(プロパティ?)が色々あるのって、
>なんか騙されてる気がするのだが(w
書きやすさ、読みやすさに配慮したからでしょう。
あなたなら、どうする?

>制御構造はまだまだ考慮の余地が残されてる様な。
>まそれはおいといて
例外も意外とショボイ。でもパターンマッチがある(w
まあ後は自分で作れということでしょう。


28:デフォルトの名無しさん
03/12/12 02:35
>>23
println "Hello, World!"

で、"Hello, World!" がメッセージというのにはちょっとびっくり。
do: と同様に、従来のALGOL系文法の手続き型言語に馴染んだ人が
逆にびっくりしないような配慮が多くなされている言語のようですね。

個人的には Io に注目しています。SelfのいいとこどりのNewtonScriptの
さらにいいとこどりのような言語で、非同期メッセージ送信までサポート
しています。難点は、Selfと同様、ググったときに欲しい情報になかなか
行き当たらない名前ってところでしょうか(^_^;)。

29:デフォルトの名無しさん
03/12/12 13:43
 NewtonScriptで思い出したんですが、プロトタイプベース言語だと
UIレイアウト等のデータ構造記述に混ぜてコードを書けるのが面白い
ですよね。

myArray := [
 { label: "小さいつづら" doIt: func() begin game.over(); end },
 { label: "大きなつづら" doIt: func() begin game.add5points(); end }};


とか。

30:Io
03/12/12 17:57
Io日本語リソースです.ありがたいですなぁ.
今度じっくり読もっと.

+ プログラム言語 Io のはなし
URLリンク(f21.aaacafe.ne.jp)

+ プログラミング言語Io リファレンスマニュアル
URLリンク(user.ecc.u-tokyo.ac.jp)


31:デフォルトの名無しさん
03/12/12 21:41
>>17
そう。しかもECMAScript4とかになると結局クラスが入ってくるしねぇ。
なんだか残念だ。せっかく綺麗な言語なのに。

>>30
どーでもいいがURLとタイトルが逆だぞ。

32:Io
03/12/12 21:50
うわっ かっこわるぅ…
>>31 指摘どうも.
大変失礼しました.貼り直しです.

+ プログラミング言語Io リファレンスマニュアル
URLリンク(f21.aaacafe.ne.jp)

+ プログラム言語 Io のはなし
URLリンク(user.ecc.u-tokyo.ac.jp)


33:デフォルトの名無しさん
03/12/12 22:25
Embedding vs Delegation
多いに語ってくれ

34:デフォルトの名無しさん
03/12/12 23:26
Embeddingって何?

35:デフォルトの名無しさん
03/12/12 23:40
Embedding: あるオブジェクトからメソッドを抽出し,自己に組み込む
Delegation: あるオブジェクトの参照を保持しておき,
自己のメソッド起動をそのオブジェクトのメソッド起動に置き換える
という感じかな? メソッドで表現すれば.
俺は動的フェチなんでDelegationのが好きだなぁー


36:デフォルトの名無しさん
03/12/13 11:28
>>21
そういう意味での独自のオブジェクトか。
既存のオブジェクトの雛形しか使えないことに変わりないわけだね。

37:デフォルトの名無しさん
03/12/13 12:01
>>36
>既存のオブジェクトの雛形しか使えないことに変わりないわけだね。
プロトタイプベースなんですけど。。
独自のオブジェクトって、たとえばどういうの?

38:デフォルトの名無しさん
03/12/13 12:03
>>35
その方向性なら Forwarding も対象に入るんじゃない?

39:デフォルトの名無しさん
03/12/15 14:27
>>35
文法や表現形式はともかく、
意味論的には行った先での self (this) が誰をさしているか、
といった違いになりますか?

>>36
ちょっと意味がわからないので、何か具体例を挙げて話してくれるとうれしい。
"class" っていうキーワードを使ってないからダメ、だとか。

40:デフォルトの名無しさん
03/12/15 14:42
>>39
> 意味論的には行った先での self (this) が誰をさしているか、

(プロトタイプ指向で一般的な)動的型付の場合にはそれでいいと思う。
静的型付した時にはその限りでないと思う。


41:デフォルトの名無しさん
03/12/17 08:17
cecil やってる人がいるよ。

URLリンク(www.kmonos.net)

42:デフォルトの名無しさん
03/12/23 11:25
URLリンク(www.kmonos.net)

43:デフォルトの名無しさん
03/12/24 00:44
>41-42
>>3

44:41
03/12/24 01:16
>>43
書き込んでから気付いた・・・。

それにしても、スクリプト言語ばっかりだねぇ。

45:デフォルトの名無しさん
03/12/24 13:51
ああっ、こんなスレッドができていた!
プロトタイプベースの言語はJScript(苦笑)しか知らないけれど、大好きだよ。

Javaの仕事をした後、JScriptを書いていると、その素晴らしい自由自在さに
コルセットが外れていくような解放感があるよ。

それと同時に、2chのJavaScriptスレッドの「すぐ目先の実用一点張り」な様子は
とても残念だよ。こんなにきれいで面白い言語なのに。

>>31
激しく同意。クラス導入に反対!

46:デフォルトの名無しさん
03/12/25 16:35
Newtonもってる。だれかおもろいアプリ書いてくり!

47:デフォルトの名無しさん
03/12/30 20:21
age tokuyo


48:デフォルトの名無しさん
04/01/04 09:57
URLリンク(www.ipsj.or.jp)

学校教育用オブジェクト指向言語「ドリトル」。Java 上で動くプロトタイプベース
言語らしい。

49:デフォルトの名無しさん
04/01/04 10:01
URLリンク(kumiki.c.u-tokyo.ac.jp)

ついで。Ruby で実装した Self ライクな環境 SeRuby というのがあるらしい。

50:デフォルトの名無しさん
04/01/04 13:27
>>48
LOGOのOO版みたいなもんですね.
論文は会員じゃなきゃ見れないので…
URLリンク(www.logob.com)


51:デフォルトの名無しさん
04/01/04 14:10
>>50
Squeakみたいだね
似たようなことアラン・ケイが小学生にさせてたのを教育テレビで見たことある

52:デフォルトの名無しさん
04/01/07 01:29
JavaScriptは本物のプロトタイプベース言語とは言えないと思う。

var obj = new Object();
と書いて生成された obj が参照するプロトタイプは、
obj.prototype ではなく、
Object.prototype だ。

だから、オブジェクトのプロトタイプを、生成された個々のオブジェクトごとに
変更することができない。プロトタイプの変更は、同一のコンストラクタから生成された
オブジェクトすべてに影響が及んでしまう。

プロトタイプをオブジェクトごとに、自由に変更できるようにするためには、
オブジェクト一つごとにコンストラクタを一つずつ、用意しなければならない。

まるでクラスベースの型制約に近い不自由さを感じるのだけど。

こんな風に書けたらよかったのに。
var obj;
obj.foo = function(){ alert("ふー!"); };
var obj2;
obj2.prototype = obj;

obj2.foo(); // "ふー!" と表示。

どうしてこうならなかったんだろう?

53:デフォルトの名無しさん
04/01/07 06:35
>>24 のリンク先だけど、soopy では、

>println がオブジェクト、"Hello, World!"がメッセージになります。

println が組み込みオブジェクトだからこういう語順になっている訳だけど、
個人的には Ruby みたいに、"Hello, World!" println のスタイルの方がしっく
りくる。文字列オブジェクトにプリントメッセージを送信て感じ。
soopy 方式は Lisp っぽい(writeline "Hello World!")。

出力先をオブジェクトにして、文字列オブジェクトをメッセージの引数に
している言語もあるね。
Smalltalk は Transcript show: 'HelloWorld!'.
Java も Sysem.out.println("Hello World!")
C++ も cout << "Hellow World!" で Smalltalk と語順的には一緒。

これを、引数渡しのところもメッセージ送信に出来ないかな。ついでに
改行自体もメッセージ式に。
output-port [ "Hello World!" print ]; newline みたいな。
[ "Hello World!" print ] が何を返すべきなのか分からんけど。

54:53
04/01/07 07:40
前のレス、最後のところは無しにして下さい。

println が、オブジェクトなのか、文字列オブジェクトに対するメッセージなのか、
出力先オブジェクトに対するメッセージなのか、言語によって捉え方が色々で
面白いなぁと。

調べてみたら、Smalltalk では「show: 'Hello World!'」で一つのメッセージという
カウントをしてるんですね。

55:デフォルトの名無しさん
04/01/07 08:20
>>52
ECMAScriptではなくてJavaScriptと書いてあるのでJavaScriptの話をすると、

> var obj = new Object();
> と書いて生成された obj が参照するプロトタイプは、
> obj.prototype ではなく、
> Object.prototype
でもなく、
obj.__proto__ だ。

var obj = {}
obj.foo = function(){ print("ふー!"); }
var obj2 = {}
obj2.__proto__ = obj
obj2.foo(); // "ふー!" と表示。

56:デフォルトの名無しさん
04/01/07 08:37
あとちなみに、ECMAScript (3rd) だと、
obj = new Object() の参照するプロトタイプは
obj.prototype ではなく Object.prototype ではなく、 obj.[[prototype]]。
スクリプトからは明示的な読み出しも書き換えもできないので
困る、っちゅーのはその通り。

57:52
04/01/08 01:12
>>55-56
おお、詳しい方ですね!__proto__なんて、昔オライリーのサイ本でチラッと
目にして以来忘れていました。
NN7で試したら、動きました。今でもちゃんと動くんだなあ。
IEで動かないのが残念。

あつかましくて恐縮ですが、質問させてください。

1.obj.[[prototype]]の二重カッコはどういう意味なのでしょうか?

2.ECMAScriptは、どうしてプロトタイプを明示して読み書きできないという、
 プロトタイプベースの発達の制限をしているのでしょうか?
 どういう設計思想なのでしょう?
 私はプロトタイプをもっと自由に使いたいのに。

58:52
04/01/08 01:32
プロトタイプを、例えばどんな風に使いたかったかというと、

画面にたくさんのテキストフィールドがあって、
それのイベントハンドラをいっせいに切り替えるようなこと。
画面のモードによって、いっせいにフィールドの挙動を変えるようなこと。

まず↓のようにセットしておけば、
var common;
var proto1;//たくさんのイベントハンドラが定義してある。
var proto2;//同様に定義してあるが、各イベントハンドラの内容は上と異なる。

for (var form in document.getElementsByTagName("INPUT")){
form.prototype = common;
}

↓のように、ごく簡単に複数のオブジェクトの挙動を変えられる。
common.prototype = proto1;//モード1の動作をセット。
common.prototype = proto2;//モード2の動作に変更。

こうなってたら、とても面白かったと思うのですよ。残念だなあ。

59:55
04/01/08 13:16
>>57
> 1.obj.[[prototype]]の二重カッコはどういう意味なのでしょうか?

「内部プロパティ」のつもり。意味論的にはオブジェクトのプロパティの
一つなんだけど、言語内では触ることのできないシロモノ。
URLリンク(www2u.biglobe.ne.jp)

> 2.ECMAScriptは、どうしてプロトタイプを明示して読み書きできないという、
>  プロトタイプベースの発達の制限をしているのでしょうか?

実装の最適化のためだと思うよ。「あとから定義が変更できるクラス」
程度の柔軟性が残ってさえいれば、あとはできるだけ高速化しやすい
仕様を選んだんじゃないかと。知らんけど。

60:52
04/01/09 01:25
>>59
ありがとうございます。実装の最適化ですか…。
私は、クラスベースの言語の挙動に似せるためだと思っていました。
具体的にはJavaですね。
一般のプログラマは、非常に保守的ですから。

Java自体、最初はOAKという、FORTHに似た構文の言語だった時には全く人気が出ず、
Cに似た構文を採用してJavaとなってからやっと使われるようになったといいます。
(しかしJavaは5年ぐらいは、「ポインタ演算のできないC」として扱われた)

LiveScript -> JavaScriptも、Javaとの共通性を(ニセのイメージだとしても)打ち出さ
なければ、普及しなかったのじゃないかなと思うのです。
プロトタイプベースの言語は、そのシンプルな美しさに関わらず、いまや絶滅寸前
ですから。

あまりにも自由自在にすると、クラスベースにある堅牢さから遠ざかり、プログラマから
好まれないのではないか、と設計者が考えたのではないかと私は思っていました。

いずれにせよ、私は現状を残念に思います。今のECMAScriptは、貧者のJavaに過ぎない。

61:デフォルトの名無しさん
04/01/09 02:52
固く考えすぎだと思うんだけどなぁ。
「プロトタイプ指向かくあるべき」という先入観を捨ててから、もう数ヶ月ECMAScriptを使い込んでみて欲しい。

・ECMAScript は JavaScript(Netscape) と JScript(IE) の仕様摺り合わせとして
 策定されたもの。そして JScript には __proto__ が実装されていなかった。それだけだ。
 ECMAScript1.0が出た頃には、普及も何も、既にWWWのクライアントサイド言語としてシェアをほぼ全制覇していたし。

> プロトタイプベースの言語は、そのシンプルな美しさに関わらず、いまや絶滅寸前ですから。
・絶滅という言葉が使えるほど栄光の時代があったパラダイムではないと思うんだけど。
 逆に今ならJavaScript があるし、ActionScript (Flash) がある。プロトタイプチェーンくらいはmetatableで
 簡単に実装できるだけの柔軟性をもったLua言語も最近流行し始めた。

 もちろん各言語のほとんどのユーザはプロトタイプ指向を用いては
 いないだろうけど、それでもSelfしかなかった頃と比べたら、今や
 プロトタイプな人の数は雲泥の差だ。

62:52
04/01/10 00:21
>>61
うーん、少々舌足らずだったかも知れません。
ECMAScriptがJavaScriptとJScriptのすり合わせで成立していることは承知している
つもりなのです。
ではなぜ、JScript、JavaScriptがこのような言語になったのでしょうか?
JScriptではプロトタイプはコンストラクタからしかアクセスできず、
JavaScriptでも__proto__は元々隠し機能であり、いつ廃止されるかわからない
状態だった。
それはやはり言語設計者が、プロトタイプを自由に扱わせることに、この言語の普及において
メリットよりデメリットを感じたからだと思うのです。馴染みにくいから。

また、そういうニーズは少ない。ネットを見回すと、JavaScriptでオブジェクト指向を
実現しようとする試みはたくさん見つかりますが、そのほとんどが「いかにしてJavaと
同じ事をするか」に腐心しています。それに対して、JScriptがプロトタイプを公開して
いないことに対する不満を主張するサイトは、私はまだ一度も見たことがありません。

プロトタイプベースの言語が世に広まってきたとは言え、そのほとんどのユーザにその意識が
無いままでは、いつまでも「Javaより貧弱な言語」と見なされるだけで終わってしまうのでは
ないかと思うのです。


63:52
04/01/10 00:22
などと大上段に構えたことを言っておりますが、実は私もつい数ヶ月前までは、プロトタイプ
ベースなんて意識することもありませんでした。
今書いたようなことは、Googleで偶然に
URLリンク(squab.no-ip.com:8080)
このあたりにたどり着いて、中途半端に感化されてしまっただけのことなんです。
すみません。

ただ、今まで オブジェクト指向 = クラスベース としか思っていなかった私には、
まさに目からウロコだったのです。
プロトタイプによる委譲という単純な仕掛けだけで、クラスベースと同等以上の
記述性をもった言語が成立するというのが新鮮だったのですね。
年季の入った人からは稚拙な主張だと思います。

だから、皆さんがプロトタイプベースの言語とどのように付き合っているのか、
お聞かせ願えたらと思います。
例えば、ECMAScriptはこう書けば、このように自由なことができる、とか。
この言語は、このように便利だ、とか。

64:デフォルトの名無しさん
04/01/10 19:53
誰も使ってない

65:デフォルトの名無しさん
04/01/10 21:53
井戸の中に蛙が一匹

66:デフォルトの名無しさん
04/01/10 22:46
効率悪そうだな。

67:デフォルトの名無しさん
04/01/15 19:58
実行効率?なんで?

68:デフォルトの名無しさん
04/01/15 19:59
でも、大規模システムの開発効率は悪そうだな。型機能が不足な分。

69:デフォルトの名無しさん
04/01/15 20:05
いまIoとか絶滅どころかめちゃめちゃアクティブじゃんよ

70:デフォルトの名無しさん
04/01/15 21:14
>>45
JavaScriptは、使われ方からユーザがほとんど厨ユーザだからね。
おまいみたいなヤシばっかだったらいいのに。

71:デフォルトの名無しさん
04/01/15 21:39
あっちのスレは、Web政策版と棲み分けようと努力しているよ。
あとからあとから厨が乱入してくるけど。

72:デフォルトの名無しさん
04/01/15 22:20
他人がスクリプトをどう使うかについて文句を言える筋合いはないが、
実用本位で使うから房っていうのは(もしその意図があるなら)頂けないな。
まあ高邁な学者さんのようなご意見だとは思うけどね。

73:デフォルトの名無しさん
04/01/16 23:06
>>66
Self は JIT で結構速いらしいよ。
プロトタイプ言語のオーバーヘッドは結構大きそうな感じはするけどね。

74:デフォルトの名無しさん
04/01/19 02:27
>>72
そうばかりは言えないよ。あなただって、Java で COBOL みたいなコーディングを
している人がいたら「もうちょっと言語を理解して使ったほうがいいんじゃないの?」
と思うでしょ?


75:デフォルトの名無しさん
04/01/19 02:28
ちょっと JavaScript の話。

別にコンストラクタをたくさん用意しなくても、プロトタイプを自由に変えることは
できる。生成されたオブジェクトが参照するのは、 new されるときにコンストラクタが
保持していたオブジェクトだから。

var Factory = function(){}; //共通のコンストラクタ

//プロトタイプとなるオブジェクト
var a = { foo: function(){ alert("foo A!"); } };
var b = { foo: function(){ alert("foo B!"); } };

//a をプロトタイプとするオブジェクトを生成
Factory.prototype = a;
var a0 = new Factory;

//b をプロトタイプとするオブジェクトを生成
Factory.prototype = b;
var b0 = new Factory;

a0.foo();//「foo A!」と表示
b0.foo();//「foo B!」と表示

76:デフォルトの名無しさん
04/01/19 02:35
>>72
厨なコードを「実用本位」と呼ぶことは、本当に実用になるコードを書く職人さんに失礼。

77:75
04/01/19 02:40
こう書くと、デザパタに慣れた人は、
これが FactoryMethod パターンと State パターンを組み合わせたものに
近い、と感じられないかな。
a と b が State ね。

オブジェクト指向言語には、既存のオブジェクトの機能を利用して新しいオブジェクトを
作る方法が、大きく分けると2つある。「継承」と「委譲」。

クラスベースの言語は、言語レベルで「継承」をサポートし、
プロトタイプベースの言語は、言語レベルで「委譲」をサポートしたものだと
言えると思う。

上と似た動作のコードは Java でも書けるけど、かなり煩雑になる。

78:75
04/01/19 02:56
ということで、蛇足なんだけど、
JavaScriptは、せっかく言語レベルで委譲をサポートしているのだから、委譲を中心に
活用するのが良いと思う。
Java の真似をして、継承という枠組みで使うのは、無理があるし、もったいない。

79:デフォルトの名無しさん
04/01/19 03:18
委譲っていう概念自体が、既存の静的なクラスをベースとした言語を基礎にしてる
気がする。

80:デフォルトの名無しさん
04/01/19 04:12
>>79
なんで?クラスなんて全然関係ないじゃん。

81:79
04/01/19 07:48
>>79
s/言語を基礎に/言語を背景に/

82:デフォルトの名無しさん
04/01/19 23:32
意味不明.
委譲の発祥がクラスベースって言うんだったら
そもそも最初のOOPLがクラスベースだったんだから(ry


83:デフォルトの名無しさん
04/01/20 01:12
クラスベースの多重継承の代替物というイメージが強いからじゃ?
そもそも漏れみたいな厨は、それが委譲のオリジンだと思ってた。

84:デフォルトの名無しさん
04/01/20 03:04
継承と委譲についてだけど、どちらも、
「あるオブジェクトが、自分の実装していない機能があったとき、別のオブジェクトから
 それを借りてくる」
という点では変わらない。

で、継承は、オブジェクトを作る金型(クラス)の間で、機能の貸し借りをするの
だけど、
委譲は、実際に生成されたインスタンスの間で、機能の貸し借りが行われる。

型なし言語(だった)JavaScriptが委譲を採用しているのは、まあ当然かも。

85:デフォルトの名無しさん
04/01/20 03:09
>>84
> 型なし言語(だった)JavaScriptが委譲を採用しているのは、まあ当然かも。

型とクラスが混ざってないかい?

86:デフォルトの名無しさん
04/01/20 03:23
あと、無粋なツッコミですまんが、>>83
プロトタイプ・チェインはむしろ単一継承にたとえられることが多いはず。
多重継承は、一回の継承で複数個の親クラスを持つことでしょ?

歴史的経緯については私も知らない。すまん。

87:デフォルトの名無しさん
04/01/20 03:28
>>86
あー、俺は83じゃないが、たぶん83が言いたいのは、
単一継承のOOPLで多重継承的なことをやるために委譲が使われた、
みたいな感じのことだと思われ。

88:デフォルトの名無しさん
04/01/20 03:29
>>85
ん?あなたが言っている型というのは、プリミティブ変数の型のことかい?
私はクラスを、オブジェクトの型として構わないと思うのだけど。
さしさわりがあったら、教えてほしい。

89:デフォルトの名無しさん
04/01/20 03:32
>>87
なるほど、了解。これは私の読み違いだったか。

90:デフォルトの名無しさん
04/01/20 03:35
>>88
例えばJavaにはオブジェクトの型としてインターフェイス型なんてものあるねえ。

ついでに言えば、Smalltalkはいわゆる型なし言語(正確には動的型付言語)
と言われているが、コテコテのクラスベースOOPLだよ。


91:デフォルトの名無しさん
04/01/20 03:47
>>90
ええと、私は「型」というものを、「変数の、ある機能を保証するもの」と
見なしている。例えば、数値型だったら、四則演算が保証される、というように。

同様に、例えばあるインスタンスがコレクション・インターフェースに属していたら、
それはイテレータによる処理が保証されるわけだから、これをオブジェクトの
型とみなして良いと考えていた。

それに対して、プロトタイプベース言語は、実行するまでその操作が可能か、事前には
分からない。型による保証がない。

こういうイメージで、クラス(ないしはインターフェース)を「型」の一種と考えている
んだけど、まずいだろうか?

92:デフォルトの名無しさん
04/01/20 04:03
>>90
Smalltalk については、知らないのでなんとも言えない。
だけど、型なし言語だったら、プロトタイプベースのほうが自然なんではないか
という気がする。オブジェクトの機能の貸し借りに、クラスというものを介在
させずにすむから。

ということで、機会があったら、勉強してみます。

93:デフォルトの名無しさん
04/01/20 04:15
class と interface とが異なるってことだと思う。

class は C++ みたいな言語での、継承の階層図での位置だよね。
対して interface は、 method とかの集合だと思う。

静的で class-based な言語なら一意に対応するだろうけど、
動的な言語だと interface だけ変えるとか、 class だけ変えるとかができそう。

94:デフォルトの名無しさん
04/01/20 04:53
>>92
> だけど、型なし言語だったら、プロトタイプベースのほうが自然なんではないか
> という気がする。オブジェクトの機能の貸し借りに、クラスというものを介在
> させずにすむから。

どうだろうね。

プロトタイプベースではオブジェクトの型紙としての機能を全オブジェクトに持たせるのに対して、
Smalltalkではオブジェクトの分担をはっきりさせ、
Classクラスのオブジェクトにその機能を集中させて専業させることで
その他のオブジェクトを簡素化している、
とも言えるわけで、

全てのオブジェクトにオブジェクト生成機能を持たせるSelfと
オブジェクト生成機能を特定のオブジェクトに専門化させたSmalltalk。
つまり
比較的単質なオブジェクトの集合としてオブジェクト世界を構築するSelfと
色々な種類のオブジェクトの集合としてオブジェクト世界を構築するSmalltalk。
その一方で、
固定的な種別を排除した雑多なオブジェクト世界を構築するSelfと
クラスという明確な種別による整然としたオブジェクト世界を構築するSmalltalk。
結局はコインの表裏ってとこだよ。

どっちが自然というよりは、モデリングの視点が違っているだけの話だと思う。
あとは趣味の問題。


95:デフォルトの名無しさん
04/01/20 08:38
オブジェクト生成機能って、new とか init, alloc, clone みたいなの?

96:デフォルトの名無しさん
04/01/20 09:00
>>95
まあそんなもの。

属性名とスロットインデックスの対応とかメソッド辞書等の、
オブジェクトの構造や機能に関する情報と、
それを使ってオブジェクトを生成する操作。


97:デフォルトの名無しさん
04/01/20 17:51
>>94-96
なるほどねえ。
プロトタイプベースについて論じるためには、実はクラスベースについても
広くきちんとした知識をもっていなければならないのだなあ。
勉強になりました。

98:デフォルトの名無しさん
04/01/20 17:57
ということで、ややスレ違いで恐縮なんだけど、
>>93のように、Smalltalk って、インスタンスの属するクラスをを動的に変更
できるの?まさか、キャストのことじゃないよね?

インスタンスが生成されたあとでも、その属するクラスを動的に変更できると
したら、プロトタイプベースと同等の自由度だよね?にわかに信じがたい。
もし本当なら、Javaでは信じられない世界だ。

99:デフォルトの名無しさん
04/01/20 21:42
>>97
ここら辺が参考になるかと。
URLリンク(www.shiro.dreamhost.com)
URLリンク(homepage.mac.com)

>>98
CLOS ではオブジェクトが属するクラスを後から変えられるみたい。
Smalltalk では become: というメソッドがあったらしい。
URLリンク(www.sra.co.jp)
URLリンク(blade.nagaokaut.ac.jp)
URLリンク(homepage.mac.com)

>その属するクラスを動的に変更できると
>したら、プロトタイプベースと同等の自由度だよね?
サブクラシングせずに、オブジェクト毎にメソッドを追加/上書き出来ないと
同等じゃないと思う(個人的には)。

私はプログラマでも言語実装者でもないので、全部伝聞でスマソ。

100:1
04/01/20 23:39
100.get!

101:1
04/01/20 23:45
>その属するクラスを動的に変更できると
>したら、プロトタイプベースと同等の自由度だよね?
そこまでしてクラスに拘る理由があるのか疑問.
そうやってどんどんクラスベースに柔軟性を持たせると,
結局プロトタイプベースと同じものになるだろう.
そうなったらクラスという概念が無い方がシンプルでわかりやすい.
自由度と危険性を手に入れたいならクラスという概念はいらないはず.


102:デフォルトの名無しさん
04/01/21 00:03
オブジェクト to オブジェクトのトランスレートなんて頻繁に起こる物じゃないから、
基盤をクラスに置く事は何の不思議もないと思うけど。

103:デフォルトの名無しさん
04/01/21 01:51
>>102
そうかな?
あるオブジェクトのインスタンスがあって、モードによってその動作を
ガラッと変えたい、なんて場合には、ぜひとも既存のインスタンスの
属すクラスを、別のものに変えたいと思うけどなあ。

GUI の設計とかしていると、よくそういうことない?

というか、Java でよく使う Stateパターンって、動的にクラスの
変更のできない言語で、委譲先を変えることによって機能をそっくり
取り替えてしまおう、というものでしょ?
(まあ、メソッドの内容は変えられても、シグナチャは変えられないんだけど)

ということで、今はそんなにクラスの変換は行われていなくても、もし言語が
それをサポートしているなら、需要はいくらでもあると思う。

104:デフォルトの名無しさん
04/01/21 01:53
>>103
自己訂正。
State パターンで変えられないのはシグナチャ、という言い方は不適切だな。
メソッド自体を新設したり、廃止したりということはできない、とすべきだった。

105:デフォルトの名無しさん
04/01/21 02:22
>>98
> ということで、ややスレ違いで恐縮なんだけど、
> >>93のように、Smalltalk って、インスタンスの属するクラスをを動的に変更
> できるの?まさか、キャストのことじゃないよね?

キャストじゃないよ。そもそもSmalltalkは動的型付だからキャストは存在しない。

> インスタンスが生成されたあとでも、その属するクラスを動的に変更できると
> したら、プロトタイプベースと同等の自由度だよね?にわかに信じがたい。
> もし本当なら、Javaでは信じられない世界だ。

とりあえず簡単なやり方としては、

1. 自分相当のオブジェクトを違うクラス(仮にAnotherMyClassと呼ぶ)で生成する。
 newSelf ← AnotherMyClass from: self.

2. 自分をnewSelfにする。
 self become: newSelf.

これで、今までの自分とはサヨナラ、これからの私はAnotherMyClassのオブジェクトです、
となる。

ちなみに>>99さん、become:はまだ生きてますよ。
というか、Smalltalkはこれがないと根本的に動かない。

106:デフォルトの名無しさん
04/01/21 02:51
>>105
素晴らしい!Smalltalk ってそんなに自由なのか!
クラスベースにも、こういう可能性があったのですね!

こんなJava厨の質問に答えてもらって申し訳ない。
ありがとう、>>105の中の人!

107:Java厨
04/01/21 04:22
オブジェクトの各変数(フィールド)はどうなるの?

108:デフォルトの名無しさん
04/01/21 11:16
>>105
#become: を使っているだけに #become: の挙動みたいな説明ですね(笑)。
完璧に化ければそれはもはや本人と見なしてよいか…という問題をはらんでいます。

私は、もともと self に束縛されていたオブジェクト(ここで「被害者」、
今は newSelf に束縛されている)のアイデンティティを擁護する
立場(^_^;)なので、被害者のクラスについてはこの処理を経たあとも
それまでとなんら変わらない事実を踏まえて、Smalltalk のインスタンスに
そのクラスを鞍替えすることは特殊な状況を例外として「できない」
と答えるのは正解かな、と。

特殊な状況とは、そのクラス(仮に Hoge )のインスタンスがひとつしかなく、
そのインスタンスが鞍替えする先のクラス(同じく Hage )のインスタンスが
なく、さらに Hoge 、Hage がサブクラスを持たない場合です。このように
状況を限定すれば、 Hoge become: Hage を使って注目するインスタンスの
「クラスは変わった」と判断してもよいように思います。

| hoge hogeClass hogeO |
hoge _ Hoge new.
hogeClass _ hoge class printString.
hoge o: $o.
hogeO _ hoge o.
Hoge become: Hage.
^ {hogeClass. hogeO. hoge class printString. hoge a}

=> #('Hoge' $o 'Hage' $o)

このようにインスタンスとそのクラスとの委譲関係は自由にはできませんが、
クラスをしてそのスーパークラスとの委譲関係は比較的自由に乗り換えられる
ことは話の流れ的には強調してもよいのかな…、とも。

109:105
04/01/21 12:22
>>108
> 完璧に化ければそれはもはや本人と見なしてよいか…という問題をはらんでいます。

ようするにアイデンティティをどう捉えるのかという問題ですね。
あなたはSmalltalkerのようなのでSmalltalkで答えると、

anOrderedCollection ← OrderedCollection new: 0.
anOrderedCollection addAll: #(1 2 3 4 5)

ここで、2行目の実行前と実行後で、anOrderedCollectionが同じオブジェクトで
あると看倣す人であれば、become:によってクラスを変更できると答えるべきだと
思いますが、いかがでしょう?

> 状況を限定すれば、 Hoge become: Hage を使って注目するインスタンスの
> 「クラスは変わった」と判断してもよいように思います。

クラスオブジェクトにbecome:を使うと色々と後片付けが面倒なんで・・・
不可能とは言いませんが、それこそ特定のクラスに対して、よほど注意しながら
でないと使うべきではない手ではないかと。
#じゃ非クラスインスタンスに対してはbecome:を気軽に乱発していいかというと(ry


110:105
04/01/21 12:47
成り行きとはいえ、スレ違いのSmalltalkネタを書きすぎました。
スレ汚しスマソ。


111:デフォルトの名無しさん
04/01/21 21:28
>>110
いや、ちっとも迷惑じゃないです。
ということで、>>107 について簡単でよいから教えていただけませんか?
私も知りたい。

112:デフォルトの名無しさん
04/01/21 22:53
CLOS についても聞きたいっす。名前だけは見かけるんだけど。
実際どうなんでしょ?柔軟性という点ではプロトタイプベースとタメを
はれるんでしょうか?

113:デフォルトの名無しさん
04/01/22 01:56
>>103
クラスの付け替えは、閉じた環境の中で実装しながら設計するという Smalltalk や
Lisp 特有のニーズだと思っていたけど、そこまで積極的に使いたいなら >>101
言うように最初からプロトタイプベースの言語を使用した方が良いのでは?
クラスは型システムみたいにある種の保証を持たせたり、最適化のポイントとして
使われる場合もあるから、ほいほい変えられるものじゃないと思うけど。
実際初期の Squeak では、オーバーヘッドを考えて become: の使用をなるべく
減らす様な実装にしていたらしいし(処理系依存だけど)。

114:105
04/01/22 14:34
>>111
簡単に言うと、今まで自分を指していた参照がbecome:の引数のオブジェクトを
指すようになるだけなので、今までの自分の各変数はどうにでもなります。
実際の実装はともかくとして、言ってみればシステム中の全参照の中から
自分を指している変数をbecome:の引数のオブジェクトに指し替えてやるだけです。

なので、元のオブジェクトのインスタンス変数から新しいクラスのインスタンスに
どう情報を持ってきてコピーするのかは、>>105の例で言えば、from:の実装次第。
変数名や宣言の順番(スロット位置)や変数の数など、同じでも異っててもいいです。
というか、そのオブジェクトに関係している他のオブジェクトが混乱しなければ
つまり同じようなメッセージに反応できて、同じような意味の振舞いを示せば
あとはどうでもいいのです。(動的型付の強みです)

例えば元のオブジェクトにはstart, endの2つの変数があって、新しいオブジェクト
にはlength, offsetの2つの変数があったとします。たぶんfrom:の実装は
from: anOriginalObject
| aNewObject |
aNewObject ← self new.
aNewObject setLength: anOriginalObject end - anOriginalObject start.
aNewObject setOffset: anOriginalObject start.
↑aNewObject
みたいな感じでしょう。

これで、NewObject from: anOriginalObjectとすると、lengthおよびoffsetが
適切に設定されたNewObjectのインスタンスが生成されます。


115:105
04/01/22 14:37
なお、>>109で出した例はどういう意味かというと、
SmalltalkではOrderedCollectionという可変長配列みたいなクラスがあります。
これはどうやってサイズを可変にしているのかというと、
自分よりちょっと大きなサイズのOrderedCollectionのインスタンスを作って、
中身に自分の中身をザクっとコピーしておいて、
そいつにbecome:するのです。
つまり、厳密に言えばそのオブジェクト自体が可変長なのではなくて、
別のサイズのコピーにbecome:することで「実質的に」可変長になっています。
(多少のサイズの変動はbecome:することなしにfirstIndex, lastIndexで調整しますが)

ここで、新しいOrderedCollectionのインスタンスを作るとき、
新しい大きさに適した別のクラスのインスタンスに変更していくことも可能です。
(現在の実装では、ずっと同じクラスのインスタンスのままです。)
>>109で、OrderedCollectionのサイズ変更前と後とで同じオブジェクトと看倣すの
であればクラスも動的に変更できると看倣すべき、と言ったのは、この意味です。

じゃ、これでこの流れのSmalltalkネタは最後にしますです。
また面白そうなネタがあったら口を挟ませてもらいます。


116:デフォルトの名無しさん
04/01/22 16:16
とある知り合いの言うことには、
「クラスベースのオブジェクト指向言語は
リファレンスマニュアルが書きやすいからいいんだよ」
とても納得した。


117:デフォルトの名無しさん
04/01/23 03:49
>>114-115
予備知識がなくて難しいですが、ある程度分かった気がします。
become: というのは、他のインスタンスを自分のアドレスにコピーすることなのですね?
それなら、オーバーヘッドが大きいのも分かります。
from: の実装次第で、どのようなクラスに変えることができるのも分かりました。
>>108-109 については、正直「なんとなく分かった?」程度ですが、自分としては
一応満足です。さすがにこれ以上はスレ違いでしょうし。

丁寧にご説明いただき、大変ありがとうございました。

118:デフォルトの名無しさん
04/01/24 00:10
プロトタイプベースに対するクラスベースの優位性ってなんですかね?
その一つは型チェックだと思うんだけど、Smalltalkのようなインタプリタだと
その利点もなくなるし、結局なにがいいのかな?

119:デフォルトの名無しさん
04/01/24 01:56
>>118
Smalltalk言語処理系は基本的にコンパイラベースです。Smalltalk環境内であまりに
自在にコードを評価できるので勘違いされがちですが…。いちおう、念のため。

クラスベースのアドバンテージですが、結局は型チェックの例と同様に、ある種の
制約を課すことによる安心感、安定さ、安全性に尽きると思います。

クラスベースとプロトタイプベースをコインの表裏、テーゼとアンチテーゼのように
例える向きもありますが、それよりむしろ、クラスベースはプロトタイプベースが実現できる
システム形態のひとつだと考えるほうがいろいろなことをうまく説明できます。
Smalltalk 処理系を Self で比較的すなおに実装できるのに対して、逆はそうでは
ないことなどは、その良い例でしょう。

120:デフォルトの名無しさん
04/01/24 02:53
-- プロトタイプベース言語、何それ?
ふーん、クラス無いの。静的型チェックも出来ないんだ。
オーバーヘッドも大きそうだし、そんなにころころ挙動が
変わったらドキュメント作る時どうするの。そんなふわふわ
した言語でコーディングなんて出来ないよ。学者さんの研究
じゃないからね。こっちは仕事で納めるコードを書いてるんだ。

って言われない事。

121:デフォルトの名無しさん
04/01/24 02:58
>>119
> Smalltalk 処理系を Self で比較的すなおに実装できるのに対して、逆はそうでは
> ないことなどは、その良い例でしょう。

んなわきゃない(苦笑

122:デフォルトの名無しさん
04/01/24 03:14
>>120
ころころ挙動が変わらないようにプログラム組めば?
プロトタイプベースでももちろんできるけど。
挙動がころころ変わるような柔軟な処理も組めて、
挙動が変わらないプログラムも組める。
ところが、クラスがあると柔軟には組めない。

123:デフォルトの名無しさん
04/01/24 03:16
ていうか、Smalltalkには静的型チェック無いな。w
クラスはあるが。

124:デフォルトの名無しさん
04/01/24 03:24
>>122
> ところが、クラスがあると柔軟には組めない。

どうして?例えばこのスレでも何度か話題に出てるSmalltalkなんかは
実行中にクラス定義を変化させたり、メソッドを定義したりできるじゃん。

それに1クラス1オブジェクトにすればプロトタイプベースと変わらなくなるし、
1クラス複数オブジェクトも可能な分だけ柔軟性があるとも言えるじゃないの?

つーかさ、クラスベースだからとかプロトタイプベースだからとかナンセンスでしょ。
柔軟性をキーワードにしたって、双方にそれぞれの利点と欠点があるわけでさ。

125:デフォルトの名無しさん
04/01/24 04:00
sumin さんとこの wiki に書き込めるようなレベルじゃない自分にとって、
このスレの議論は実にありがたい。
皆さん、どうかもっとガンガンやって下さい。

つうか、議論が長くなってくると、wiki より 2ch の方が見やすいなあ。

126:デフォルトの名無しさん
04/01/24 04:23
>クラスベースのアドバンテージですが、結局は型チェックの例と同様に、ある種の
>制約を課すことによる安心感、安定さ、安全性に尽きると思います。

>そんなにころころ挙動が
>変わったらドキュメント作る時どうするの。そんなふわふわ
>した言語でコーディングなんて出来ないよ

クラスベースの利点やプロトタイプベースの欠点は、抽象的にはこうした意見に
集約されるようですが、もっと具体的に知りたいです。

例えばSmalltalkは柔軟なのだからこれは当てはまらないのではないですか?
当てはまるとしたら具体的にどういった例が挙げられますか?


次ページ
最新レス表示
スレッドの検索
類似スレ一覧
話題のニュース
おまかせリスト
▼オプションを表示
暇つぶし2ch

5383日前に更新/368 KB
担当:undef