オブジェクト指向談義 on Twitter
今朝方Twitterでこのエントリを紹介したら、
オブジェクト指向談義が盛り上がったのでその議事録をば。
monjudoh | とてもためになる読み物http://return0.dyndns.org/log/2008/08/10#s_2 |
monjudoh | >「クラスベースのオブジェクト指向プログラミング言語はプロトタイプベースのそれの特殊ケースであり、プロトタイプベースは関数型言語で大抵はエミュレートできる、というか関数型言語のサブセットに近いと思ってる。」 |
nagise | @monjudoh みねこあさんとこのエントリ読んでたら、自分の理解するOOPが実はOOPじゃないんじゃないかと思えてきて。 |
iratqq | @monjudoh エミュレートは出来ても使い物になるものにするにはファーストクラスのマクロが必要で、つまりCL最強という話ですね、わかります。 |
deq | @monjudoh クラスベースというかclassってstrongly typedなよーな、つまりcompile timeに型チェックができる仕組みのよーな気がするのですが |
nagise | ちょっと前まで自分は「JavaのOOP」こそOOPだと思っていたんだけど、プロトタイプベースを学んで理解するに至って、どうやら自分が主軸を置いていたのはOOPというより型システムなんだなと理解した。 |
nagise | Javaのような静的で強い型付けの言語が、OOPと組み合わさった時に得られる効果が自分は凄く好きで、動的言語が嫌いなのはそのOOPがどうよ?とかそんな話でなくて、単に型による制約が行えないのが嫌なんだな、と。 |
yugui | @nagise じゃあJavaよりC++だ! |
nagise | @yugui うーん。でもC++のテンプレートよりJava式のジェネリクスが好きで、OOPとジェネリクスによってがちがちに固めた型システムがたまらなく好きなんですよ |
nagise | あとは、型システムをうまく使ったアスペクト指向がのっかれば、かなりパワフル。AspectJとかをやりかけているんだけど、まだ評価中の段階。 |
nagise | Javaのintとかのプリミティブ型がOOPやジェネリクスを阻害しているから、やはりScalaに移ろうかな、とは思っている。 |
nagise | いまどきの高級言語はプリミティブ型なんていうパフォーマンスのための泥くさいデータ型なんて抽象化しちゃうべきなんじゃないか。Pythonとかを見ているとそう思うな。 |
t_yano | @nagise いやープリミティブがあるかどうかはパフォーマンスにもろに影響しますからねえー。私はあったほうがいいと思うな。そこが仕事言語たるところというか。 *Tw* |
t_yano | そういう意味では C# の struct とかわりと好きかも。 getter/setter しかない class ってものを端的にあらわしてくれてパフォーマンス的にかなりよい。 *Tw* |
nagise | @t_yano でも、プリミティブゆえのボクシング変換でしょう?あのあたりどうにかならないのかなぁ。JITとか頑張ればパフォーマンス上の問題は薄くなるとは思うんですよね。 |
nagise | というか、コンパイル前の時点でプリミティブじゃないように、という話だから本当に愚直にintに対してメモリ上にオブジェクトを作らないといけないというわけではないけど。 |
nagise | やっぱりC#はバイナリ指向だな。Javaが抽象指向で。 |
monjudoh | @t_yano プリミティブは裏で使うけど表に出さないとか出来ないのかなー。確かRubyはそうじゃなかったっけ?>プリミティブがあるかどうかはパフォーマンスにもろに影響 |
yugui | @nagise 私はJavaのジェネリクスの融通が利かないのにルーズなのがいまいち。C++でグニャグニャなのに抜けようもなく型チェックされるのが好き。 |
monjudoh | 元々のエントリを何で引用したかというと「クラスベースのオブジェクト指向プログラミング言語はプロトタイプベースのそれの特殊ケースであり」の辺りで、昨日した話JavaみたいなClassありきのオブジェクト思考言語で勉強を始めるより、JavaScriptで{}で普通のプロパティだけ持ったオブジェクトを作る、メソッドを持ったオブジェクトを作る、prototypeを使うというのをそれぞれよくなれてから次の段階に進ませる方が理解しやすいのではを思い出したからなのだ。 |
t_yano | @monjudoh 自動的にキャストしたりするのならできるんでしょうけど、それだとパフォーマンスが犠牲になってしまうので ..... *Tw* |
t_yano | プリミティブをそのままプリミティブとしてオブジェクト型とわけて処理できたほうがよいかなーと思う。 *Tw* |
monjudoh | 「プロトタイプベースは〜関数型言語のサブセットに近い」でJavaScriptがプロトタイプベースオブジェクト指向言語SELF と関数型言語Schemeの影響を受けているっというのを思い出したとか。 |
nagise | @yugui ルーズってのは? |
nagise | @t_yano えー。でもListみたいなコレクションAPIとかが酷いことになるでしょう?ボクシングの機能って相当汚いですよ。 |
nagise | @monjudoh 理解に必要な知識のステップから言えば、そういう階段の昇り方は確かに自然に思いますね。 |
nagise | 強い静的型付けの言語ってのは型システムを飼いならしてなんぼ、なんだけど、その壁はすごく厚く高い気がする。 |
t_yano | @nagise C# は struct というプリミティブと同様のパフォーマンスを持つものを持ち込んで、 Int とかは Struct で定義して解決したので、そういうプリミティブを導入したらいいんだろうなー *Tw* |
t_yano | というか、プリミティブを List に突っ込めないという仕組みのほうが問題なんじゃないのかな。プリミティブの配列を作れることと整合性が取れてないというか。 *Tw* |
t_yano | その実現方法が C# の場合は Struct だったけど、別に実装方法はなんでもいい。 *Tw* |
t_yano | となると、 VM 仕様を変えないといけないので、 Java の場合互換性考えると無理かなー *Tw* |
monjudoh | 調べてみたらSelf軽い件>「Self の VM(仮想機械)は C言語と比較して(一部のベンチマークで)約半分程度の性能を達成している。」http://ja.wikipedia.org/wiki/Self |
t_yano | そういや、 Scala はプリミティブはどう処理してるんだろ。なんかいい方法があるのかな。あるんならそれを Sun がパクればいいんだけど。 *Tw* |
alohakun | OOP って言った時点で最低 3 種類ぐらい (ユーザ定義型,メッセージパッシング,総称関数(抽象データ型),...)の流派があるんで,もう OOP っていう用語は廃止した方が良いよ派ですね. |
alohakun | あとプロトタイプか. |
alohakun | オブジェクト指向というのは,要するに AI の知識階層を実装するための,知識表現手法の一つだと思っている. |
kmizu | 俺は抽象データ型のスーパーセットの流儀が基本かなあ…すっぽすっぽ先生より、どちらかというとめいやー先生の影響の方が大きい気がする |
nagise | 自分がプリミティブの何が嫌かって、それは設計論じゃなくて実装論だろう、設計の邪魔をするんじゃねぇ!ということに尽きる。 |
nagise | 設計のレイヤからは実装論は外しておきたい。実装の都合って奴はできるなら局所化して隠ぺいしてしまいたい。 |
kmizu | あと、抽象データ型のスーパーセットとしてのOOPを教えるときは、 DbC( とか LSP) もセットで教えるべきだと思う ( 順番的には後で良いと思うけど ) 。 |
t33f | プログラミングパラダイムとしての OO がどれくらいよいものであるのか僕はよくわかっていない。思考のためのフレームワークとしてはよいものだと思っている。OCaml や Haskell のような静的型が設計を助けてくれるのと似たような感覚で。 |
melponn | @nagise でもやっぱり理論を現実世界に落とし込む以上、実装の都合っていうのが漏れ出てくるんですよねー。 |
nagise | @melponn それがどの程度影響するのかってところだと思う。カリカリにチューニングしちゃうと保守とか非現実的になるわけだから、実装の都合での複雑化は避けたい。 |
nagise | かといってO(n2)みたいなアルゴリズムを選んでいいってほどには実装の都合を考えなくていいってわけにはいかないだろうけども。 |
nagise | だからって、プリミティブみたいなそこら中に散らばっている奴全部でパフォーマンスという実装上の都合が出てくるのは違うんじゃないか |
melponn | @nagise 実装上の都合と言えば、配列やリストとかもそうですよねー。 |
nagise | @melponn 僕は配列ももはやいらないと思ってる。言語に可変長配列の機構が組み込まれていればいい。だけど、その内部が配列か、双方向リストなのかは無視しちゃいけないと思うから面倒なんだ |
melponn | @nagise でも初期化時で決定したらもう変更できない固定長配列が欲しいと思うことはありますけどね。そうじゃないと、メソッドにそれを渡して帰ってきたときに数が同じであるという保証ができない。 |
nagise | よく使うデータ構造が言語にビルドインされることは肯定するんだけど、実装は選びたい。そこの特性を無視していいとは思わないんだよね。 |
melponn | @nagise まあでも、それは実装の都合とはまた別問題ですかね。 |
nagise | @melponn そういうListがあるならあるでもいいんじゃないかな。固定長Listがあってもいい気がする。言語にビルドインするならどういう抽象レベルでやるべきだろうか。[0]みたいなインデックスアクセスでいいんだろうか? |
melponn | @nagise ライブラリを一切持たないすごく小さい言語仕様に対して各人が用途に応じてライブラリを実装するしか! |
melponn | @nagise 言語にビルドインするものってどうやって選ぶんでしょうかねー。 |
melponn | 欲しい実装が全部用意されている言語さえあればっ! |
melponn | call ほげほげ、とかやったらほげほげアプリが実行されるような言語きぼんぬ |
melponn | まてよ、もし、これから全て作られるアプリケーション全てに対して一意なIDさえ付けられれば |
melponn | そのIDさえ覚えておけばいつでもそのアプリケーションを実行できる言語が実装できるのではないか |
nagise | 言語にビルドインされる配列的機構に対して、そのデータ構造特性を指定する機能があるとすれば、今思いつくアイデアではSQLのヒントのような形での明示だろうか。 |
nagise | @melponn 問:既存のIDすべてを返すプログラムのIDを示せ |
nagise | ヒントによる言語ビルドインの配列的機構の実装決定は、型の代入互換性ということを考えると大きな問題を孕んでいる。双方向リストに配列によるリストを突っ込めるか?という話題。 |
t_yano | 抽象化をめざすならプリミティブを隠蔽するんじゃなくてプリミティブは捨てたほうがきれいだと思うんだよな。 int って書いたら全部 Integer ってくらいに。残すならちゃんと見える形で残してほしいって程度。 *Tw* |
t_yano | あと、配列はプリミティブは内包できるしオブジェクトのプロパティがプリミティブなのは何も問題ないので、やはりコレクション(関連して generics )がプリミティブをうざくしているように思う。 *Tw* |
t_yano | やっぱりコレクションにプリミティブを入れたいな。 *Tw* |