1 名前:デフォルトの名無しさん [03/12/08 21:30] オブジェクトを複製または継承によって生成を行う言語, プロトタイプベース・オブジェクト指向言語について語りましょうよ. 関連リンク >>2
82 名前:デフォルトの名無しさん mailto:sage [04/01/19 23:32] 意味不明. 委譲の発祥がクラスベースって言うんだったら そもそも最初のOOPLがクラスベースだったんだから(ry
83 名前:デフォルトの名無しさん mailto:sage [04/01/20 01:12] クラスベースの多重継承の代替物というイメージが強いからじゃ? そもそも漏れみたいな厨は、それが委譲のオリジンだと思ってた。
84 名前:デフォルトの名無しさん mailto:sage [04/01/20 03:04] 継承と委譲についてだけど、どちらも、 「あるオブジェクトが、自分の実装していない機能があったとき、別のオブジェクトから それを借りてくる」 という点では変わらない。 で、継承は、オブジェクトを作る金型(クラス)の間で、機能の貸し借りをするの だけど、 委譲は、実際に生成されたインスタンスの間で、機能の貸し借りが行われる。 型なし言語(だった)JavaScriptが委譲を採用しているのは、まあ当然かも。
85 名前:デフォルトの名無しさん mailto:sage [04/01/20 03:09] >>84 > 型なし言語(だった)JavaScriptが委譲を採用しているのは、まあ当然かも。 型とクラスが混ざってないかい?
86 名前:デフォルトの名無しさん mailto:sage [04/01/20 03:23] あと、無粋なツッコミですまんが、>>83 プロトタイプ・チェインはむしろ単一継承にたとえられることが多いはず。 多重継承は、一回の継承で複数個の親クラスを持つことでしょ? 歴史的経緯については私も知らない。すまん。
87 名前:デフォルトの名無しさん mailto:sage [04/01/20 03:28] >>86 あー、俺は83じゃないが、たぶん83が言いたいのは、 単一継承のOOPLで多重継承的なことをやるために委譲が使われた、 みたいな感じのことだと思われ。
88 名前:デフォルトの名無しさん mailto:sage [04/01/20 03:29] >>85 ん?あなたが言っている型というのは、プリミティブ変数の型のことかい? 私はクラスを、オブジェクトの型として構わないと思うのだけど。 さしさわりがあったら、教えてほしい。
89 名前:デフォルトの名無しさん mailto:sage [04/01/20 03:32] >>87 なるほど、了解。これは私の読み違いだったか。
90 名前:デフォルトの名無しさん mailto:sage [04/01/20 03:35] >>88 例えばJavaにはオブジェクトの型としてインターフェイス型なんてものあるねえ。 ついでに言えば、Smalltalkはいわゆる型なし言語(正確には動的型付言語) と言われているが、コテコテのクラスベースOOPLだよ。
91 名前:デフォルトの名無しさん mailto:sage [04/01/20 03:47] >>90 ええと、私は「型」というものを、「変数の、ある機能を保証するもの」と 見なしている。例えば、数値型だったら、四則演算が保証される、というように。 同様に、例えばあるインスタンスがコレクション・インターフェースに属していたら、 それはイテレータによる処理が保証されるわけだから、これをオブジェクトの 型とみなして良いと考えていた。 それに対して、プロトタイプベース言語は、実行するまでその操作が可能か、事前には 分からない。型による保証がない。 こういうイメージで、クラス(ないしはインターフェース)を「型」の一種と考えている んだけど、まずいだろうか?
92 名前:デフォルトの名無しさん mailto:sage [04/01/20 04:03] >>90 Smalltalk については、知らないのでなんとも言えない。 だけど、型なし言語だったら、プロトタイプベースのほうが自然なんではないか という気がする。オブジェクトの機能の貸し借りに、クラスというものを介在 させずにすむから。 ということで、機会があったら、勉強してみます。
93 名前:デフォルトの名無しさん mailto:sage [04/01/20 04:15] class と interface とが異なるってことだと思う。 class は C++ みたいな言語での、継承の階層図での位置だよね。 対して interface は、 method とかの集合だと思う。 静的で class-based な言語なら一意に対応するだろうけど、 動的な言語だと interface だけ変えるとか、 class だけ変えるとかができそう。
94 名前:デフォルトの名無しさん mailto:sage [04/01/20 04:53] >>92 > だけど、型なし言語だったら、プロトタイプベースのほうが自然なんではないか > という気がする。オブジェクトの機能の貸し借りに、クラスというものを介在 > させずにすむから。 どうだろうね。 プロトタイプベースではオブジェクトの型紙としての機能を全オブジェクトに持たせるのに対して、 Smalltalkではオブジェクトの分担をはっきりさせ、 Classクラスのオブジェクトにその機能を集中させて専業させることで その他のオブジェクトを簡素化している、 とも言えるわけで、 全てのオブジェクトにオブジェクト生成機能を持たせるSelfと オブジェクト生成機能を特定のオブジェクトに専門化させたSmalltalk。 つまり 比較的単質なオブジェクトの集合としてオブジェクト世界を構築するSelfと 色々な種類のオブジェクトの集合としてオブジェクト世界を構築するSmalltalk。 その一方で、 固定的な種別を排除した雑多なオブジェクト世界を構築するSelfと クラスという明確な種別による整然としたオブジェクト世界を構築するSmalltalk。 結局はコインの表裏ってとこだよ。 どっちが自然というよりは、モデリングの視点が違っているだけの話だと思う。 あとは趣味の問題。
95 名前:デフォルトの名無しさん mailto:sage [04/01/20 08:38] オブジェクト生成機能って、new とか init, alloc, clone みたいなの?
96 名前:デフォルトの名無しさん mailto:sage [04/01/20 09:00] >>95 まあそんなもの。 属性名とスロットインデックスの対応とかメソッド辞書等の、 オブジェクトの構造や機能に関する情報と、 それを使ってオブジェクトを生成する操作。
97 名前:デフォルトの名無しさん mailto:sage [04/01/20 17:51] >>94-96 なるほどねえ。 プロトタイプベースについて論じるためには、実はクラスベースについても 広くきちんとした知識をもっていなければならないのだなあ。 勉強になりました。
98 名前:デフォルトの名無しさん mailto:sage [04/01/20 17:57] ということで、ややスレ違いで恐縮なんだけど、 >>93 のように、Smalltalk って、インスタンスの属するクラスをを動的に変更 できるの?まさか、キャストのことじゃないよね? インスタンスが生成されたあとでも、その属するクラスを動的に変更できると したら、プロトタイプベースと同等の自由度だよね?にわかに信じがたい。 もし本当なら、Javaでは信じられない世界だ。
99 名前:デフォルトの名無しさん mailto:sage [04/01/20 21:42] >>97 ここら辺が参考になるかと。 ttp://www.shiro.dreamhost.com/scheme/docs/schemersway-j.html ttp://homepage.mac.com/mkino2/oop/index.html >>98 CLOS ではオブジェクトが属するクラスを後から変えられるみたい。 Smalltalk では become: というメソッドがあったらしい。 ttp://www.sra.co.jp/smalltalk/SML/archives/2001-August/005283.html ttp://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-dev/11398 ttp://homepage.mac.com/mkino2/oop/methodAddition.html >その属するクラスを動的に変更できると >したら、プロトタイプベースと同等の自由度だよね? サブクラシングせずに、オブジェクト毎にメソッドを追加/上書き出来ないと 同等じゃないと思う(個人的には)。 私はプログラマでも言語実装者でもないので、全部伝聞でスマソ。
100 名前:1 [04/01/20 23:39] 100.get!
101 名前:1 mailto:sage [04/01/20 23:45] >その属するクラスを動的に変更できると >したら、プロトタイプベースと同等の自由度だよね? そこまでしてクラスに拘る理由があるのか疑問. そうやってどんどんクラスベースに柔軟性を持たせると, 結局プロトタイプベースと同じものになるだろう. そうなったらクラスという概念が無い方がシンプルでわかりやすい. 自由度と危険性を手に入れたいならクラスという概念はいらないはず.
102 名前:デフォルトの名無しさん mailto:sage [04/01/21 00:03] オブジェクト to オブジェクトのトランスレートなんて頻繁に起こる物じゃないから、 基盤をクラスに置く事は何の不思議もないと思うけど。
103 名前:デフォルトの名無しさん mailto:sage [04/01/21 01:51] >>102 そうかな? あるオブジェクトのインスタンスがあって、モードによってその動作を ガラッと変えたい、なんて場合には、ぜひとも既存のインスタンスの 属すクラスを、別のものに変えたいと思うけどなあ。 GUI の設計とかしていると、よくそういうことない? というか、Java でよく使う Stateパターンって、動的にクラスの 変更のできない言語で、委譲先を変えることによって機能をそっくり 取り替えてしまおう、というものでしょ? (まあ、メソッドの内容は変えられても、シグナチャは変えられないんだけど) ということで、今はそんなにクラスの変換は行われていなくても、もし言語が それをサポートしているなら、需要はいくらでもあると思う。
104 名前:デフォルトの名無しさん mailto:sage [04/01/21 01:53] >>103 自己訂正。 State パターンで変えられないのはシグナチャ、という言い方は不適切だな。 メソッド自体を新設したり、廃止したりということはできない、とすべきだった。
105 名前:デフォルトの名無しさん mailto:sage [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 名前:デフォルトの名無しさん mailto:sage [04/01/21 02:51] >>105 素晴らしい!Smalltalk ってそんなに自由なのか! クラスベースにも、こういう可能性があったのですね! こんなJava厨の質問に答えてもらって申し訳ない。 ありがとう、>>105 の中の人!
107 名前:Java厨 mailto:sage [04/01/21 04:22] オブジェクトの各変数(フィールド)はどうなるの?
108 名前:デフォルトの名無しさん mailto:sage [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 mailto:sage [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 mailto:sage [04/01/21 12:47] 成り行きとはいえ、スレ違いのSmalltalkネタを書きすぎました。 スレ汚しスマソ。
111 名前:デフォルトの名無しさん mailto:sage [04/01/21 21:28] >>110 いや、ちっとも迷惑じゃないです。 ということで、>>107 について簡単でよいから教えていただけませんか? 私も知りたい。
112 名前:デフォルトの名無しさん mailto:sage [04/01/21 22:53] CLOS についても聞きたいっす。名前だけは見かけるんだけど。 実際どうなんでしょ?柔軟性という点ではプロトタイプベースとタメを はれるんでしょうか?
113 名前:デフォルトの名無しさん mailto:sage [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 名前:デフォルトの名無しさん mailto:sage [04/01/22 16:16] とある知り合いの言うことには、 「クラスベースのオブジェクト指向言語は リファレンスマニュアルが書きやすいからいいんだよ」 とても納得した。
117 名前:デフォルトの名無しさん mailto:sage [04/01/23 03:49] >>114-115 予備知識がなくて難しいですが、ある程度分かった気がします。 become: というのは、他のインスタンスを自分のアドレスにコピーすることなのですね? それなら、オーバーヘッドが大きいのも分かります。 from: の実装次第で、どのようなクラスに変えることができるのも分かりました。 >>108-109 については、正直「なんとなく分かった?」程度ですが、自分としては 一応満足です。さすがにこれ以上はスレ違いでしょうし。 丁寧にご説明いただき、大変ありがとうございました。
118 名前:デフォルトの名無しさん mailto:sage [04/01/24 00:10] プロトタイプベースに対するクラスベースの優位性ってなんですかね? その一つは型チェックだと思うんだけど、Smalltalkのようなインタプリタだと その利点もなくなるし、結局なにがいいのかな?
119 名前:デフォルトの名無しさん mailto:sage [04/01/24 01:56] >>118 Smalltalk言語処理系は基本的にコンパイラベースです。Smalltalk環境内であまりに 自在にコードを評価できるので勘違いされがちですが…。いちおう、念のため。 クラスベースのアドバンテージですが、結局は型チェックの例と同様に、ある種の 制約を課すことによる安心感、安定さ、安全性に尽きると思います。 クラスベースとプロトタイプベースをコインの表裏、テーゼとアンチテーゼのように 例える向きもありますが、それよりむしろ、クラスベースはプロトタイプベースが実現できる システム形態のひとつだと考えるほうがいろいろなことをうまく説明できます。 Smalltalk 処理系を Self で比較的すなおに実装できるのに対して、逆はそうでは ないことなどは、その良い例でしょう。
120 名前:デフォルトの名無しさん mailto:sage [04/01/24 02:53] -- プロトタイプベース言語、何それ? ふーん、クラス無いの。静的型チェックも出来ないんだ。 オーバーヘッドも大きそうだし、そんなにころころ挙動が 変わったらドキュメント作る時どうするの。そんなふわふわ した言語でコーディングなんて出来ないよ。学者さんの研究 じゃないからね。こっちは仕事で納めるコードを書いてるんだ。 って言われない事。
121 名前:デフォルトの名無しさん mailto:sage [04/01/24 02:58] >>119 > Smalltalk 処理系を Self で比較的すなおに実装できるのに対して、逆はそうでは > ないことなどは、その良い例でしょう。 んなわきゃない(苦笑
122 名前:デフォルトの名無しさん mailto:sage [04/01/24 03:14] >>120 ころころ挙動が変わらないようにプログラム組めば? プロトタイプベースでももちろんできるけど。 挙動がころころ変わるような柔軟な処理も組めて、 挙動が変わらないプログラムも組める。 ところが、クラスがあると柔軟には組めない。
123 名前:デフォルトの名無しさん mailto:sage [04/01/24 03:16] ていうか、Smalltalkには静的型チェック無いな。w クラスはあるが。
124 名前:デフォルトの名無しさん mailto:sage [04/01/24 03:24] >>122 > ところが、クラスがあると柔軟には組めない。 どうして?例えばこのスレでも何度か話題に出てるSmalltalkなんかは 実行中にクラス定義を変化させたり、メソッドを定義したりできるじゃん。 それに1クラス1オブジェクトにすればプロトタイプベースと変わらなくなるし、 1クラス複数オブジェクトも可能な分だけ柔軟性があるとも言えるじゃないの? つーかさ、クラスベースだからとかプロトタイプベースだからとかナンセンスでしょ。 柔軟性をキーワードにしたって、双方にそれぞれの利点と欠点があるわけでさ。
125 名前:デフォルトの名無しさん mailto:sage [04/01/24 04:00] sumin さんとこの wiki に書き込めるようなレベルじゃない自分にとって、 このスレの議論は実にありがたい。 皆さん、どうかもっとガンガンやって下さい。 つうか、議論が長くなってくると、wiki より 2ch の方が見やすいなあ。
126 名前:デフォルトの名無しさん mailto:sage [04/01/24 04:23] >クラスベースのアドバンテージですが、結局は型チェックの例と同様に、ある種の >制約を課すことによる安心感、安定さ、安全性に尽きると思います。 >そんなにころころ挙動が >変わったらドキュメント作る時どうするの。そんなふわふわ >した言語でコーディングなんて出来ないよ クラスベースの利点やプロトタイプベースの欠点は、抽象的にはこうした意見に 集約されるようですが、もっと具体的に知りたいです。 例えばSmalltalkは柔軟なのだからこれは当てはまらないのではないですか? 当てはまるとしたら具体的にどういった例が挙げられますか?
127 名前:デフォルトの名無しさん mailto:sage [04/01/24 05:28] >>122-123 いや、そういう事じゃないんだけど・・・。 クラスがあるのは良いけど、クラスに色々盛り込み過ぎなんだよなぁ。
128 名前:デフォルトの名無しさん mailto:sage [04/01/24 05:39] >>112 CLOS / MOP についてはここを読むといい。 ttp://www.geocities.co.jp/SiliconValley-Oakland/1680/clisp/index.html ttp://www.shiro.dreamhost.com/scheme/wiliki/wiliki.cgi
129 名前:デフォルトの名無しさん mailto:sage [04/01/24 05:53] >>126 そんな理由で、Smalltalk を鼻にもかけない人や、プライベートプログラミングとしては 楽しいけど、仕事で使うのはちょっと…とためらう人が多いのではないでしょうか。 >Smalltalk は柔軟だから当てはまらない クラスベースの目指すところからしたら、Smalltalk や CLOS はさながら 鬼っ子か異端児といったところでしょうから、この二者が反例を呈すから、それは クラスベースの特徴 or 制約ではないと言い出すと、ここでの対比や理解を深めることを 難しくしてしまうように思いますがいかがでしょう。
130 名前:デフォルトの名無しさん mailto:sage [04/01/24 05:57] >>121 ttp://research.sun.com/research/self/release_4.0/smalltalk.html
131 名前:デフォルトの名無しさん mailto:sage [04/01/24 08:33] >>130 で、Smalltalk上にSelf(-like)環境を構築するのは困難とする根拠は?
132 名前:デフォルトの名無しさん mailto:sage [04/01/24 10:15] >>130 SmalltalkじゃないけどRubyでSelfライクな環境を構築した例なら、ほれ。 すげー短いコードだし。 ttp://kumiki.c.u-tokyo.ac.jp/~ichiyama/projects/reports/seruby/
133 名前:1 mailto:sage [04/01/24 13:38] オブジェクト指向は本当に「オブジェクト」指向か?] www.ogis-ri.co.jp/otc/hiroba/technical/Classification/index.html このスレ的にけっこう関係ありかと思われ. 単一分類と静的分類に縛られては素直なモデル化ができない. 上位工程では多重分類と動的分類をモデル化に用いて, 途中でそれを単一分類と静的分類に書き直し, 一般的なオブジェクト指向言語で実装する. でもプロトタイプベースについては一言も触れられてないのが残念.
134 名前:デフォルトの名無しさん mailto:sage [04/01/24 16:50] クラス指向 vs プロトタイプベースは結局 >>94 に集約されると思うが。 どちらが良いなんて無い。どちらが(自分の問題領域に)向いているかで 考えれば良い。 だいたい、オブジェクトシステムなんてこの 2 者以外にも色々モデルが ある訳だし。
135 名前:デフォルトの名無しさん mailto:sage [04/01/24 16:55] 94って、意味がわからん。 なんか、大学受験の現代文の文章を読んでるかのごとく、 わかりにくい。 もっとこう、解説本のように具体例を挙げて説明してくれんかな。
136 名前:デフォルトの名無しさん mailto:sage [04/01/24 17:37] >>94 の日本語訳 プロトタイプベースはオブジェクトだけだが、クラスベースはいろんなクラスがある。 つまり、視点が違うんだ!
137 名前:デフォルトの名無しさん mailto:sage [04/01/24 17:39] >>94 Classクラスのオブジェクトって?
138 名前:Java厨 mailto:sage [04/01/24 17:47] java.lang.Class hoge; //この変数に入れるオブジェクト
139 名前:デフォルトの名無しさん mailto:sage [04/01/24 18:07] >>135 オブジェクト管理システムとして、クラスを使いたいかどうかって事でしょ。 クラスベースの場合、変数やメソッドの追加はクラスを通して行う。逆に言うと オブジェクトの定義はクラスを見に行けば良い。オブジェクトはクラスの実体化 に過ぎないから、オブジェクト同士の比較やオブジェクトの型の保証等々はクラス を使う事で簡単に実現出来る。 プロトタイプベースだと、変数やメソッドはオブジェクトローカルで自由に変え る事が出来る。逆に、オブジェクトのメタな情報はそれぞれのオブジェクトが バラバラに持っている(もちろんクラス相当のオブジェクトを作ってあげて、 そこに登録すれば良い訳だけど)。同じオブジェクトでもタイミングが違うと 全く異なる挙動をする可能性がある。 色々突っ込まれそう・・・。
140 名前:デフォルトの名無しさん mailto:sage [04/01/24 23:00] > Smalltalk や CLOS はさながら鬼っ子か異端児 ゴルァ!勝手に異端扱いするんじゃねぇ! どっちも OO システムとして はかなり初期なんだから、むしろ後発の連中が静的マンセーになっちまった だけだろーが!
141 名前:デフォルトの名無しさん mailto:sage [04/01/25 00:02] >>139 私もそういう考え。自信ないけど。 >>140 後発の言語のほうが、クラスベースの良さをよく理解していたのかもしれないよ。
142 名前:デフォルトの名無しさん mailto:sage [04/01/25 02:57] >>141 > 後発の言語のほうが、クラスベースの良さをよく理解していたのかもしれないよ。 そうかな? 型とクラスを安易に対応させる悪弊を撒き散らしたと思ってるけど。 ひどい時にはクラス=型なんて話が出たりもする。 例えばJavaのインターフェース型なんて、プロトタイプベースでも十分可能でしょ? つまり、型チェックのためにクラスを導入する必然性はないわけで。
143 名前:Java厨 mailto:sage [04/01/25 03:35] >>142 よろしければ、もう少し解説してくださらぬだろうか。
144 名前:デフォルトの名無しさん mailto:sage [04/01/25 07:23] 単純に、最適化しやすいほうが選ばれやすかったんだと思う。 で、 C/C++ が主流。 でも、変更に弱いとつらいってことが、少しずつ知られてきたよね。 computer の性能も、どんどん高くなってきた。 prototype-based とかも、これから見直されてくと思う。
145 名前:デフォルトの名無しさん mailto:sage [04/01/25 09:48] >>142 クラスとオブジェクトはもともと Simula-67(のちにSimula)で、それぞれ「ユーザー定義 可能な型」とその「データ(インスタンス)」という位置づけてそう名付けられたものです。 C++はその流れを忠実に受け継いでいるので「クラス=型」という考え方はなにも間違って いないと思いますよ。 ただしこれはあくまで抽象データ型の話で、オブジェクト指向からはちょっと離れます。 C++はSmalltalkなどと違って抽象データ型言語としても使えるので、こういう話になります。 抽象データ型とオブジェクト指向でクラス定義や扱いがどう変わるかについては、 クックの論文によく整理されているので興味があればぜひ。 ttp://www.cs.utexas.edu/users/wcook/papers/OOPvsADT/CookOOPvsADT90.pdf
146 名前:デフォルトの名無しさん mailto:sage [04/01/25 12:27] >>145 > ただしこれはあくまで抽象データ型の話で、オブジェクト指向からはちょっと離れます。 その通り。 Simula-67ではデータ型とクラスが一緒くたになっていたが、 Smalltalkではそこからクラスとしての要素を抽出してpure OOにした。 ところがSimula以降の静的型付言語では、あいかわらずデータ型とクラスを 掛持ちさせている。 本来OOにおいてプログラマが気にするべきなのはJavaのインターフェース型のような そのオブジェクトに可能な操作や観察としての型なわけだが、 処理系のほうはオブジェクトの内部構造のほうを要求していて 静的型付OO言語の設計では、処理系の都合のほうが常に優先されてきた。 効率を度外視すれば、クラスが存在しないプロトタイプベース言語でも インターフェース型は導入可能で、それにより柔軟性をある程度手放して 実行前に型安全をチェックすることも可能でしょ。理論上は。 まあ、俺はクラスベースでもSmalltalkやPythonのような動的型付言語のほうが 好きな口なんで、静的型に縛られたプロトタイプベース言語なんて使わないと思うが、 インターフェース型ならばまだ妥協して使うかもしれない。
147 名前:デフォルトの名無しさん mailto:sage [04/01/25 13:48] インターフェイスってクラスブラウザとリフレクションじゃダメなの? 実行時にレシーバのオブジェクトが何であるか決まるオブジェクトシステムで、 実行前に型チェックなんて出来ないでしょう。
148 名前:デフォルトの名無しさん mailto:sage [04/01/25 14:57] >>144 > でも、変更に弱いとつらいってことが、少しずつ知られてきたよね。 そうなんだよ。JScriptだと、いきなりコードを書き始めて、少しずつ洗練させていくことが できるんだけど、Javaだとあらかじめすごく考えてから書き始めないと、すぐ破綻 しちゃうんだよ。 これは自分の頭が悪いせいだと思ってたんだけど、下の文章を見て、ああ、そういう ことなのかと思ったよ。 簡潔さは力なり www.shiro.dreamhost.com/scheme/trans/power-j.html 芸術では、刺繍やモザイクといったメディアは何を作るかをあらかじめ知っていれば うまくいくが、そうでなければめちゃくちゃになる。作りながらイメージを発見したい のなら---例えば人物画のような複雑なイメージを扱いたい時はほとんどそうなのだが--- もっと柔軟性のあるメディア、鉛筆とかインク・ウオッシュ、あるいは油彩が必要だ ろう。実際、タペストリーやモザイクは最初に画を描いてからそれをコピーすることで 作られている。
149 名前:デフォルトの名無しさん mailto:sage [04/01/25 15:16] で、Java 世界でもこの「100%わかっている内容しかコーディングできない」という のを問題とする人が増えてきて、その解決策としてリファクタリングが取り上げられる ようになったんだと思うよ。 ファウラーの『リファクタリング』は基本的に、ずっとこんな感じ↓の内容で。 仕事に取り掛かった時点では、私はどういうクラス設計をしたらいいか、いつも わからないんです。だから仕事に取り掛かるのがいつも怖かったんです。 だけどリファクタリングを知って、「とりあえず動くコードを書くことを目標に しよう。設計はどうせまずいだろうけど、あとでリファクタリングできるから」 と考えるようになって、すごく安心しました。 この内容、私も本当に同感だったんだけど、>>148 のリンク先を見て、また別の感想を 持つようになったよ。 リファクタリングって、なんつうか、もともと変更に向かないモザイクのような言語で、 なんとか変更を行えるようにしたもの、という気がしてきたんだよ。 まあ、それなりに機能していると思うんだけど、モザイクを「15パズル」のように いじっているような、もどかしさを感じてねえ。 www.game3rd.com/game/puzzle/15puzzle/
150 名前:デフォルトの名無しさん mailto:sage [04/01/25 15:57] >>147 まずは何かJavaの入門書を読んでinterface typeが何かを理解したら?
151 名前:デフォルトの名無しさん mailto:sage [04/01/25 16:06] >>150 動的言語に適用した場合の具体的な実装とメリットがイメージ出来ないんだけど。 まぁ言い散らかすのは勝手だが。
152 名前:デフォルトの名無しさん mailto:sage [04/01/25 16:12] >>149 Refactoringは元々Smalltalkerの流儀から来ている。 Smalltalkはオブジェクトを生かしたまま(つまりプログラムの実行中に) クラス定義を変更したりメソッドを書き変えたりできるから、 まずは何かとりあえず動くオブジェクトを作ってみて、 動かしながら変数をいじったりメソッドを変更していく流儀が前提にあって、 その中から使用頻度が高く機械的にできる変更のパターンをまとめたのが Refactoring。 別の言い方をすれば、Refactoringは変更し難い言語で変更を容易にするものではなく 元々どうにでも変更しやすい言語で、変更の仕方を分類整理して名前をつけて、 初心者への教育とか、プログラマ間のコミュニケーションを改善するものだと思う。 だから、変更のし難さというのはクラスベースだからというわけではなく、 むしろ静的型の弊害であり、かつ、クラスをそのまま型として使うことの弊害だと思う。 つまり、クラスの内部設計(インスタンス生成機構)をクラスの外部仕様(型)と 同一視したことによる縛り。
153 名前:デフォルトの名無しさん mailto:sage [04/01/25 16:31] >>152 > だから、変更のし難さというのはクラスベースだからというわけではなく、 > むしろ静的型の弊害であり、かつ、クラスをそのまま型として使うことの弊害だと思う。 > つまり、クラスの内部設計(インスタンス生成機構)をクラスの外部仕様(型)と > 同一視したことによる縛り。 うおー、目からウロコだー!ありがとうございます! >>150-151 議論が噛み合っていない気がするなあ。もうちょっと冷静にやろうよ。
154 名前:1 mailto:sage [04/01/25 16:41] >>152 >その中から使用頻度が高く機械的にできる変更のパターンをまとめたのが >Refactoring。 はぁ? リファクタリングはパターンじゃないんですけど… 使用頻度とか機械的だとかコミュニケーションとか関係ないんですが. リファクタリングとは,ソフトウェアの外部的振る舞いを保ったままで, 内部の構造を改善していく作業を指します. (リファクタリング プログラミングの体質改善テクニック)
155 名前:デフォルトの名無しさん mailto:sage [04/01/25 16:49] >>154 うーん、リファクタリングには定石はあるわけで、それを「パターン」と呼んでも リファクタリングの趣旨からは離れはしないと思いますよ。 実際、「この長いメソッドは別クラスとして独立させてね」という感じで パターンを意識したコミュニケーションも行われているし。 まあ、スレ違い気味ではあるが。
156 名前:デフォルトの名無しさん mailto:sage [04/01/25 16:49] パターンってデザインパターンだけを指す言葉ではないよ。本来はもっと意味が広い。 「アナリシスパターン」 や 「Smalltalk ベストプラクティス・パターン」 があるように。 名前を付けて体系化することで、暗黙知を形式知とすることと、 コミュニケーションするときの共通語彙として使えるようにすることが パターンの目的というか役割。
157 名前:1 mailto:sage [04/01/25 16:57] >>155 >>156 言いたいことはわかります. ただ用語の定義が正確ではないと思ったのでレスしました. 「使用頻度が高く機械的にできる変更のパターン」を リファクタリングと呼ぶのは間違いです. リファクタリング・パターンとでも言うべきでしょう. リファクタリングという作業自体には使用頻度が低いものもあるし, 機械的に行うことが難しいものもあるのです.
158 名前:デフォルトの名無しさん mailto:sage [04/01/25 16:58] >>150 ライブラリ利用時の保証ならクラスブラウザで良いし、実行時の保証ならリフレクションを 使う事になるんじゃないのって事なんだけど。
159 名前:デフォルトの名無しさん mailto:sage [04/01/25 17:19] んでもって、Happy Squeaking!! と SML の該当箇所。 ttp://www.ogis-ri.co.jp/otc/hiroba/technical/Squeak4/S4-5-5_1.html ttp://www.sra.co.jp/smalltalk/SML/archives/1999-March/thread.html#3323 Smalltalk でインターフェイスを実装する話。操作の集合としてインターフェイスを 付けるのは良いけど、静的な型システムの代用とはならない。
160 名前:156 mailto:sage [04/01/25 17:25] >>157 スレ違いなのでこれで最後。 漏れは |使用頻度が高く機械的にできる を含めた定義には賛成しないよ。
161 名前:155 mailto:sage [04/01/25 17:40] >>160 スレ違いなんだけど、私も一つだけ。 私は基本的に「使用頻度が高く機械的にできる」を支持したいなあ。 ソフトウェアの改善という、それまで「一から書き直したほうが早い」と されてきた手のつけようのない難事業を、 ある程度機械的に処理できるようになったことが、リファクタリングの 第一のご利益だと思うから。 もちろん、リファクタリングの中には、それではすまない部分もあるけど。
162 名前:Java厨 mailto:sage [04/01/25 18:04] >>152 ,>>153 すまぬ。interfaceとclassで、型として何が違うというの? 実装があるかないかの違いだけで、 interfaceは型そのものじゃないか? Smalltalkがわからんのでリンク先読んでも肝心なところがわからん。 いってみれば、classはvoid型たれ、ということ? じゃあ、classってなに?
163 名前:デフォルトの名無しさん mailto:sage [04/01/25 18:56] >>159 んでもって、変数宣言時にインターフェイス(の集合)を指定すれば静的型付になる。 この場合の型はクラスとは独立しているからプロトタイプベースでも可能でしょ?
164 名前:152 mailto:sage [04/01/25 19:15] 厳密に言えば、1氏の言う通り、Refactoringは仕様を変えずに実装を変更する 作業であって、パターンそのものではないです。 しかし、Refactoring作業のカタログ化はFowlerの"Refactoring"のPrefaceに | The heart of the book, the catalog of refactroings, stretches from | Chapter 5 through Chapter 12 とあるように、FowlerがRefactoringを普及させるにあたって念頭に置いてい ることと合致していると思います。 そして、>>149 の文脈では 「あるRefactoring作業パターンのリストがあって、 そこから現状の実装に適切な作業パターンを選んで実行することで 漸近的により良い実装に近付けていく。」 という意味合いが強いと思い、あえてカタログ化としての面を前面に出し >>152 のように書きました。 また、「機械的に」や「使用頻度が高い」についても同様で、 Refactoringという作業そのものの定義とは関係ありませんし、 実際に当てはまらないパターンもあります。 しかし、FowlerがRefactoringをカタログ化するにあたって、それぞれ 非常に重要な基準の一つであったのではないかと、 彼の"Refactoring"に掲載されたカタログから推測しました。
165 名前:デフォルトの名無しさん mailto:sage [04/01/25 19:36] >>162 あなたの質問は、いつも私の知りたいポイントを突いているなあ。 ということで、どうかどなたかお教えください。 今までの議論を自分なりに理解すると、 ・型、インターフェース…そのオブジェクトにどのような操作が可能か 定義するもの。 ・クラス…そのオブジェクトがどのような継承関係で成り立っているか、 ライブラリの中でどのような位置にあるかを示すもの。 なのでしょうか? 私もJava厨なので、この二つが別物というのは驚きだし、いまいち 実感が湧かない。
166 名前:1 mailto:sage [04/01/25 19:39] >>152 いや,まぁ… なんというか 余計な事に突っこんですまんでした. Fowlerの本読むとリファクタリングのカタログ的な面が強調され過ぎてて ちょっと堅苦しいなぁと思ってたんです. その後Kent BeckのTDD本読んだら「機械的に」や「使用頻度が高い」とか はあまり関係なくて,リファクタリングという作業,リズムが重要だというか…
167 名前:Java厨 mailto:sage [04/01/25 19:50] >>165 >>152 をもう一回読んで小便したら気がついたのだが、 classは動的に出来ること(メソッド)がどんどん変わってよい(Javaではできない)、 ということではないかと。 そのときそのときで、なにかのinterfaceの条件にあっていればよい、と。 しかし、それはいびつだなぁ。Aさんが小学生だったのが中学生になり、かつバスケの選手になる、 というのはあるが、全人類が小学生や中学生バスケ選手になることはないと思う。 うーん、やっぱりクラスって何?
168 名前:デフォルトの名無しさん mailto:sage [04/01/25 20:07] 今、このスレは自分的には、2chでいちばんの良スレだ。 もちろんアカデミシャンからは稚拙な議論なのだろうけれど、 自分がずっと興味があって、しかし仕事と直接の関わりがなくて手を出せなかった 分野を、何とか自分に理解できるレベルで話してもらえるというのは最高です。 皆さんどうもありがとう。
169 名前:152 mailto:sage [04/01/25 20:15] >>166 > その後Kent BeckのTDD本読んだら「機械的に」や「使用頻度が高い」とか > はあまり関係なくて,リファクタリングという作業,リズムが重要だというか… そうですね。Kent BeckはXPからもわかるように、開発プロジェクト全体の 手法のほうに着目してますから。 ところでプロトタイプベースでもリファクタリングみたいな作業は重要だと思いますが、 ↓こんなのがありますね。 selfguru.sourceforge.net/ 個人的にはC++やJavaのような「堅い」言語よりも、プロトタイプベース言語のほうが Refactoringのカタログを充実させる要請が強いと思うのですが、どうでしょう? オブジェクトをクラスではなくインスタンス単位でまとめていくために必要になる 「カン所」にうまく名前を付けて、多くのプログラマからそれらを集積して整理する ことで、プログラマの能力をよりよく発揮させられると思うのですが。
170 名前:デフォルトの名無しさん mailto:sage [04/01/25 20:19] クラスとはオブジェクトを作る"元"で、オブジェクトの構造(実装)やメソッドを定義しておいて、 その類(クラス)のオブジェクトが共通に使うものって事? で、C++やJavaはクラスを型としても使ってしまっているから混乱するって事? Smalltalkがクラスを型として使っていないってのは、オブジェクトが何のクラスに属するかは きっちり決まっていて、クラスからオブジェクトを生成するけど、 オブジェクトをポイントする変数そのものには型が無いって事? Java のインタフェースも思いっきりクラスの気がするんだけど。実装は持たないし オブジェクトを作る元にもならないけど、継承もできるし、オブジェクトの分類を示すものには 違いないでしょう? それでもやっぱり抽象データ型の変形に過ぎないのかな?
171 名前:152 [04/01/25 20:32] >>167 > というのはあるが、全人類が小学生や中学生バスケ選手になることはないと思う。 OOの話で例え話はあまり好きじゃないのですが、バスケ選手の話で言えば、 playerという変数の型として、PlayerだのNBAProといったクラスはどうでもいい話で、 むしろmoveableとかthrowableといったインターフェースが重要じゃない? player.run_to(direction, distance, speed)とかplayer.throw_at(direction, speed)とかが ちゃんと実行できることが大事なんじゃない? Playerクラスをplayerの型としてしまうと、車椅子バスケとかに対応しようとした時に PlayerクラスにFoot leftfoot, rightfoot;なんて変数があったら困ることになるかもよ? 本当はmoveableでthrowableならFootがあろうがなかろうが関係ないんじゃない? という話です。
172 名前:1 mailto:sage [04/01/25 20:36] >>168 なんか最近妙に賑わってるのがなんか怖いw このスレ立てたのが,プロトタイプベースに関する日本語の資料がほとんど見つからなかった という理由なんだけど,興味ある人/知ってる人はけっこういるみたいね. 俺もSelfとか使ってみたいんだけど… 初心者が簡単に手をつけられる状況じゃないよなぁ.
173 名前:デフォルトの名無しさん [04/01/25 21:10] >>167 ではないけれど >>171 ならinterfaceのあるJavaは問題ないということですか?
174 名前:Java厨 mailto:sage [04/01/25 21:29] >>171 interfaceの適切な粒度とそれ中心で考えるというのは理解するし、普段から心がけている。 話はそれではなく、クラスの定義がどんどん変わると、 世界に散らばったインスタンス達も同様に変わってしまうわけで、 それは普通は変ではないかと。 個々のインスタンスが変身していくのはわかるけど、と。 こう考えると、クラスってなに?と。 クラスベースでクラスにこういうことやるのはおかしくない?と
175 名前:デフォルトの名無しさん mailto:sage [04/01/26 00:35] >>174 クラス定義を動的に変えられることは、仕様の変更を伴うものばかりとは 限りません。メソッド名を変えずに、別のより性能の良いアルゴリズムを 採用したものに差し替えるとか、それこそバグの修正ということもありえます。 大事なのは、システム(アプリ)を停止せずにこれができるということで、 クラスのあるべき立場を危うくすることは目的ではないと思います。Smalltalk にしても CLOS にしても、できるからといって、クラスの定義がどんどん 変わってゆくような設計は特殊な事情でもなければしないはずです。
176 名前:デフォルトの名無しさん mailto:sage [04/01/26 00:36] 171じゃないけど燃えてきたので横槍 >>173 Java の interface は、クラスの定義時に、設計者が 宣言しなければならないところが問題。 例えば、メソッド A と B と C を要求する interface I があるとしよう。そしてクラス X は A も B も C も定義 している。しかしクラス X が interface I を implements していなかったら I としては使えないわけだ。つまり、 クラスの作成者があらかじめあらゆる使われ方を考慮 しておかないといけない。でもこれは無理な話なわけで。 ここで動的型付け言語だとそもそもそういう宣言は必要なくて、 実行時に A B C というめそっどがあればよい。また、静的 型付け言語でも interface の後付けができる処理系が あったはず。そういう機構があるなら、>>171 の言ってる 問題点は解決したと言ってもいいと思うよ。
177 名前:デフォルトの名無しさん mailto:sage [04/01/26 00:44] >>175 >>152 の > だから、変更のし難さというのはクラスベースだからというわけではなく、 > むしろ静的型の弊害であり、かつ、クラスをそのまま型として使うことの弊害だと思う。 > つまり、クラスの内部設計(インスタンス生成機構)をクラスの外部仕様(型)と > 同一視したことによる縛り。 とうまく整合できないのですが、 よろしければ補足をいただけませんか?
178 名前:デフォルトの名無しさん mailto:sage [04/01/26 01:01] 実行中に変えるということについては、型とかクラス云々ではなく、 実行中にプログラムを変える口を持つかどうかということではないだろうか。
179 名前:デフォルトの名無しさん [04/01/26 01:28] >>176 interface I をインターフェース継承して、Xをメンバに持つ新しいクラス newXを作ってメソッドA,B,CをXに委譲すれば解決。
180 名前:デフォルトの名無しさん mailto:sage [04/01/26 02:18] みんなクラスとかインターフェースとか、型付けとか好きだねぇ。
181 名前:デフォルトの名無しさん mailto:sage [04/01/26 02:38] >>179 それだと実行前に定義しておかなければならないという問題を全然解決していない。
182 名前:152 mailto:sage [04/01/26 04:24] >>177 私は>>175 氏ではありませんが、たぶん彼が言いたいのは、 「納入したシステムが実行時に動的に自身のクラスを頻繁に変更するのは 特殊な場合だろう」 ということなのでは? 一方、私の>>152 は実行時といっても開発における実行時の話であり、 クラスを変更するのはプログラマです。 というわけで、私としては>>175 氏との間に意見の齟齬は無いと思っています。 で、私自身、>>175 氏に同意します。 Smalltalkで「実行時に動的に自身のクラスを頻繁に変更する」のも可能では ありますが、よほど強い要請がなければやりません。 ただ、それが可能であることは重要だと思います。 プロトタイプベースでも同様だと思います。 動的にdelegationを変更したりslotを変更するのは、それ自体が目的ではなく、 表現したい振舞いを簡潔かつ見通し良く記述するための手段に過ぎないわけで そのためのプロトタイプベースです。 実現したい振舞いを可能にするための動的変更を最小のインパクトに抑えるのは プロトタイプベースであれクラスベースであれ共通の指針だと思います。 この視点に立った上で、言語処理系自体が動的変更を標準の機能として認めていて 実際に簡潔な記述で動的変更が可能であることは強力な武器だと思っています。