プロトタイプベース・ ..
449:デフォルトの名無しさん
04/02/12 14:33
>>446
> メソッドを用意する。これに対して、Ruby (と、まあ Smalltalk/
> Squeak)では元のクラスのサブクラスを作って、注目するインスタンス
> のクラスをそれに差し替え、インスタンス特異的なメソッドは差し替え
> たサブクラスに定義している。
>
12ヘェ〜。純粋クラスベースOOの枠組み内でうまいことやってるですね。
ちなみにPythonが冗長なのは、滅多に使わないような機能や生産性にほとんど
影響しないようなところに安易に新しい構文を用意することで、言語が無駄に
複雑化したり初心者を混乱させたりするのは悪である、という思想があるから
のようです。ってプロトタイプとかけ離れてきたのでこの辺で。
450:デフォルトの名無しさん
04/02/14 16:30
URLリンク(sof.ch)
> Experimental prototype base object orientation.
Scheme 処理系の一つ、QScheme はプロトタイプベースなオブジェクトシステムを
持ってるらしい。
451:デフォルトの名無しさん
04/02/15 17:36
結構みんなこのスレ見てるんだね。今日だけでも色んなスレでプロトタイプベースという
言葉を見たよ(以前はそうでもなかったけど)。それともプロトタイプベースの認知度が
上がったのかな。
452:デフォルトの名無しさん
04/02/15 20:59
URLリンク(www.logtalk.org)
>Support for both class-based and prototype-based systems
>You may have, in the same application, class-based hierarchies (with instantiation
>and specialization relations) and prototype-based hierarchies (with extension relations).
Prolog のオブジェクト指向拡張ライブラリ? の Logtalk はクラスベースとプロトタイプ
ベースの両方をサポートしているみたい。Features 見ていると、色々面白そう。
453:デフォルトの名無しさん
04/02/15 21:04
で、プロトタイプベースの中で、一番進んだ言語って何?
Ioですか?
454:デフォルトの名無しさん
04/02/15 21:08
ああ、一番遅れた言語ね。
455:デフォルトの名無しさん
04/02/15 21:23
MLud もプロトタイプベースだけど、強型付けな ML 上に構築されているという事は、
MLud 自身も強く型付けされた環境なのかなぁ。だとしたらちょっと異色かも。
URLリンク(moonflare.com)
456:デフォルトの名無しさん
04/02/15 21:36
>>453
言語に大きく依存した機能じゃないから、好きな言語でどうぞっていう流れじゃないかな。
クロージャがあるか、ファーストクラスのメソッドがあれば何とかなる。
457:デフォルトの名無しさん
04/02/16 00:12
>>453
一番進んでいるのはオブジェクトモデル、VMの性能、クラスライブラリ
の充実度のどれをとってもいまだにSelfだろ。ちょっと古いのと、対象
となるプラットフォームが異常に限られているのが玉に瑕だが。
NewtonScript もかなりよくできていたけど、これはプラットフォーム
自体がなくなっちゃったからなぁ…。
目先を変えて、Scheme の SLIB に含まれる YASOS なんかもいいかもしれない。
URLリンク(members.at.infoseek.co.jp)
458:デフォルトの名無しさん
04/02/16 00:20
>>456
インスタンス特異的メソッドのみならともかく、委譲機構をそれなりに
実現しようとすると結構な手間になるのでは?
459:デフォルトの名無しさん
04/02/16 00:55
インスタンスにスロットを持たせるのはなんとなく分かったので、
委譲機構とやらのサンプルコードをキボンヌ。最低限どんな動きが
どれくれーできればいいんだ?
460:デフォルトの名無しさん
04/02/16 02:46
>>459
既出ですが、これなんかよく説明されていると思います。
URLリンク(kumiki.c.u-tokyo.ac.jp)
サンプルコードの書き下ろしは面倒なので勘弁してください。
私自身は、簡単にできるとは思っても言ってもいないので、説明責任もないし(^_^;)。
最低限できればよいのは、委譲先オブジェクトのメソッドを暗示的
(レシーバには見つけられないとき)に、あるいは必要なら明示的 (Self の
resend、Smalltalk 系の super)に起動できて、その際、起動した
メソッドのコード中の偽変数 self には(メソッドホルダではなく)
レシーバを束縛できていること、でしょうか。
461:デフォルトの名無しさん
04/02/17 00:33
459じゃないんだけど。
つまり委譲機構ってのは手前で処理できぬメッセージが来たら
プロトタイプチェーンを遡ってメソッドを探す事っつーことですか。
クラスベースだと何に当たる言葉なんだろう。「ポリもアフィズム」じゃないし。
self / this にそもそもメッセージを受けた人が入らないといけないが、
クラスベースなら[[クラスの]]継承階層を遡っていき、クラスとオブジェクトが峻別されるから
あまり問題にならないところだが、
プロトタイプベースだと[[オブジェクトの]]チェーンを遡っていくんだが
でも親のオブジェクトが受けちゃったりしたらまずいって訳だ。
RubyもSelfもわからんので読めん。
漏れの読めるプロトタイプベースはECMAScriptだけでいいや・・・。
462:n
04/02/17 10:11
本当にECMAScriptってプロトタイプベースなんですか?
わたしにはろくに継承/委譲ができないように思えるのですが・・・。
463:デフォルトの名無しさん
04/02/17 16:56
>>462
勉強を兼ねて恒例の bank account を書いてみました。
委譲/継承も多態もできているみたいです。
個人的には self をメソッドで暗示的引数に指定しなくていいぶん、
Python よりはスジがよいように思います。
<script type="text/javascript">
var bank_account = new Object;
function ba_set_balance(_x) {this.balance = _x; return this}
bank_account.set_balance = ba_set_balance;
function ba_get_balance() {return this.balance}
bank_account.get_balance = ba_get_balance;
document.write( bank_account.set_balance(200).get_balance() + "<br>"); // => 200
function ba_deposit(_x) {
this.set_balance(this.get_balance() + _x);
return this}
bank_account.deposit = ba_deposit;
document.write( bank_account.deposit(50).get_balance() + "<br>"); // => 250
function ba_withdraw(_x) {
this.set_balance(Math.max(this.get_balance() - _x, 0));
return this}
bank_account.withdraw = ba_withdraw;
document.write( bank_account.withdraw(100).get_balance() + "<br>"); // => 150
document.write( bank_account.withdraw(200).get_balance() + "<br>"); // => 0
464:デフォルトの名無しさん
04/02/17 17:05
>>463 続き
var my_account = new Object;
my_account.__proto__ = bank_account;
document.write( my_account.set_balance(100).get_balance() + "<br>"); // => 100
document.write( my_account.deposit(50).get_balance() + "<br>"); // => 150
document.write( bank_account.get_balance() + "<br>"); // => 0
465:デフォルトの名無しさん
04/02/17 17:07
>>464 続き
function sa_set_num_shares(_x) {this.num_shares = _x; return this}
stock_account.set_num_shares = sa_set_num_shares;
function sa_get_num_shares() {return this.num_shares}
stock_account.get_num_shares = sa_get_num_shares;
function sa_set_price_per_share(_x) {this.price_per_share = _x; return this}
stock_account.set_price_per_share = sa_set_price_per_share;
function sa_get_price_per_share() {return this.price_per_share}
stock_account.get_price_per_share = sa_get_price_per_share;
stock_account.set_num_shares(10).set_price_per_share(30);
document.write( stock_account.get_num_shares() + "<br>"); // => 10
document.write( stock_account.get_price_per_share() + "<br>"); // => 30
466:デフォルトの名無しさん
04/02/17 17:10
>>465 続き
function sa_set_balance(_x) {
this.set_num_shares(_x / this.get_price_per_share());
return this}
stock_account.set_balance = sa_set_balance;
function sa_get_balance() {
return this.get_num_shares() * this.get_price_per_share()}
stock_account.get_balance = sa_get_balance;
document.write( stock_account.get_balance() + "<br>"); // => 300
document.write( stock_account.set_balance(600).get_balance() + "<br>"); // => 600
document.write( stock_account.set_balance(600).get_num_shares() + "<br>"); // => 20
document.write( stock_account.deposit(60).get_balance() + "<br>"); // => 660
document.write( stock_account.get_num_shares() + "<br>"); // => 22
document.write( stock_account.withdraw(90).get_balance() + "<br>"); // => 570
document.write( stock_account.get_num_shares() + "<br>"); // => 19
</script>
467:デフォルトの名無しさん
04/02/17 18:03
読み難いソースだなぁ…
468:デフォルトの名無しさん
04/02/17 23:48
Netscapeで動く。
IEでは動かない。
セッターが必ずthisを返してメッセージをカスケードさせてるのは趣味?
Smalltalk以外でもそうするものなの?
Netscapeのガイド
URLリンク(devedge.netscape.com)
だと、コンストラクタ作って、prototypeプロパティに継承元をセットしていて、クラスベースっぽい
469:デフォルトの名無しさん
04/02/18 08:51
stock_accountの定義はどこ??
var stock_account = new Object;
stock_account.__proto__ = bank_account;
が抜けてる??
470:デフォルトの名無しさん
04/02/18 09:36
>>469
ああ、すみません。抜けてます。465 と 464 の間に。
>>468
ああ、すみません。Smalltalker なもんですから…。
そうでないと気持ち悪くて…。
>>467
ああ、すみません。初めて書いた JavaScript なもんですから…。
でも、私の責任は1/3くらいです(^_^;)。
1/3は JavaScript のせい、1/3は2ちゃんの改行数制限せいです(笑)。
471:n
04/02/18 10:21
あう、__proto__を使うのですね、それは反則の方向で(ぇ
確かに__proto__が使えるならプロトタイプベースと呼べるとは思うのですが、
__proto__がなくてもプロトタイプベースなのかなぁ、と感じたのですよ。
472:デフォルトの名無しさん
04/02/19 09:20
>>470
もう少しJSらしく書いてみたけど、普通にやると多態は駄目。
var BankAccount = new Object;
BankAccount.balance = 200;
document.write(BankAccount.balance + "<br>"); // 200
BankAccount.deposit = function(x) { return this.balance += x; }
document.write(BankAccount.deposit(50) + "<br>"); // 250
BankAccount.withdraw = function(x) {
return this.balance = Math.max(this.balance - x, 0);
}
document.write(BankAccount.withdraw(100) + "<br>"); // 150
document.write(BankAccount.withdraw(200) + "<br>"); // 0
function make_Account(){}
make_Account.prototype = BankAccount;
var myAccount = new make_Account;
// Mozilla 系 JS ならば var myAccont.__proto__ = BankAccount だけでもいい。
myAccount.balance = 100;
document.write(myAccount.balance + "<br>"); // 100
document.write(myAccount.deposit(50) + "<br>"); // 150
document.write(BankAccount.balance + "<br>"); // 0
473:デフォルトの名無しさん
04/02/19 09:22
続き
var stockAccount = new make_Account;
// Mozilla 系 JS ならば var stockAccount.__proto__ = BankAccount でもいい。
stockAccount.numShares = 10;
stockAccount.pricePerShare = 30;
document.write(stockAccount.numShares + "<br>"); // 10
document.write(stockAccount.pricePerShare + "<br>"); // 30
stockAccount.balance = function(x) { // こんな風にしてみたけど…
if(arguments.length) this.numShares = x / this.pricePerShare;
return this.numShares * this.pricePerShare;
}
document.write(stockAccount.balance() + "<br>"); // 300
document.write(stockAccount.balance(600) + "<br>"); // 600
document.write(stockAccount.numShares + "<br>"); // 20
stockAccount.deposit(60);
document.write(stockAccount.balance() + "<br>");
// Error: stockAccount.balance is not a function
document.write(stockAccount.numShares + "<br>");
stockAccount.withdraw(90);
document.write(stockAccount.balance() + "<br>");
document.write(stockAccount.numShares + "<br>");
474:デフォルトの名無しさん
04/02/19 09:29
stockAccount.deposit(x) でこける。
URLリンク(sumim.no-ip.com:8080) の Io の最初の例と同じで
# つか、上自体 Io の例そのままパクッただけだったり。
既にあるプロパティと同名のメソッドを作れない。
結局 getter, setter になるメソッドを書かないとうまくいかない。
475:デフォルトの名無しさん
04/02/19 10:52
ついでにURLリンク(homepage.mac.com)
の Chain of Responsibility を JS で。
var app = new Object;
app.preview = function(){alert("preview in app");}
function make_app(){}
make_app.prototype = app;
var dialog = new make_app;
dialog.print = function(){alert("print in dialog");}
function make_dialog(){}
make_dialog.prototype = dialog;
var button = new make_dialog;
button.help = function(){alert("help in button");}
button.help();
button.print();
button.preview()
すっきり書けてるほうとは思うけど、どうも…
476:デフォルトの名無しさん
04/02/19 10:54
>>475 __proto__ 版
var app = new Object;
var dialog = new Object;
var button = new Object;
app.preview = function(){alert("preview in app");}
dialog.print = function(){alert("print in dialog");}
button.help = function(){alert("help in button");}
dialog.__proto__ = app;
button.__proto__ = dialog;
button.help();
button.print();
button.preview()
やっぱりこっちの方がプロトタイプっぽい。
477:デフォルトの名無しさん
04/02/19 13:18
var app = new Function;
app.prototype.preview = function(){alert("preview in app");}
var dialog = new Function;
dialog.prototype = new app;
dialog.prototype.print = function(){alert("print in dialog");}
var button = new dialog;
button.help = function(){alert("help in button");}
クラスっぽく書くとこうか:p
478:デフォルトの名無しさん
04/02/19 15:46
昔なつかし
function app(){
var name = "app";
this.preview = function(){alert("preview in" + name);};
}
function dialog(){
var name = "dialog";
app.apply(this, arguments);
this.print = function(){alert("print in" + name);};
}
var button = new dialog;
button.help = function(){alert("help in button");};
479:1
04/02/23 15:58
soopy版
app = {
fun preview() {
do: println "preview in app";
};
};
dialog = app + {
fun print() {
do: println("print in dialog");
};
};
button = dialog + {
fun help() {
do: println("help in button");
};
};
button help ();
button print ();
button preview();
480:デフォルトの名無しさん
04/02/25 19:17
なんか色々中途半端とか言われてるけど、
結局はこれ使って何するのか、だと思うよ。
これ使ったら開発効率が上がりました、
実行効率が上がりました、
保守がしやすくなりました、
ってスタンスのパラダイムじゃないよね。>プロトタイプベース
趣味?
481:デフォルトの名無しさん
04/02/25 19:51
>>480
んー Newton Script なんかがまさにそうなんだけど、例えば HTML / XHTML のように
UI + action なんかをさらーっと記述するフレームワークなんかを考えると、ごく当たり前に
プロトタイプベースの発想になったりします。
<a id="a" onClick="hoge()"> a </a>
<a id="b" onClick="bar()"> b </a>
なんていうようなものを表現するとき、それぞれにクラスを作るのではなくインスタンス毎に
メソッドを定義して済ませてしまうとか。
482:デフォルトの名無しさん
04/02/25 21:55
UI + action というか、
すでにインスタンスベースの枠組み(UI + actionはその典型)があって、
それに乗っかる場合、っていう意味だろうか。
なんか受け身で消極的な感じがする。
483:デフォルトの名無しさん
04/02/26 08:19
マルチスレッドとの相性ってどうなんでしょうか。
484:デフォルトの名無しさん
04/02/26 12:56
>>482
乗っかるというか、全体を構築するために使ってもいいし (Newton は後者)。
ただ、フレームワークそのものはクラスベースでいいんじゃない、っていう見解は
ある意味当たり前にあって(フレームワークで定義されるものは普通汎用性を持っていて、
個別インスタンスなんて珍しいから)、そういう面では prototype 言語でも内部的に
クラスを使っていたりします。
↑漏れはNewtonScript と SpiderMonkey (Netscape 由来の JavaScript エンジン)位
しか詳しくないので信頼度低いけど。
485:デフォルトの名無しさん
04/03/04 16:33
URLリンク(www.ogis-ri.co.jp)
C++でテンプレートによる「修飾」継承という手で爆発を抑えつつ多重分類を実現できそうな気が。
486:デフォルトの名無しさん
04/03/13 12:29
あげ
487:デフォルトの名無しさん
04/03/19 17:47
>>480>>481
保守、ついでに戯言
Delphi の procedure | function 型のプロパティとか、
Java の匿名内部クラスとかでイベントを捕獲するのは、
メソッドをカスタマイズするという点でプロトタイプに通じる考えだと思う。
あると便利、なくてもほかに手段があれば別に困らないかもしれない。
488:デフォルトの名無しさん
04/03/20 01:40
プロトタイプベース言語の proto ってクラスベース言語の super みたいな物であってますか?
どちらも、元のオブジェクトへの参照を保持しているだけですよね?
489:デフォルトの名無しさん
04/03/20 03:51
>>488
selfとsuperは同じオブジェクトを指す
490:デフォルトの名無しさん
04/03/20 12:52
>>489
言語によるかも。
491:デフォルトの名無しさん
04/03/20 13:26
>>488
SELF のリファレンスマニュアルのこれ、
URLリンク(research.sun.com)
なんかみてみてもらうとわかると思うけど、それであながち間違いでもなさそう。
SELF の場合、self は self のままで(まぎらわしいなぁ…)、メソッドの呼び出し記述のほう
に resend を冠する。ただ、これはペアレント(aka proto)スロットが一つのときで、複数ある
ときはそれを明示的にするためにペアレントスロット名をもって resend に代える、とある。
まあ、SELF の話をされてもかなわんよ…という人も多いだろうから、なんか他の言語でも
調べてみることにするか。
492:デフォルトの名無しさん
04/03/22 19:33
プロトタイプチェインについての覚書(ECMAScript, JavaScript)
URLリンク(members.jcom.home.ne.jp)
493:デフォルトの名無しさん
04/03/24 22:39
インスタンスを実体、クラスを概念とすると、「継承」というものを現実世界で例えた場合に
プロトタイプベースとクラスベースの、どちらがより簡単で判り易い例えができるんでしょうね
クラスベースはクラス,つまり概念の継承なので、クラスに慣れるとクラスの例は
『クーラーボックスの親はただの箱』みたいでも違和感無いですが、
一般人には???な話でしょうし。(ちょっと説明すればわかると思いますが)
逆にプロトタイプの例では特定の個人を例に挙げなければ難しいですし。
(実際にプログラム内で操作するのは「個人」ですから、
実際の例を出せばこちらのほうが俺は判り易いと思いますが)
というかインスタンスとクラスの区別が厳密についてないですね俺 orz
クラスが無い分プロトタイプのほうが簡単ですか?
494:デフォルトの名無しさん
04/03/24 22:41
> クラスを概念
そこがもーダメなような
495:493
04/03/24 22:46
そか orz
判ったつもりで判ってなかったんだな
496:デフォルトの名無しさん
04/03/24 22:47
ごめん下げ忘れた。逝ってきます。
497:デフォルトの名無しさん
04/03/25 12:02
>>493
んー。やっぱり プロトタイプベース vs クラスベース という構図が
そも間違っていると思う。プロトタイプベースはよりプリミティブな
オブジェクトモデルなんで、クラスベースがよい仕事をする問題領域なら
機能を制限してそうしたフレームワークを組めばいい(ひらたく言えば
クラスベースを使えばいい) プロトタイプベースが活きるのは、
クラスベースが到達できない領域なのよ。その最たるものがインスタンス
に独自のメソッドや属性を持たせるってやつで。
498:デフォルトの名無しさん
04/03/25 12:26
>>497
それは別にクラスベースでもできるでしょう。
例: python, CLOS, 他のにもあるハズ
嬉しいのは「よりプリミティブである」って事だけなの?
499:デフォルトの名無しさん
04/03/25 12:32
結局Ruby最強ってことで
500:デフォルトの名無しさん
04/03/29 13:10
乙
501:デフォルトの名無しさん
04/03/29 20:36
500 名前: デフォルトの名無しさん :sage 投稿日: 04/03/25 (木) 14:16
まえにも見たな、この展開… (w
>>498
とりあえず、任意の instance から別の instance 作れるとか。
class と instance を兼用させるようなことができる。
501 名前: デフォルトの名無しさん :sage 投稿日: 04/03/25 (木) 14:29
>>500
> とりあえず、任意の instance から別の instance 作れるとか。
> class と instance を兼用させるようなことができる。
で、それも、どっちもclass baseでもできるんだよな。
502 名前: デフォルトの名無しさん :sage 投稿日: 04/03/25 (木) 17:46
501は
完全に「実現可能」のレイヤーを取り違えているんだよ。
そんなこと言ったら、Cでもマシン語だって可能だ。
その区別が付かない奴にいくら言っても堂々巡り。
503 名前: デフォルトの名無しさん :sage 投稿日: 04/03/25 (木) 17:54
>>498
だから、クラスベースの典型例やそこにおける反例として、
プロトタイプベースの素養を持つ CLOS だの Python をひきあいに
だすなっちゅうの。わざとか?
502:デフォルトの名無しさん
04/03/29 20:41
504 名前: デフォルトの名無しさん :sage 投稿日: 04/03/25 (木) 18:00
>>501
>で、それも、どっちもclass baseでもできるんだよな。
class baseだとclass定義したりそのclassの知識がないとできないから、
ただ「できる」っていうのは無意味。
C言語でOOできると言い張るのと同じ。
prototype baseはinstance を見るだけで追加できるという点で
大きく違う。
それが有効かどうかはともかく。
505 名前: デフォルトの名無しさん :sage 投稿日: 04/03/25 (木) 18:07
>>498
世に”簡潔は力なり”っていうからねw。
オブジェクトが扱える範囲でよりプリミティブであることは
いいことなんでないの?ようわからんけど。
506 名前: デフォルトの名無しさん :sage 投稿日: 04/03/25 (木) 18:18
>>504
> C言語でOOできると言い張る
それはprototype basedでclass basedもできると言うのと違わない
のかえ?それが許されるなら、class basedでprototype basedもできる
ってのも通るような…
507 名前: デフォルトの名無しさん :sage 投稿日: 04/03/25 (木) 19:16
形から入る人が多そうなスレですね
503:デフォルトの名無しさん
04/03/29 20:48
508 名前: デフォルトの名無しさん :sage 投稿日: 04/03/25 (木) 19:28
> オブジェクトが扱える範囲でよりプリミティブであることは
> いいことなんでないの?ようわからんけど。
小さい事は良い事!ってなミニマリストにはそうだろうがねぇ.Scheme なんかは
オブジェクトシステム自体が好きにすれば?ということでもっとプリミティブな
仕様になってるが,ミニマリストはあーゆうのが イイ!! って方向にいっちゃうのかね?
でもさ,たとえば加算だけ用意すりゃ乗算は不要ってわけでもないだろ?プリミティ
ブだから良いって言われてもねぇ.なんか利点をガツーンとたのむわ.>>504 の解説
はわかりやすいなー.あとはそれがどのようにクラスベースよりイイのかを聞いてみたい.
509 名前: デフォルトの名無しさん :sage 投稿日: 04/03/25 (木) 21:43
>>508
でもさ、インスタンス特異的メソッドや属性がクラスベースで実現可能だからって
オブジェクトレベルでそれを実現するモデルを採用したオブジェクトシステムが
用なしってわけもないだろ? なんだ自分で答えてるじゃん。それだよ、それ。
510 名前: デフォルトの名無しさん :sage 投稿日: 04/03/25 (木) 22:22
お、また堂々巡り繰り返してるな。
511 名前: デフォルトの名無しさん :sage 投稿日: 04/03/25 (木) 22:23
>>508
そうさねぇ。
他人の作った生きているオブジェクトを
改良できることかなぁ。
.NETのClient side Validationはその具体例かな。
# ただインスタンスにメソッドを追加して回ってるだけなんだけどね。
504:デフォルトの名無しさん
04/03/30 01:19
512 名前: デフォルトの名無しさん Mail: sage 投稿日: 04/03/25 23:13
そして、言語の動的側面を勘違いした椰子が現れて… まわるぅ〜まわるぅよ(ry
513 名前: デフォルトの名無しさん Mail: sage 投稿日: 04/03/25 23:46
一見ループに見えるが完全に同じではない.循環を断ち切れる事を願ってるんだYO!!
>>509 の意見とか初耳のような気がするぞ.他人の作った生きているオブジェクトを改良できる?
それはプロトタイプベースの特徴なのか?しかし浅学故,それがどうプロトタイプベー
スと関連するのかわからない.オブジェクトの受け渡しと特異メソッドが必要だがプ
ロトタイプベースとは関係ないんじゃ?と思うんだけど違うのかな.
今のところ
1. 「クラス」がないからシンプル
2. 「クラス」がなくても同等の機能(…なの?)
くらいしか理解してないんだが.どうもプロトタイプならではってウリが見えないわ
け.インスタンスのコピーはクラスベースだと苦労が多いけど,プロトタイプベース
にしたら楽になるのかな?コピーの深さの問題はどうしようもない気がするんだけど.
514 名前: デフォルトの名無しさん Mail: sage 投稿日: 04/03/26 00:05
>>513
循環してるのは一部の人の頭の中だけだと思うよ。それを断ち切りたいなら、
何か言語いじってみれ。
505:デフォルトの名無しさん
04/03/30 01:20
515 名前: デフォルトの名無しさん Mail: sage 投稿日: 04/03/26 00:34
>>513
プロトタイプベースでは、それなりの規模のシステムではたいてい、トレイトと呼ばれる
クラスベースのクラスと同じ枠組みを作ってそれを使っています。したがって、クラスが
なくても同等…というのは(解釈のしかたにもよりますが)当たりません。
こうした状況はクラスベースの Ruby が特異メソッドを用意しているのと似ていますね。
違いを際だたせるとすれば、Ruby にあるプロトタイプベースの側面は、特異クラスという
ちょっとトリッキーな方法で実現されているのに対して、SELF などでのトレイトは、言語
自体には手を加えずに実現されてているというところでしょうか。
余談ですが、SELF には Ruby とまったく同様の目的と機能を持つミックスインすら
Ruby よりはるか以前からエンティティとして実装しています。それも、言語仕様には
まったく手を加えずに、です(もっとも、トレイトとミックスインの違いは、継承があるか
無いかの違いだけなわけですが…)。
何度か出ていますが、プロトタイプベースのメリットは、通常は言語仕様として出来合で
エンドユーザー(つまりプログラマ)が変更不能な部分を開放したかたちで処理系が提供
されている(できる)ことではないでしょうか。511 さんの言う「自分で改良できる」という
ニュアンスにはそんなところも含まれているように感じました。
これは、Smalltalk が処理系全体を Smalltalk 自身で記述し、エンドユーザーが自由に
閲覧、変更、拡張ができるようにしているのと似ていなくもないですね。ただ、SELF の
場合は、Smalltalk では変えられない部分も(たとえば、クラスとインスタンスの関係と
いったプリミティブな部分も) SELF 自体でトレイトフレームワークとして表現されている
ために、エンドユーザーが到達可能…というわけです。
Ruby の例に戻ると、仮に特異メソッドやミックスインの振る舞いに不満を感じても、まつ
もとさんを説得するまで仕様の変更は不可能です。しかし、プロトタイプベースなら自分の
好きに変えてしまえばよいのです。もっとも、これをミニマリズム、動的側面のメリットのとり
違い…と言われてしまえばそれまでですが。
506:この先、誰か持ってない?
04/03/30 01:21
516 名前: デフォルトの名無しさん Mail: sage 投稿日: 04/03/26 00:43
>>508
Scheme が好まれるのはミニマルだからというのもあるけど、一番大きいのは
何かを特別扱いする事が少ないってことだと思うんだよね。言い直せば、言語
仕様による制限が取り除かれているってこと。
クラスは便利だけど同時に制約ともなるから、それを言語の根幹に据えるのは
嫌だなぁ。
517 名前: デフォルトの名無しさん Mail: sage 投稿日: 04/03/26 00:46
>>512
動的じゃなきゃプロトタイプベースは成り立たないとおもわれ。
よって、動的であることの利点はプロトタイプベースの利点の一部に必ず含まれる罠。
518 名前: デフォルトの名無しさん Mail: sage 投稿日: 04/03/26 00:49
このスレが活性化するのって、誰かがガンガってソースコードを晒した時か vs. クラスベース
の時かのどっちかだよな。クラスベースの時は大抵不毛な話題に終始するけど。
519 名前: デフォルトの名無しさん Mail: sage 投稿日: 04/03/26 00:55
>>518
んだんだ。
traitsやmixin以外にどんな機能が実現可能か妄想したりするスレとかには……ならないなw
507:デフォルトの名無しさん
04/04/02 06:23
プロトタイプベースな言語で分散オブジェクト環境を構築するのって
結構大変そうっていうかパフォーマンスが苦しそう。
508:デフォルトの名無しさん
04/04/02 12:09
>>507
うん・・・でもパフォーマンスを考慮した従来型の ORB や RPC に代わって
SOAP とか出てきてる世の中だからなぁ。
509:デフォルトの名無しさん
04/04/03 01:41
sage :04/03/26 01:23
プログラム / プロトタイプベース・オブジェクト指向 - 情報
Lispがプリミティブなλ計算そのものだから何でもできるように、
プロトタイプは、OOについてプリミティブだから何でもできる、でいいの?
モノがほかのモノをプロトタイプとして持つってすごく変なモデルの気がするけど、
λ計算みたいに、数学的な意味を持ったモデルなんでしょうか。
プロトタイプがプリミティブたるOOモデルというのが多分数学的にあって、
クラスベースもその中にすっぽり入ってしまうんだと思います。
そういう、本物のOOの定義モデルが実はあるような気がします。
どの言語の何がOOの起源でObjectとはどうだこうだ、というレベルではなくて、
本物のOO定義モデルが。
制約は普通の手続き言語なんかそのものですよね。
チューリングモデルを制約することで使いやすくしているという意味で。
510:デフォルトの名無しさん
04/04/03 02:24
>>509
まんどくさいから、その辺からツッコミ直してみる。
> どの言語の何がOOの起源でObjectとはどうだこうだ、というレベルではなくて、
> 本物のOO定義モデルが。
prototype baseなモデルMpとclass baseなモデルMcを定義できたとして、
Mp上に仮想Mcを構築できて、なおかつ、Mc上で仮想Mpを定義できれば
どっちが本物とは言えなくなる罠。
と言うと、オッカムの剃刀と言い出す香具師がいるかもしれんが、
OOの全ての機能をObjectに集中させたのがprototype baseで、
オブジェクトの種類という視点では一番簡便になる。
一方、class baseではオブジェクトの生成とオブジェクトの働きを別々に記述するが
これは各機能をより純粋にモデリングしたということでもある。
> 制約は普通の手続き言語なんかそのものですよね。
> チューリングモデルを制約することで使いやすくしているという意味で。
これについては、そうは思わない。
チューリング機械は現代のプログラミング言語よりも表現上の制約を受けている。
つーか、チューリング機械なんて、ヘッドの左右への動きとヘッド位置にある
シンボルの置き換えでしか表現できないんだから、これ以上制約したら
ほとんど何もできなくなる罠。
511:デフォルトの名無しさん
04/04/03 16:59
> Mc上で仮想Mpを定義できれば どっちが本物とは言えなくなる罠。
これが出来ないんじゃないのかな、
というのが上のレスと思われ。
> チューリング機械は現代のプログラミング言語よりも表現上の制約を受けている。
これについては、そうは思わない。
チューリング機械は現代のプログラミング言語の表現のどのようなモノも、
(表現が長たらしくなるが)表現できる。逆に、
現代のプログラミング言語はチューリング機械の表現のどのようなモノも、
(言語機能と同レベルで)表現できるとは限らない。
「言語機能と同レベルで」ってのはチューリング機械自体をエミュる層をわざわざ作らずに、ということ。
512:デフォルトの名無しさん
04/04/03 17:23
>>511
> > Mc上で仮想Mpを定義できれば どっちが本物とは言えなくなる罠。
>
> これが出来ないんじゃないのかな、
> というのが上のレスと思われ。
クラスベース環境上にプロトタイプベース環境を構築した例など腐るほどあるが。
> 現代のプログラミング言語はチューリング機械の表現のどのようなモノも、
> (言語機能と同レベルで)表現できるとは限らない。
現代風のプログラミング言語で実現できない例を挙げてみなよ。
つーか、とりあえず構造化プログラミングの論文でも読んでみれば?
513:デフォルトの名無しさん
04/04/03 17:54
> クラスベース環境上にプロトタイプベース環境を構築した例など腐るほどあるが。
ああ、まったくそのとおり。ずばりエミュだもんな。ぼけてた。
これについては>>510の通り。
> 現代風のプログラミング言語で実現できない例を挙げてみなよ。
チューリングマシンのコーディングは漏れは出来ないけど、
関数Aのn行目から任意の関数Xのm行目にジャンプするってできないじゃん?
514:デフォルトの名無しさん
04/04/03 18:03
まあ、何が言いてぇかっつうと、
Lispだとプリミティブな計算モデルそのものだから、
任意の言語モデルを作って使えるみたいに、
プロトタイプはプリミティブなOOモデルそのものだから、
任意のOOモデルを作って使えるんじゃないかな、という妄想。
まあ、そのためには記法の問題っつうか、
Lispのマクロ相当がないとそのままは使えないけど。
515:デフォルトの名無しさん
04/04/03 18:22
プロトタイプ機構? (゚Д゚)ハァ?そんなの余計なお世話。
こんなお仕着せの機構で成り立ったシステムがプリミティブだなんて
あり得ねぇよ。クラス機構と目糞鼻糞。
516:デフォルトの名無しさん
04/04/03 18:25
>>513
> 関数Aのn行目から任意の関数Xのm行目にジャンプするってできないじゃん?
そんなことはチューリングマシンでもできん罠
517:デフォルトの名無しさん
04/04/03 18:40
チューリングマシンに関数なんてない、
だから相当するモノを作ることになる。
で、自分で作るんだから、
> 関数Aのn行目から任意の関数Xのm行目にジャンプするってできないじゃん?
が出来るように作ればいい。schemeで似た事出来るし、出来るでしょ。
はNG?
518:デフォルトの名無しさん
04/04/03 18:47
>>515
プログラムコードの再利用機構って意味では、委譲ベースでも継承ベースでも
どっちでも良いな。相互排他的な物でもないし。
どっちも無いと困るけど。
肝はオブジェクト生成後にメソッドの再定義を受け付けるかどうかだと思う。
変数のスロットはインスタンスローカルで持てるのに、メソッドのスロットを
インスタンスローカルで持てないのって不便。
519:デフォルトの名無しさん
04/04/03 18:49
>>518
> 肝はオブジェクト生成後にメソッドの再定義を受け付けるかどうかだと思う。
> 変数のスロットはインスタンスローカルで持てるのに、メソッドのスロットを
> インスタンスローカルで持てないのって不便。
それ、Smalltalkでは動的にどうとでもできるって話が出てなかったか?
520:デフォルトの名無しさん
04/04/03 18:51
>>517
エミュるんだったら、プログラミング言語でもエミュるのアリにしないとな。
521:デフォルトの名無しさん
04/04/03 18:59
>>520
論理的な問題じゃなくて、実際的な問題。
チューリングマシンは概念がないから概念をエミュってなんぼのモノ。
プログラミング言語は、エミュらなくてもすぐ概念を使えるようにしているモノ。
用途で考えれば、プログラミング言語でもエミュるのは無意味。
エミュって概念壊したらプログラム言語の意味ないじゃん。
522:デフォルトの名無しさん
04/04/03 19:02
>>519
別クラスを生成して become するって話?
それともブロッククロージャを変数に代入してコールするとかかな。
523:デフォルトの名無しさん
04/04/03 19:04
> 肝はオブジェクト生成後にメソッドの再定義を受け付けるかどうかだと思う。
どういう意味でキモなのかわからん。
委譲ベースとか継承ベースとかと関係が見えない。
とりあえず、リフレクション最強、
と言っておけばいいのか?
524:デフォルトの名無しさん
04/04/03 19:15
>>523
>> 肝はオブジェクト生成後にメソッドの再定義を受け付けるかどうかだと思う。
>どういう意味でキモなのかわからん。
>委譲ベースとか継承ベースとかと関係が見えない。
コードの再利用機構 ーー> どうでも良い
メソッドの再定義可能性 ーー> こっちが重要
リフレクションは実現方法の一つに過ぎないと思う。
525:デフォルトの名無しさん
04/04/03 19:15
>>518
いやいや、メソッド呼び出しとは何かの定義次第だから、
どっちもなくていいでしょ。それを定義できればいいんだから。
つまるところ、CLOSを産んだLisp最強ってことで。
526:デフォルトの名無しさん
04/04/03 19:18
>>524
なる。でもそれは必要なのは、
メソッド再定義可能性、じゃなくて、>>525の呼び出しの定義では?
委譲ベースでの定義 自分を捜して、なければプロトタイプから探す
継承ベースでの定義 自分のクラスを探して、なければクラスの親から捜す。
これ以外にもあり得るでしょ。
527:デフォルトの名無しさん
04/04/03 19:24
結局、プリミティブなOOモデルなんて存在しねぇと。
クラスベースもプロトタイプベースも目糞鼻糞。
528:デフォルトの名無しさん
04/04/03 19:38
>>525-526
なるほど、そうですね。
>それを定義できればいいんだから。
までは考えてませんでした。
>自分を捜して
というのがあれば自分的には嬉しいです。
Scheme みたいに、シンボルに束縛されているのが値か手続きか区別しない(
評価する時に S 式の頭にあれば手続きと看做される)ようなモデルがイイですね。
メソッドテーブルはクラスに属し、変数テーブルはインスタンスに属するという
のは実装上の都合ですよね。これは一貫性に欠けると思います。特にメソッドが
ファーストクラスなら、尚更。
529:デフォルトの名無しさん
04/04/03 20:04
>メソッドテーブルはクラスに属し、変数テーブルはインスタンスに属するという
>のは実装上の都合ですよね。
実装って言うか、それがクラス、なのかな?
うーん、クラスってなんだろ。
欲しいのは、
自分を捜して、なければ自分のクラスを探して、なければクラスの親から捜す、
っていう感じ?
しらんけど、Rubyってこんなんじゃない?
530:デフォルトの名無しさん
04/04/03 20:17
消えたログの続きが読みたい・・・。
>>509 は >>506 の続きになるのかな。
531:デフォルトの名無しさん
04/04/04 00:57
>>529
メソッドに話を限れば、クラスは、オブジェクトにとって
・原則として変更が許されない
・無条件移譲先
ですね。逆に言えば、プロトタイプベースのオブジェクトにこのような
制約を課すことで、オーソドックスなクラスベースのオブジェクトが
できあがるわけです。縛りを緩くすれば、プロトタイプベースの要素を
盛り込むことができます。
532:デフォルトの名無しさん
04/04/04 01:22
>>531
さらに、自分が委ねられたメソッド起動リクエストについては、無条件委譲先
ではなく、あらかじめ別に用意した移譲先に委譲する…という縛りを設ければ
より完全にクラスベースの振る舞いをさせることができそうです。
たとえば、Smalltalk のクラスは(インスタンス)メソッドを持っていますが、
それらはインスタンスから委譲された場合のみ起動でき、自分で起動する
ことはできません。これは先の無条件委譲のしばりが効いていると考えるとうまく
説明できます。また、インスタンスから委譲されたが自分は持っていない
メソッドについては、ここで述べた「自らがレシーバでないときは、無条件
移譲先に委譲できない」という縛りから、二つある委譲先スロットのうち、
無条件移譲先には委譲できず、もう一方、つまりスーパークラスへ委譲せざるを
得ない、というふうに解釈すればよいわけです。
533:デフォルトの名無しさん
04/04/04 01:28
>>532
このようなメソッドディパッチの観点から言うと、CLOS はそもそも
メソッドがオブジェクトに属しておらず、クラスベースでもプロトタイプ
ベースでもないので、ちょっと脇によけておいた方がよさそうですね。
534:デフォルトの名無しさん
04/04/04 01:39
じゃ、クラスベースはどんな制限をつけるとプロタイプベースになるの?
535:デフォルトの名無しさん
04/04/04 03:08
>>534
クラスのインスタンスが常にひとつであるような制約を課すことで(見かけ上の)
プロトタイプベース・オブジェクトを実現できます。
たとえば、Smalltalk のようにクラス自身もオブジェクトで、かつ、メタクラスの
シングルトンであることが保証されている言語なら(非クラスの)インスタンスを
使わず、クラスを使うことでそのままプロトタイプベースプログラミングが(見かけ上)
可能です。
インスタンスに直接メソッドをもたせるような機構にしなければならないのならば、
制約を課すだけでは駄目で、薄いながらも何かしらレイヤーを書いてやる必要が
あるでしょう。
536:デフォルトの名無しさん
04/04/04 05:37
>>528
> Scheme みたいに、シンボルに束縛されているのが値か手続きか区別しない(
> 評価する時に S 式の頭にあれば手続きと看做される)ようなモデルがイイですね。
スレ違いだが、それはどうだろうね。
変数名とメソッド名への制約が増えるから、俺は嫌いだね。
537:デフォルトの名無しさん
04/04/05 16:15
えーと、「出来ます」ってだけだと、そりゃある程度強力な言語ならあちてい何でもできるわけで、
インスタンスベースのスロットの定義等について、その機構をサポートする簡易な文法があって、
便利に利用できるってことが重要なんじゃない?
例えば、プロトタイプ言語で
human = [ kind: #human, bark() { print("I'm human");} ];
anAho = [ _proto: human, iq: 100, bark() : { print("My name is aho");} ];
とか2行でかけるものを、何行も文を連ねて書いて「出来ます」ってのはなんか違うっていうか・・・
538:デフォルトの名無しさん
04/04/06 02:08
>>537
簡単なオブジェクトを簡単に記述できるというのは、
スクリプト言語ならば重要な問題かもしれんが、
環境がベースになっている言語ではあまり本質ではないね。
つまり、スクリプト言語に使うのならメソッドを2,3定義するだけでいいものが多いから
1行や2行で書けるかどうかが問題になるが、もっと環境を使ってライブラリ蓄積
していくことを想定した言語では、そういった1行コードは問題ではない。
あと、Modula-3のopaque typeのように一見煩雑に見えるけど
言語機能としてはそれなりに洗練された結果というものもある。
539:デフォルトの名無しさん
04/04/06 06:41
>>537
流行ってないんでしようがないのだけれども、こういうのはある意味典型的な
プロトタイプ言語のコードなわけで、なんてのかな、>>535の前半のような発想よりは
むしろ↑の方で出てきたクロージャでインスタンスを実現するものの方が指向が
近しいような気がする、というか。。
>>536
>スレ違いだが、それはどうだろうね。
たぶん殆どのプロトタイプ言語でその区別は行われていないと思います。
好き嫌いはともかく。
540:デフォルトの名無しさん
04/04/06 07:23
>>537-539
あのー、いつの間にモデルの話からリテラル表現の話に飛んでいったのでしょうか?
あと、当然ながら処理系の設計の話もまた別の話だ罠。
541:デフォルトの名無しさん
04/04/07 13:17
モデルの話は結論?まで逝ったからいいでしょう。>>537-539は解ってなさそうだけど。
ところで、POOとUMLの関係ってどうなん?
542:デフォルトの名無しさん
04/04/07 14:26
>>532
> さらに、自分が委ねられたメソッド起動リクエストについては、無条件委譲先
> ではなく、あらかじめ別に用意した移譲先に委譲する…という縛りを設ければ
> より完全にクラスベースの振る舞いをさせることができそうです。
それだと、メタ方向の委譲とスーパー方向の委譲が混ざらないか?
543:!532
04/04/08 01:10
>>542
メタ方向ってインスタンス←クラス←メタクラスの関係の事?
スーパー方向はインスタンス←クラス←スーパークラスだよね。
>>532
で、>>532 が言ってるのは、foo.bar() で foo のクラス Foo がメソッド bar() を
持っていない時、クラス Foo は(Foo 自身のクラスである) MetaFoo に問い
合わせずに、別に用意されたクラス SuperFoo に問い合わせに行くようにする。
MetaFoo に行くか SuperFoo に行くかは、自分がレシーバかどうかで判断する。
・自分がレシーバの時は自分のクラスに問い合わせる(自分がクラスならメタクラス
に問い合わせる ーー そんなケースあるのかな?)
・自分がレシーバじゃない時はスーパークラスに問い合わせる
であってます?
自分がレシーバじゃないってどう判断するのかな?
プロトタイプチェーンが分かっていないので、変な事を言っていたら済みません。
544:デフォルトの名無しさん
04/04/08 02:20
処理系の実装が複数あって、仕様がある程度きっちり決まっているプロトタイプベース
言語って JavaScript 以外にあります?
545:デフォルトの名無しさん
04/04/08 08:33
>>543
そういう制御をしようとしたら処理系自体に手を入れないと話にならんでしょ
546:デフォルトの名無しさん
04/04/10 05:25
Smalltalk の SomeClass allInstances do: [foo_proc] みたいなイメージで、
あるプロトタイプを共有しているオブジェクト全てにメッセージを送信する
機能を持っているプロトタイプベース言語ってありますか?
547:デフォルトの名無しさん
04/04/10 22:54
>>546
細かいようですが、SomeClass allInstances do: [:inst | inst somethingToDo] ですね。
で、本題は SomeClass allInstances みたいなものがあるか?
ということでよろしいですか? それなら元祖的存在の SELF にすでに
browse childrenOf: obj
というのがあります。プロトタイプスロットに obj を束縛している
全オブジェクトをリスト(a vector) で返します。
548:デフォルトの名無しさん
04/04/11 21:24
>>547
どうもありがとうございます。
オブジェクト生成する毎に辞書に登録してるのかしらん。
プロトタイプベースの言語は個々のオブジェクトは野放し状態だと
思ってましたが、ある程度の管理はされているんですね。
549:デフォルトの名無しさん
04/04/12 02:43
>>548
ん〜、でも、Smalltalk においても #allBehaviorsDo: なんかは本来はオブジェクト全部に
問い合わせたりするのがスジだったりするので(高速化のための端折っていますが)
クラスベース、インスタンスベースに限らず、全オブジェクトがオブジェクトメモリ内にあるか、
さらに、それらにアクセスする手段があるか否かってところで、allなんたらな機能が存在しうる
かどうかが決まってしまうような気もします。
まあ、純粋なオブジェクト指向(そんなものがあればの話ですが…(^_^;))を論ずるとき、
実装において、高速化や最適化がからむ部分は解釈が難しいですね。たとえば、
消えてしまったログの object-oriented pointer で表現されるオブジェクトには“状態”
はあるかないか…なんて話とかもそのたぐいだと思います。
次ページ最新レス表示スレッドの検索類似スレ一覧話題のニュースおまかせリスト▼オプションを表示暇つぶし2ch
5404日前に更新/368 KB
担当:undef