K.Maebashi's BBS

ご自由に書き込んでください。雑談も可。
テスト書き込みの類はテスト用掲示板にどうぞ

[日付順表示] [日付順インデックス] [スレッド順インデックス]

新規投稿 | 開設者ホームページへ戻る | ヘルプ

[1326] Re:コード生成部分について
投稿者:
2009/06/01 01:48:27

>>int[] func(p1,p2,p3); >>これの int[] 配列の戻りが禁止になっています。 > >対策するのであれば、ユーザには、配列への参照自体を取得できないようにしておかな Cで言う所のポインターの存在がありません。だから、グローバル変数に参照を 入れることが出来ません。 int func(p1[],p2[]) { p1[2]=10; // これはOK p2[4]=9;    // これはOK p1=p2;     // これがエラーです } ひょっとしてdiksamはOKでしたか? (駄目だと思い込んでいました)仕様が変わっています。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1325] Re:コード生成部分について
投稿者:(ぱ)こと管理人
2009/06/01 01:30:54

>int[] func(p1,p2,p3); >これの int[] 配列の戻りが禁止になっています。 具体的にどうされているのかがよくわかりませんが、少なくとも、関数の戻り値の型として 配列型を返せないようにするだけでは不完全ではないでしょうか。 ユーザが、配列への参照を取得できるのなら、それをグローバル変数に代入することも できるはずで、もしそれをされたら、関数を抜けてスタックが開放された時点で 不正なポインタになってしまいます。 対策するのであれば、ユーザには、配列への参照自体を取得できないようにしておかないと だめなのでは。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1324] Re:コード生成部分について
投稿者:
2009/06/01 01:11:00

>ええと、ということは、そもそもユーザは配列への参照を取ることができない >(配列を引数として別関数に渡すときは内部的には参照が作られるが、ユーザがそれを >変数に代入したりすることはできない)ということでしょうか? >それなら問題ないように思います。CやJavaに慣れた身にはちょっと不便そうですが。 言葉足らずですみません。 int[] func(p1,p2,p3); これの int[] 配列の戻りが禁止になっています。 int func(p1[][],p2[]) これは問題ありません。内部で操作しても問題なく処理されます。 配列は参照渡しなので、子関数で操作したものは、呼びだし関数の配列内が変わります
[この投稿を含むスレッドを表示] [この投稿を削除]
[1323] Re:コード生成部分について
投稿者:(ぱ)こと管理人
2009/05/31 22:03:45

>>Cですごくありがちなバグである、 > 配列の参照戻しは今エラーにしています。もともと、配列は参照渡しなので、 >リターンで戻す必要を感じなかったので。 ええと、ということは、そもそもユーザは配列への参照を取ることができない (配列を引数として別関数に渡すときは内部的には参照が作られるが、ユーザがそれを 変数に代入したりすることはできない)ということでしょうか? それなら問題ないように思います。CやJavaに慣れた身にはちょっと不便そうですが。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1322] Re:コード生成部分について
投稿者:
2009/05/31 03:19:58

 やはり寝ながら思いついたアイデアは細部まで検討されていませんでした。 出来なくは無いのですが、副作用が見つかったし。やはりトリッキーでnew事態の 一般的な意味の仕様も変えてしまうのは問題が有るので、上のアイデアは 無かったことにしてください。 orz  今日は寝れそうに無くなってしまった…
[この投稿を含むスレッドを表示] [この投稿を削除]
[1321] Re:コード生成部分について
投稿者:
2009/05/31 02:48:40

>Cですごくありがちなバグである、  配列の参照戻しは今エラーにしています。もともと、配列は参照渡しなので、 リターンで戻す必要を感じなかったので。  いや~~寝ようとしたら、動的配列生成でトリッキーな方法を思いついてしまって 眠れなくなってしまいました、ここ2日間の作成をチャラにして元に戻そうかな~~  何を思いついたかと言うと、配列をnew宣言したときにスタック上の配列データの所を 開ける、その為にスタックを移動することです。スタックにリアルアドレスを持ってい るわけではないし、アドレス操作をするときは移動してないわけで。たぶん問題ないかと。  ああ~~~だめだ、思いついたらやらないでおけなくなってしまう。寝ながら だめだ、だめだ、こんな変なこと考えてはと、何度繰り返したことか。でも、どうせ 好きに作れるんだからやってしまおう^^ どう思いますか? 
[この投稿を含むスレッドを表示] [この投稿を削除]
[1320] Re:コード生成部分について
投稿者:(ぱ)こと管理人
2009/05/31 02:10:17

>>(1)Cのように、配列の領域をスタック上に取る。 >ご指摘ありがとうございます。前の書き込みからVMをいろいろ調べていましたが、 >まさに(1)の方法を取ろうと思っています。このレス読んだのがちょうど今日なん >ですよ。 この方法を取るとして、ローカルな配列への参照を、別関数に渡すことは できるのでしょうか? できるとしたら、配列への参照がプログラマの思いのままにできるということですから、 Cですごくありがちなバグである、 char *get_line() { char buf[256]; /* bufに値をつめる処理 */ return buf; } みたいなのも許すことになりませんか?
[この投稿を含むスレッドを表示] [この投稿を削除]
[1319] 配列の仕様について
投稿者:
2009/05/30 21:54:58

 上記の仕様変更により。yacc,lex部分からの修正をしています。 下に示すようなプログラムに。diksamの言語仕様と離れていってしまうのは 仕方の無いことかもしれません。それに、ほぼC言語に近くなってしまう。 ちなみに、配列変数宣言時に[]内に変数を入れるとエラーになります。 ---------------------------------------- int main(int p1,int p2) {   int aa;   string[1+2] msg = { "asd","qwe","zzz"};   int[1+1+1] i1 = {1,2,65537};   int[10][9] id;   id[5][4] = 321;   aa =id[9][8]; } ----------------------------------------  結局の所、GCを装備して配列の動的確保を可能にし、管理のための処理及び間接 アクセスのためのオーバーヘッドを許すか。領域を固定にもって直接スアクセス し、高速で単純な処理だが配列領域は宣言時に固定で確保しなければならないか。 のチョイスで有ったのではないかと思います。  私は今回、連続的な処理(一般的なプログラム)より。マルチスレッドで複数の 小さな処理の集合体による制御を優先しているので下の方を選びました。単にGCを 入れたくなかっただけかもしれませんが^^;
[この投稿を含むスレッドを表示] [この投稿を削除]
[1318] Re:>(ぱ)こと管理人さん
投稿者:(ぱ)こと管理人
2009/05/30 12:38:04

>一応、抽象化されていますが、確かに分かりにくいかもしれません。 「分かりにくい」とか「一応、抽象化」といった話ではなくて、SEさんの出した UpperStackでの継承の使い方は *間違っています*。 仮に実装継承による差分プログラミングを(いろいろの弊害は度外視して)認めると しても、それが趣旨ならUpperStackをStack型の変数に代入してはいけないし、 スタックから要素を取得するメソッドはget()をオーバーライドしてはいけません。 getUpper()のような別のメソッドを作るべきです。 たとえ「リスコフの置換原則」とかの名前を知らなくても、ポリモルフィズムを 理解していれば、当然そう考えると思うんですが。 >FileWriterを例にした方がいいかもしれません。内容的には同じ意図です。 「同じ意図です」って、どういう意図でしょうか? FileWriterがこういう継承関係になっている「意図」を理解しているのなら、 オセロ盤に棋譜を吐かせるのに、Boardクラスによりによって「ファイル名」を 渡すなどという設計がでてくるはずがないのですけど。 http://kmaebashi.com/bbs/list.php?boardid=kmaebashibbs&from=1303&range=1
[この投稿を含むスレッドを表示] [この投稿を削除]
[1317] Re:>(ぱ)こと管理人さん
投稿者:(ぱ)こと管理人
2009/05/30 12:29:14

>Cではモジュール化しようと思った所しかモジュール化しません。 >具体的に言うと、せいぜいDBアクセスとか通信部分などでしょう。 えーっ! 私がある程度大きなプログラムを最初にCで設計から実施したのは、入社2年目でしたから かれこれ15年くらいは前の話ですけれど、すべての関数をモジュールに入れていました。 5万行程度の、UNIX上のシステムで、XとMotifで画面描画するようなシステムでした。 他にもいろいろなシステムを見ましたが、数万行以上の規模なら、誰が設計しても、 まずモジュール分割はやっていたように思います。ヘッダファイルをちゃんと分離して なかったりして変なことになっているケースはよくありましたが。 そういう経験もあって、2000年2月ころに書いたのがこちら。 http://kmaebashi.com/programmer/c_yota/module.html 現在作っているcrowbarやDiksamといった言語も、モジュール分割はしています。 Diksam ver.0.2のソースにGLOBALをかましたのはこちら。 http://kmaebashi.com/programmer/devlang/diksam_src_0_2/index.html メモリ管理モジュールMEMやデバッグ用モジュールDBGの上に、コンパイラDKCと 仮想マシンのDVMがあります。その中でも機能ごとにソースファイルを分けると いったようなことはしています。 なお、なにせCなのでモジュール化の単位はクラスではないですけど、 これはその方が都合がよいという考えでそうしています。 Javaでも、メンバのアクセスレベルがデフォルトで「パッケージ」になっている あたり、「実装隠蔽の単位としてクラスは適当ではない」というのが現状の コンセンサスでいいんじゃないかと思っています。 ……それはさておき。 私も長いことこの仕事をやってますから、いろいろアレな設計やナニなソースを 見てきたつもりでいましたけど、なんだかんだでずいぶん恵まれた環境にいたのかなあ。 これでも。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1316] Re:Smalltalk原理主義を粉砕せよ! (was Re: オブジェクト指向の…
投稿者:(ぱ)こと管理人
2009/05/30 12:11:31

おお、ご本人が降臨されるとは。 >それらしいのを見つけましたがこれですか? >http://groups.google.co.jp/group/fj.comp.oops/msg/973f372a89455de2 そうですそうですこれです。 「殲滅」ではなくて「粉砕」でしたね。 しかも対象は「Smalltalk原理主義者」ではなく「Smalltalk原理主義」。 主義者を殲滅というのは物騒でいかんですねえ。反省。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1315] Re:コード生成部分について
投稿者:
2009/05/29 23:00:15

> {"new_array_int", "b", 16}, // 次元数 基本データ-型の配列生成 > {"new_array_double", "b", 20}, // 次元数 基本データ-型の配列生成 > {"new_array_object", "b", 16}, // 次元数 基本データ-型の配列生成 > {"new_array_literal_int", "s", 16}, // int定数配列を変数に接続 > {"new_array_literal_double","s", 20}, // double定数配列を変数に接続 > {"new_array_literal_object","s", 16}, // object定数配列を変数に接続 補足  このnewは構文のnewではなくスタック上に実配列生成のnewです。 ちなみに、言語上の総ての関数は特に何も記述することなくスレッドセーフに なります。複数のスレッドから関数AAAを同時に呼んでも問題が無いです。 もちろん組み込み関数も。利用者はスレッドを意識することなく自由に組んでも 問題の無い言語になります。  しかしよくよく考えてみると、この仕様がOOのクラスに合わないんです。OOP 好きな私がOOPに合わない言語を作るとは、考えてしまいます。早く作って検証 したくてなりません。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1314] Re:コード生成部分について
投稿者:
2009/05/29 22:32:50

>(1)Cのように、配列の領域をスタック上に取る。 ご指摘ありがとうございます。前の書き込みからVMをいろいろ調べていましたが、 まさに(1)の方法を取ろうと思っています。このレス読んだのがちょうど今日なん ですよ。  ちなみに、配列の添え字記述が宣言時決定でnewは無くなる方向しかないかなと 思っています。スタック上に取る以上は動的確保は無理のようで。VMコードも多少 変わってしまいました。 下記がVMコードの現在の案です。 S_OpcodeInfo D_opcode_info[] = { {"dummy", "", 0}, {"push_int_1byte", "b", 8}, {"push_int_2byte", "s", 8}, {"push_int_4byte", "i", 8}, // 実際の値を持つ {"push_double_0", "", 12}, {"push_double_1", "", 12}, {"push_double_8byte", "d", 12}, // 実際の値を持つ {"push_string", "s", 40}, // 文字列の位置NOを持つ0~ {"push_null", "", 8}, /**********/ {"push_stack_int", "s", 8}, // intローカル変数をスタックに {"push_stack_double", "s", 12}, // {"push_stack_string", "s", 40}, // {"pop_stack_int", "s", -8}, // スタックのintをローカル変数に {"pop_stack_double", "s", -12}, // {"pop_stack_string", "s", -40}, // /**********/ {"push_static_int", "s", 8}, // int静的変数をスタックに {"push_static_double", "s", 12}, // {"push_static_string", "s", 40}, // {"pop_static_int", "s", -8}, // スタックのintを静的変数に {"pop_static_double", "s", -12}, // {"pop_static_string", "s", -40}, // /**********/ {"push_sysval_int", "i", 8}, // システムグローバル変数をスタックに {"push_sysval_double", "i", 12}, // {"push_sysval_str", "i", 40}, // {"pop_sysval_int", "i", -8}, // スタックからシステムグローバル変数に {"pop_sysval_double", "i", -12}, // {"pop_sysval_str", "i", -40}, // /**********/ {"push_array_int", "", 16}, // int配列値をスタックに {"push_array_double", "", 20}, // {"push_array_string", "", 16}, // {"pop_array_int", "", -16}, // スタックからint配列に {"pop_array_double", "", -20}, // {"pop_array_string", "", -16}, // /**********/ {"add_int", "", -8}, // 以下は総て算術演算子 {"add_double", "", -12}, {"add_string", "", -40}, {"sub_int", "", -8}, {"sub_double", "", -12}, {"mul_int", "", -8}, {"mul_double", "", -12}, {"div_int", "", -8}, {"div_double", "", -12}, {"mod_int", "", -8}, {"mod_double", "", -12}, {"minus_int", "", 0}, {"minus_double","", 0}, {"increment", "", 0}, {"decrement", "", 0}, // ここまで算術演算子 {"cast_int_to_double", "", 4}, // 以下はキャスト処理 {"cast_double_to_int", "", -4}, {"cast_boolean_to_string" "", 32}, {"cast_int_to_string", "", 32}, {"cast_double_to_string", "", 28}, // ここまでキャスト処理 {"eq_int", "", -8}, // 以下は総て論理演算子 {"eq_double", "", -12}, {"eq_string", "", -40}, {"gt_int", "", -8}, {"gt_double", "", -12}, {"gt_string", "", -40}, {"ge_int", "", -8}, {"ge_double", "", -12}, {"ge_string", "", -40}, {"lt_int", "", -8}, {"lt_double", "", -12}, {"lt_string", "", -40}, {"le_int", "", -8}, {"le_double", "", -12}, {"le_string", "", -40}, {"ne_int", "", -8}, {"ne_double", "", -12}, {"ne_string", "", -40}, {"logical_and", "", -8}, {"logical_or", "", -8}, {"logical_not", "", 0}, // ここまで論理演算子 {"pop", "", -1}, // スタックを1つ減らす {"duplicate", "", 12}, // スタック内容をコピーしてスタックに {"jump", "s", 0}, // 指定ポインターにjump {"jump_if_true", "s", -1}, // スタックがtrueならjump {"jump_if_false","s", -1}, // スタックがfalseならjump /**********/ {"push_function", "sss", 0},// 関数情報をスタックに {"invoke", "", -1}, // 関数コール {"return", "", -1}, // 関数戻り /**********/ {"new_array_int", "b", 16}, // 次元数 基本データ-型の配列生成 {"new_array_double", "b", 20}, // 次元数 基本データ-型の配列生成 {"new_array_object", "b", 16}, // 次元数 基本データ-型の配列生成 {"new_array_literal_int", "s", 16}, // int定数配列を変数に接続 {"new_array_literal_double","s", 20}, // double定数配列を変数に接続 {"new_array_literal_object","s", 16}, // object定数配列を変数に接続 };  (注:ちなみに1とか-1は未定です)  上の構造だとstringがやたらスタックを食っているのは、string自体の大きさ からです。このへんが、stringを使用するのを変えてしまいそうな気分です。 ちなみに、配列は3次元まで、要素の最大は60KByteまでの制限をする予定。汎用の 言語を作るわけではないし、あくまでもローカル変数の制限だけなので、目的と 効率を優先にしています。  また、スタック構造ですが、VC++だとenumが4byte取るのでスタック対応する フラグは消して、下記のようなS_Valueに変えて、タイプとサイズを持つことに しました。で結局の所、関数のローカル変数は総てスタックに持つことでint用と double当のプールはなくしました。前に話したようにVMは出来るだけシンプルに したいので、持つデータ構造は違う形になりそうです。配列の仕様も変えてし まったし。下記の構造体をスタックで使用します //=================================================================== typedef struct { ushort dimno; // 配列の次元数 ushort dimsno[DIMMAX]; // 配列の添え字数 union { int *intDim; // int配列実態 double *doubleDim; // double配列実態 string *stringDim; // string配列実態 }u; } SV_array; //=================================================================== typedef struct { ushort vtype; // データタイプ E_StackDType ushort size; // スタック消費サイズ union { int int_value; // intデータ double double_value; // doubleデータ string *string_value // string参照 SV_array *i_array; // int配列参照 SV_array *d_array; // double配列参照 SV_array *s_array; // string配列参照 }u; } S_Value;  以上が、今日までに想定した仕様です。まだVM自体を作っていないので、まだ 変更があるかもしれません。ちなみに、組み込み関数についてはラフ案で下記の ようなクラスを使用しようと思っています。組み込み関数からのリターンはエラー コードにする予定。パラメータ可変の関数も対応します。それと変数リファレンス 情報を持って一部の関数は総ての変数をリファレンスに操作します。この点は悩み ました。文字列と配列以外は実数渡しなのですが、一部のシステム関数のみリファ レンス操作してしまうんですよ。その一部のために構文を作るべきか特殊仕様とす るかで、たった2つの関数のために構文を変えることは止めにしました。 目的優先に^^; //=================================================================== typedef struct { char *name; // 変数名 ushort gval_x; // グローバル変数横軸数 ushort gval_y; // グローバル変数縦軸数 S_Value *val_ref; // 変数参照データ S_Value val; // 変数コピーデータ } S_Value_info; //=================================================================== class C_NFBase { //-- VMに送る情報 ---------------------- char *m_name; // 関数名 int m_prmno; // 要求するパラメータ数0-10まで20は可変関数 E_ValueType m_type[PRMMAX]; // 要求するパラメータの型 E_ValueType m_rtntype; // 関数戻り値の型 //-- VMから受け取る情報 ---------------------- int m_prninno; // 引き渡されたパラメータ数 S_Value_info m_prm[PRMMAX]; // 引き渡されたパラメータデータ //-- 関数の戻り情報 ---------------------- S_Value m_return; // 関数からの戻り値データ
[この投稿を含むスレッドを表示] [この投稿を削除]
[1313] Re:>(ぱ)こと管理人さん
投稿者:yuya
2009/05/29 20:02:21

>Cではモジュール化しようと思った所しかモジュール化しません。 主語は誰なんでしょうか……。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1312] Re:>(ぱ)こと管理人さん
投稿者:774RR
2009/05/29 16:59:07

そりゃ単にプログラマの技量の問題ぢゃん。 きれいにモヂュール化された C ソースや Fortran ソースを何度も見たことあるし ぜんぜんモヂュール化されていないグチョグチョ Java ソースも見たことあるよ。 モヂュール化を言語の仕様レベルで推し進める機構があるかないか という点ならば御意。 そしてその機構に関係なくグチョグチョソースを書く下手プログラマが どこにでも、いくらでも、いるのが現実。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1311] Re:>(ぱ)こと管理人さん
投稿者:SE
2009/05/29 16:54:50

>本質は抽象化だと仰っているのにSEさんが出してるスタックの例はまったく >抽象化されていないような気がするのですが…。 一応、抽象化されていますが、確かに分かりにくいかもしれません。 FileWriterを例にした方がいいかもしれません。内容的には同じ意図です。 ----------------------------------------------------------- java.lang.Object  |  +--java.io.Writer     |     +--java.io.OutputStreamWriter        |        +--java.io.FileWriter -----------------------------------------------------------
[この投稿を含むスレッドを表示] [この投稿を削除]
[1310] Re:>(ぱ)こと管理人さん
投稿者:SE
2009/05/29 16:49:09

>Cで「単位を合わせて」モジュール化する困難さと、クラスの階層構造を適切に設計する困難さは、 >あまり違いがないように思うんですが、人によるのかな。 Cではモジュール化しようと思った所しかモジュール化しません。 具体的に言うと、せいぜいDBアクセスとか通信部分などでしょう。 Javaの場合は全てのクラスがモジュール化なのです。 現実的に実システムでは、CでJavaと同様の単位でモジュール化するのは不可能です。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1309] Smalltalk原理主義を粉砕せよ! (was Re: オブジェクト指向の…
投稿者:sumim
2009/05/29 09:01:02

>全然完璧に関係ないですが、大昔、fjに高木浩光さんが >「Smalltalk原理主義者を殲滅せよ」なんてことを書いていて(もちろんネタですが)、 >今これを探そうとしてGoogleグループを見てみたのですが… それらしいのを見つけましたがこれですか? http://groups.google.co.jp/group/fj.comp.oops/msg/973f372a89455de2
[この投稿を含むスレッドを表示] [この投稿を削除]
[1308] Re:コード生成部分について
投稿者:(ぱ)こと管理人
2009/05/29 00:51:22

>それと、GCは不要なシステムになります。INT用とdouble用の固定長プール、そして >文字列はstringに任せてしまうのでVMとしてのGCは無くなりました。 intとdoubleが固定長のプールに保持されてGCがないということは、 配列はグローバルなものだけなのでしょうか? ローカルな配列が使えないのはちょっと不便なような。 ローカルな配列を使えるようにする場合、再帰を考えれば (1)Cのように、配列の領域をスタック上に取る。  →現状のDVMには、スタック上でインデックスを指定して要素を参照する   インストラクションがないので、追加が必要。 (2)配列の領域はヒープに取るが、その参照をスタックに持つ。  →最低でも参照カウンタのGCが必要。 ということになりそうな…
[この投稿を含むスレッドを表示] [この投稿を削除]
[1307] オブジェクト指向の利点の話
投稿者:(ぱ)こと管理人
2009/05/29 00:39:49

件名変えました。 >>関連する操作やデータをまとめる、というのは普通にモジュール化であって、 >>私が「疑りぶかい~」で書いたオセロの例の、Cでstaticで隠蔽を行った >>board.cで達成していることでは? >ここが重要です。 >構造化プログラミングの「モジュール化」は基本的にモジュール化した所でしか有効ではありません。 >1つの関数で考えた場合は分かりにくいかと思いますが、関連する複数の関数での場合を考えてください。 いや、だから私が例に出したboard.cにはちゃんと複数の関数があるんですけど。 http://kmaebashi.com/programmer/object/othello.html もうSEさんが何を言いたいのかさっぱりです。 >オブジェクト指向の >利点は「再利用性が高まる事」=「変更がしやすい、変更しても壊れにくい」。 >本質は「抽象化」 >だと言う事です。 「抽象化」なんてのはおよそあらゆるプログラミングパラダイムの目的みたいなもので、 それだけでは何がなんだかさっぱりです。 >774RRさんの言う通り、「対象読者層が異なる」というだけの話のようです。 >つまり「インスタンスが複数あっていい」というあたりを理解していないプログラマ向けの文書で、 >私の指摘は「インスタンスが複数あるのは当たり前」と理解しているプログラマの視点という事です。 私もそう思っていたのですが、ちょっと疑い始めているところです。 >棋譜をセーブデータとして残すために、コンストラクタかセッターにファイル名を渡すと >言うならボードクラスに入れるのはいいと思いますが、 >名人戦の障害発生対応が違うかもしれないので、エラーログクラスを受け渡すと言うのは >おかしいと思います。 まあそのへんは要件次第で、エラーログならstaticでよいという考え方もあるでしょう (Boardが持つのは「おかしい」と言われると、それは何故かと聞きたくなりますが)。 ええと、しかも、「コンストラクタかセッターに『ファイル名を』渡す」んですか? 棋譜をファイルに吐かず、こっちの画面に出したい、とかの場合はどうするんですか? もともとLoggerの話は、SEさんの[1269]における http://kmaebashi.com/bbs/list.php?boardid=kmaebashibbs&from=1269&range=1 >これを次のように変更します。1行で済みます。 とか、 [1273]における http://kmaebashi.com/bbs/list.php?boardid=kmaebashibbs&from=1273&range=1 >遠くの所でnewした特有の処理の入ったクラスを、引数で使い回すのは、 >構造化のスタンプ結合的で、オブジェクト指向的には良くない設計です。 とかの話から出てきたものです。Loggerを引数で引き回そうが、staticで保持しようが、 遠いところでnewされたオブジェクトを、その実際のクラスがわからない状態で 使用するということに変わりはありません。そのとき、うまく使えばポリモルフィズムで 動きが変えられるというのがよく言われるオブジェクト指向の利点です。 その点、SEさんのUpperStackは、使う側がUpperStackであることを意識して使わなければ ならない(リスコフの置換原則を破っている)のでダメだ、と言っているわけです。 CばっかりずっとやってきたプログラマにJavaで設計させると、機能単位でクラス分割は するものの、 (1)何もかもstaticフィールドとメソッドで作ってしまう。 (2)staticメソッドにしない代わりに、毎回オブジェクトをnewして、いくつか  メソッドを呼んだら使い捨てにしてしまう。 このどちらかの設計にしてしまうことがあります。 正直なところ、SEさんはこの(2)のタイプの人に見えてしょうがないんですが。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1306] Re:>(ぱ)こと管理人さん
投稿者:こくぼ
2009/05/28 18:55:50

>つまり私の言いたいのは、 >オブジェクト指向の >利点は「再利用性が高まる事」=「変更がしやすい、変更しても壊れにくい」。 >本質は「抽象化」 >だと言う事です。 >利点は「見通しの良さ」 >本質は「マルチプルインスタンス」 >ではないと思います。 本質は抽象化だと仰っているのにSEさんが出してるスタックの例はまったく 抽象化されていないような気がするのですが…。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1305] Re:オブジェクト指向の概念の発明者は誰ですか?
投稿者:こくぼ
2009/05/28 18:42:42

>まるで3つのオブジェクト指向があるように思えますが、実質的にはオブジェクト指向は2です。 >1はメッセージが焦点になっていますが、本質はオブジェクトで2と同様です。 1の本質はオブジェクトではなくてメッセージだと書いてあるはずですが…。 #Smalltalkの文法やクラスやオブジェクトといった概念もおまけでしかない、とアランケイはのたまっています >もし初心者が見たら混乱するだけだと思います。2の説明だけあればいいと思います。 きちんと分類して書いてあるから少なくとも混乱することはないと思いますけどね。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1304] Re:>(ぱ)こと管理人さん
投稿者:yuya
2009/05/28 16:49:04

クラスの階層構造のおかげで、モジュール化も適切な階層構造で行いやすくなる、ってことでしょうか。 少なくとも私自身は、そんなメリットを実感したこと、一度もないなぁ。 Cで「単位を合わせて」モジュール化する困難さと、クラスの階層構造を適切に設計する困難さは、 あまり違いがないように思うんですが、人によるのかな。 無地のノートより罫線の引いてあるノートのほうが書きやすい、ぐらいの違いはあるかもしれないけど。 Cで適切な階層構造のモジュール化が行えない人が、オブジェクト指向言語でクラス設計したところで、 (しかも実装継承で組んだりしたら)余計ぐちゃぐちゃになっちゃうような気がするんですが。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1303] Re:>(ぱ)こと管理人さん
投稿者:SE
2009/05/28 15:24:23

>関連する操作やデータをまとめる、というのは普通にモジュール化であって、 >私が「疑りぶかい~」で書いたオセロの例の、Cでstaticで隠蔽を行った >board.cで達成していることでは? ここが重要です。 構造化プログラミングの「モジュール化」は基本的にモジュール化した所でしか有効ではありません。 1つの関数で考えた場合は分かりにくいかと思いますが、関連する複数の関数での場合を考えてください。 つまり拡張を見越して単位を合わせてモジュール化しておく必要があると言う事です。 オブジェクト指向の場合はクラス単位でモジュール化されているような物であると言う事です。 つまり末端のクラスから上位のクラスまで、全ての単位でモジュール化されているため、 あらゆる単位で変更が可能だと言う事です。 つまり私の言いたいのは、 オブジェクト指向の 利点は「再利用性が高まる事」=「変更がしやすい、変更しても壊れにくい」。 本質は「抽象化」 だと言う事です。 利点は「見通しの良さ」 本質は「マルチプルインスタンス」 ではないと思います。 >いや、「世間のCプログラマはstaticで実装を隠蔽するような気の効いたことは >していない。だからお前の認識はズレているのだ」ということならそうなのかも >しれませんけど(1ソースファイル1関数、という規約のプロジェクトとかって、 >今でもあるんでしょうか)。 774RRさんの言う通り、「対象読者層が異なる」というだけの話のようです。 つまり「インスタンスが複数あっていい」というあたりを理解していないプログラマ向けの文書で、 私の指摘は「インスタンスが複数あるのは当たり前」と理解しているプログラマの視点という事です。 >うーん、Loggerくらいならstaticでもかまわないとは確かに思いますけれど、 >私ならアプリケーションのインスタンスのフィールドに持ちますね。 >オセロの例なら、Boardクラスで障害発生時とかのログを残すとして、Loggerは >Boardに持たせます。名人戦のBoardだけ障害発生時の対応が違ったりするかも >知れませんし。よって、BoardのコンストラクタかsetLogger()メソッドの >引数でLoggerを渡すことになります。 棋譜をセーブデータとして残すために、コンストラクタかセッターにファイル名を渡すと 言うならボードクラスに入れるのはいいと思いますが、 名人戦の障害発生対応が違うかもしれないので、エラーログクラスを受け渡すと言うのは おかしいと思います。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1302] Re:オブジェクト指向の概念の発明者は誰ですか?
投稿者:SE
2009/05/28 14:39:32

>>>これもひどい内容ですね。 > >とSEさんがおしゃるのか、さっぱりわからないんですけど。 1.メッセージ指向 2.クラス指向 3.手続き抽象化 のまるで3つのオブジェクト指向があるように思えますが、実質的にはオブジェクト指向は2です。 1はメッセージが焦点になっていますが、本質はオブジェクトで2と同様です。 3は少なくとも私は知りませんし、一般的ではないと思います。HP筆者の独自解釈では? もし初心者が見たら混乱するだけだと思います。2の説明だけあればいいと思います。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1301] 管理者により削除されました
2009/05/29 00:42:36

テスト投稿らしいものだったので、削除しました。 テスト投稿はテスト用掲示板にお願いします。
[この投稿を含むスレッドを表示]
[1298] Re:オブジェクト指向の概念の発明者は誰ですか?
投稿者:(ぱ)こと管理人
2009/05/27 02:24:13

>#自分も特にSmalltalkに思い入れがあるわけではありません^^; ありゃ、そうですか。了解です。 全然完璧に関係ないですが、大昔、fjに高木浩光さんが 「Smalltalk原理主義者を殲滅せよ」なんてことを書いていて(もちろんネタですが)、 今これを探そうとしてGoogleグループを見てみたのですが…Googleグループって、 NewsGroupの検索ができるのだと思っていましたが、いつのまに2ch検索エンジンに?
[この投稿を含むスレッドを表示] [この投稿を削除]
[1297] Re:オブジェクト指向の概念の発明者は誰ですか?
投稿者:こくぼ
2009/05/26 08:58:11

>こくぼさんには「Smalltalkが不憫で仕方ありません」と言われそうですが、 >職業プログラマである我々が、現状、仕事でSmalltalkを使うことはまあまずないわけで、 >JavaやC++やC#を使うのに「メッセージ」がどうこう言われたら誤解を招く、というのは >わかります。 Smalltalkが不憫っていうのは、SEさんが紹介している説明を見ると まるでSmalltalkが悪いせいでオブジェクト指向が理解されてない みたいな書き方をされてるせいです。 #自分も特にSmalltalkに思い入れがあるわけではありません^^; >とSEさんがおしゃるのか、さっぱりわからないんですけど。 ですよね。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1296] Re:コード生成部分について
投稿者:
2009/05/25 19:44:20

見ていただきありがとうございます。 >要点は、文字列以外はコンスタントプールを使わずに、直接定数を >バイトコードの中に埋め込むようにした、ということですよね。 はい >効率を考えてバイトコードではなくワードコード)中に埋め込んでいるそうです。 管理面とスピードを考えて、コードに埋め込みましたが問題なさそうでよかった。 >あと、もしシステムグローバル変数がDVM_Valueを保持しているのなら、 コード生成が一応落ち着いたのでVM部分を見ました。計算スタックはDVM_Value なんですね。VMを複数スレッド起動させるので、VMは極力最小にしようと思って います。その為に、省ける分はがさがさ省いていっています。コンスタントプール も、まさに、文字列を詰め込んだ配列とそのアクセスポインタテーブルのみです。 それと、GCは不要なシステムになります。INT用とdouble用の固定長プール、そして 文字列はstringに任せてしまうのでVMとしてのGCは無くなりました。この部分は VM管理システムで一括管理する予定。コード生成もそうでしたが、必要機能のた めに実行部分は最小に、その結果管理部分が大きくなっています。  新しく組み込んでいる部分をあいまいに表現して申し訳ありません。なにぶん 出来てみないとなんとも言えなくて、絵に描いたもちを説明するのも気が引けて。 その部分はある程度完成するまでお待ちください。構想したものを組み込んで、 自身が確認しないとなんとも^^;  追記、目的ターゲットでは、細かい文字列操作は多量にあると思いますが、長い 文字列は無いと思われますので、stringの管理でも問題は無いと思っています。 しかし、実際やってみての部分は有ります。その時は専用の文字列だけを管理する 処理を組み込む予定です。その場合も文字列だけなのでGCは不要で出来ます。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1295] Re:コード生成部分について
投稿者:(ぱ)こと管理人
2009/05/25 01:16:56

> {"push_int_4byte", "i", 1}, // 直接持に変更 > {"push_double_8byte", "d", 1}, // 直接持に変更 要点は、文字列以外はコンスタントプールを使わずに、直接定数を バイトコードの中に埋め込むようにした、ということですよね。 Diksamは、JVMを真似したのと、将来的にバイトコードをファイルに 吐き出すことを考えてコンスタントプールを持ちましたが、 たとえばYARVでは、効率を考えて定数をバイトコード(ていうかこれも 効率を考えてバイトコードではなくワードコード)中に埋め込んでいるそうです。 http://www.atdot.net/yarv/yarvarch.ja.html > {"push_sysval_int", "s", 1}, // システムグローバル変数アクセス用 > {"push_sysval_double", "s", 1}, // > {"push_sysval_str", "s", 1}, // > {"pop_sysval_int", "s", -1}, // > {"pop_sysval_double", "s", -1}, // > {"pop_sysval_str", "s", -1}, // あと、もしシステムグローバル変数がDVM_Valueを保持しているのなら、 実はpush_sysval_intやpush_sysval_doubleのようにインストラクションを 型ごとに分ける必要はありません。 Diksamの場合、スタックはDVM_Valueの配列のくせにこのインストラクションを 分けているのは、将来的にint型ローカル変数は4バイトしか消費しないようにする、 といった改善を入れるときのためです。
[この投稿を含むスレッドを表示] [この投稿を削除]