|
Javaによるプログラミング試論
|
目次 前提ーJavaによるプログラミング試論 第1回 現実界のMain、イデア界のクラス 第2回 主語述語概念の導入 第3回 ブラックボックス化(知りたくないのよ) 第4回 ブラックボックスの必然性 第5回 パラドックスへの応用 第6回 思考フレームワークについて 閑話余談:神様って? 第7回 多態性って?インターフェースって? 第8回 内部クラスについて 第9回 パラドックスのさらなる深みへ 第10回 さらなる思考の深みへ 第11回 内部クラスの補足説明 第12回 Java腕試しの問題 第13回 腕試し正解その1 第14回 腕試し正解その2 第15回 レトリックの補足 第16回 再帰について 第17回 永劫回帰か? 第18回 派閥対策? 第19回 結論らしきもの
プログラム言語における文法やその構造性が どこまで普通言語や思考の枠組みを導入しているか を検証してみたいと考えました。 初回は雑談風に取り留めのない話を少し…最後まで 雑談で終わったりしてね? さて、具体的にコンピュータ言語は何を使用するか? ホントはC#なんか言語仕様もすっきりして かつホットで良いんだが、残念ながら 私のWindows98では動かん。 C++もボーランドのコンパイラーBCCにクセ があって使いづらい。 と言っても皆さんが有料のVC++を持ってる訳がない。 そこでまあJavaならどこでも動くし、かつ 今最もポピュラーな言語なんでこれを 素材にして説明することにします。 (何しろタダです。現在はSDK V.1.4.1.02が 最新だと思うのでこれを拾ってインストールして 下さい。PATHを通すのがチョックら厄介ですが その辺りはマニュアルを見てね。) はっきり申し上げますが、これはJavaの初心者コース ではありません。あくまでJavaのCodeからその「思想性」を 探ろうという「画期的な試み」です。 そもそもこのWorkShopをアップした最大の理由は日本人ってのは 国民性からしてオブジェクト指向言語に向かないのでは ないか? この疑問からです。 日本人は哲学的思考、論理学に弱い。 物事を構造的に関連付けするのが苦手で、全て同じレベルで並列共存 させる。そこでこのHPを読んでみようなんて「哲学的思考と論理性に 秀でたと想像される皆さん方」にプログラム言語の仕組みを理解して 頂いたら、これは鬼に金棒ではないか!・・・とまあ「愚考」した訳ですよ。 どこが愚考か胸に手を置いて考えて頂ければすぐお分かり ですよね。敢えて指摘は致しません。 では次回までにJavaのSDKをインストールしておいてね。 それとVectorでCPAD(Java)というフリーソフトの エディターもあります。これはなかなか使い勝手が 良いのでお薦め。最近Eclipseというフリーの IDE(統合開発環境)が出ています。CかC++で 書かれているようなので他のJava製のIDEより軽くて、 これも評判が良いようです。まるでSmalltalkの開発環境と同じ じゃないか?なんて噂も聞きましたが。 Java関連のHPに多い言語仕様や文法の解説だけは避けたいと 考えています。 これを始めると単なるプログラム言語紹介になる可能性が高い。 また言語実装もリフレクションやイントロスペクション また多重継承の優先性とか一般の方々にはさっぱり訳の分からん話は プログラマー的には面白いが、とても皆さんに受けるとは思えない。 従ってプログラム言語の活用を中心に話しを進めるつもりでおります。 それもメンバ変数はint Stringのみ、メンバ関数はprintlnだけに 絞りこみ、主に情報隠蔽、継承、集約、多態性の考え方や 内部クラス、およびデザインパターンの構造なんかをサラッと 流してみたいと考えております。 ポイントは何故わざわざプログラムを複雑にし、 かつその実行効率まで落としてオブジェクト指向を しなくてはならないのか? そんなにメリットがあるのか? 人間の思考パターンに近いと称されているが それはホントか? というところを重点的に分かり易く説明できれば、 まあ面白いかなぁと。 自然言語は人間だけに理解されれば用は足ります。 しかしプログラムは人間にもマシーンにも理解され ないと意味がない。その辺りのバランスなんかも 結構微妙なものがあります。 プログラムは命令文です。 人間がマシーンに命令しています。 自然言語も人が人に対する命令を暗黙に含んで おります。少なくとも「読め」と 皆さんがプログラムに親しんで頂くことにより 普段は気付かない視点や構造性のようなものを 感じて頂ければと思います。 変なことを言いますが、自然言語も人の性格に影響するように プログラマーが使う言語もかなりその使用者の思考パターンに影響を 与えているように思うんです。 アセンブリー言語なんてやってた人は半ばマシーンに化していた? Cobolを組む人は単純な性格になる。C言語は頭が固い人が多い。 Rubyはもの珍しがり屋ではあるが、プロは少ない。 言語の複雑度ではC++が最も高いのではないでしょうか? (Adaとか特殊なものを除き) C言語からの追加仕様でC++は発展して来ただけに一貫性に欠ける面はある。 だからC++プログラマーは分裂気質が多い。 C++と比較するとJava,C#,Perl,Pythonなんて言語能力から見ると返って 退歩している。ガーベージコレクションは確かに 便利だが、本来メモリー管理はプログラマーの責任範囲ではないで しょうか? あそうそうPascalがありましたよね。Delphiです。 Kylixです。ちょっと隠蔽性に難はあるが、早いし 好きな言語の一つではあります。Smalltalkもオブジェクト指向 言語の草分け的存在ですから好きです。 関数型言語については別途Functional Programmingで 詳しくご説明します。 しかし今はなんと言ってもJava全盛ですよね? それとVisualBasic これも最近.Netでオブジェクト 指向言語に変化しましたよね。でもあれは失敗だと思うなぁ。 素人プログラマーに対する敷居が高くなっちゃった。 VBからC#に乗り換える人が増えるんじゃないでしょうか。 C#は言語仕様的にも現時点ではまあまあでしょう。 だが、C#がJavaを追い越すのはかなりシンドイと思います。 それだけJavaで思考し指がJavaで動く人が多いから。 例えばCobolとJavaでは時間単価が25〜30%違うらしい。 そう言う意味では、Javaでオブジェクト指向の思想性を 追求するのはー>実益も兼ねることになるかな? 少なくとも岩谷宏さんの「Javaの哲学」なんて本よりは思想性の 高い内容にはしたいと・・・って、あの本自体、Javaの言語仕様の解説ばかりで 哲学なんてどこをひっくりかえしてもありませんでしたが。 目次へ
第1回 現実界のMain、イデア界のクラス
皆さん JavaSDKはインストール出来たでしょうか? JCpadはここで手に入ります。 600KB程度です。皆さんの「貧弱なメモリー」環境でも充分作動します。 (くれぐれも頭脳と間違えないでね!) では早速定番のプログラムです。 //Welcome.Javaです。 class Welcome { public static void main(String[] args) { System.out.println("Javaへようこそ!"); //画面にOPされます。 } } これをそのままコピーしてJCpadに貼りつけ、 名前をWelcomeにして保存します。 そして上のバーにある実行ボタンを押すと、 真っ黒な不気味な画面にぼやっと 「Javaへようこそ!」が浮かびます。 いかにもコンピューター言語らしいですねぇ。 不気味ですねぇ。恐いですねぇ。 場末のオタクの雰囲気が出てますねぇ。 この真っ黒なDOS画面って普通Windowsのユーザーは 見ませんよね?アプリケーションエラーかなんかの時に 亡霊のようにチラって? レトロでしょう?なんかいかにもコンピューターの内部を 覗きこんでいる実感がするじゃないですかぁ。 ああ自分の作成したプログラムを実行しているんだぁ。 コンピューターの心臓部に直接触れているんだぁ。 public static void main(String[] args) これがかの恐るべきJavaの「まじない」の言葉です。 公共の、静的な、空虚の、中心である行為(メソッド)は、 まず言語配列の引数を貴方に要求する。と訳します。 このまじないの後の{ }の中に「現実の世界」が 展開されるのです。 従って{ }の中が空っぽであれば当然 動きません。これは当たり前です。 またホストコンピューター育ちのCobolオジさんでこの{ }中に 「しか」プログラムを書かないと、頑なにオブジェクト指向に 抵抗する三葉虫?のような方がよく居られます。 が…一理あるのです。この{ }中に 延々とIF文や関数を並べて普通のプログラムを 書いてもJavaは作動します。 反って早いのです!じゃそれでイイジャン!では ダメなのであります。永遠にオブジェクト指向をものに 出来ないからです。 そこで次のプログラムです。 //Welcome2.Javaです。 class Msg { String msg = "へようこそ!"; //言語名を引数にしてメソッドを作成。 void welcomeMsg (String gengo){ System.out.println(gengo + msg); } } class Welcome2 { public static void main(String[] args) { //クラスのインスタンス生成 Msg mg = new Msg (); //Javaを引数にメソッドを呼び出す。 mg.welcomeMsg("Java"); } } これをまたCpadに貼りつけWelcome2で保存し 実行ボタンを押して下さい。すると… 前回のプログラムと全く同じです。 何が違うのか? プログラムが違うのです! つまり貴方は、もうオブジェクト指向の中に どっぷりと漬かってしまったのです。もう逃げられません。 覚悟を決めて最後までこの講座に付き合う以外に 脱出する方法が無くなったのです。(と…暗示にかけて?) class Msg { }の中は概念の世界です。 プラトンで言えばイデアの世界です。美しいですねぇ。 つまりクラス「だけ」では絶対プログラムは動きません。 その概念をMsg mg = new Msg ();というプログラム によってnewする。つまり「公共の、性的な、空虚の、 中心である行為(メソッド)は、まず言語配列の引数を 貴方に求める。」現実世界:main programにおいて インスタンス(現実の映し身)を生成するのです。 その生成したインスタンスは「mg」と名づけられました。 ところでMsg ()はコンストラクターと言ってクラスの インスタンスを作るときに呼び出される 行為(メソッド)です。クラスの中で初期化定義にも 使用します。 そして、Javaを引数にメソッドを呼び出す 。 mg.welcomeMsg("Java");これで画面に 文字が浮かぶのです。 インスタンスをオブジェクトと称したり クラス+インスタンスのグループでオブジェクトと 称したりするので、誤解を避ける意味で用語は クラスとインスタンスに統一します。 スリラーっぽくやってみましたが、 ここまで皆さんお分かりでしょうか? 目次へ
いよいよ過去の助走を生かして大きく言語論に踏みこむことにします。 プログラマー系の方にはやや専門違いに感じるかも知れませんが、 一つの考え方として聞いて下さい。 では基本から、 A.そもそもプログラム言語は言語なのか? B.それとも設計図か仕様書にあたるものか? の疑問があります。ソフトウエアを作成するという 知的な生産活動を考慮すると、A.に相当する。 一方単に物質的には記憶媒体に01のコードを刻む だけであると考えればその設計図なり仕様書と とっても良いでしょう。 ただその発展段階が機械語を直接書いてというか、 テープに穴を開けていた時代から(エニアックの スイッチについては省略しますが、笑い)アセンブリー言語、 C言語からオブジェクト指向言語へと、所謂マシーンに 近い低級言語から人間の言語や思考パターンに近い 高級言語へと進化しております。 またインタープリター、コンパイラーの進歩により コードを書けば後は自動的に機械語に翻訳して くれるので、仕様書、設計図としても製作過程が ほとんど意識されないようになりました。 書けば、ほぼ目的達成という意味で、プログラム言語を 自然言語同様に言語論的に分析することもあながち 筋違いな話しではないと考えます。 そこでその言語目的ですが、これは「コンピューターに ある作業をさせること」に尽きます。 従ってプログラム言語は全て命令文です。 例えば: >System.out.println("Javaへようこそ!"); これは「Javaへようこそ!」と言う文字列を 画面表示せよ。ということです。 また前回の: > //クラスのインスタンス生成 > Msg mg = new Msg (); > //Javaを引数にメソッドを呼び出す。 > mg.welcomeMsg("Java"); これもMsgクラスのインスタンスを生成し、welcomeMsg() メソッドを実行せよ。との意味です。 従ってこれまで条件分岐文などはあれ、全て命令文系の述語で あった訳です。 それがpublic static void main(String[] args) この まじない文の後ろの{ }の中に延々と書かれておったのです。 つまりこれまで主語はなかったのです。(コンピューターに 決まってましたからね。笑い) クライアントプログラムは現実の世界と前回申し上げましたが、 それは全て述語の世界であります。命令行為の世界だったんです。 ところがそれに主語という概念を組み込んだのが オブジェクト指向言語なのです。 class Msg { String msg = "へようこそ!"; //フォーラム名を引数にしてメソッドを作成。 void welcomeMsg (String gengo){ System.out.println(gengo + msg); } } クラスの世界はイデア、概念の世界と前回は 申し上げましたが、言語論的には主語なんです。 Msgクラスは、"へようこそ"という言語変数を持つ。 Msgクラスは、void welcomeMsg (String gengo)のメソッド を持っているのです。 日本語はご承知のとおり、述語指向の言語です。 例えば: 開けっぴろげで、象徴的な、虚しい、中心的行為です。 これは public static void main( )の訳ですね。 皆さん覚えていますか? これを関数分析すると: ((((開けっぴろげ)で、象徴的)な、虚し)い、中心の行為)です。 かの著名な言語学者である時枝先生の修辞学で解釈するとこうなりますね。 つまり最後の「です。」は全体に懸かっておるのです。 そして「い」「な」「で」がそれ以前の全てに懸かって います。 これから、お分かりのように日本人にとっては従来の 命令文主義、述語主義が感覚にあっていたんです。 それを架空の主語概念、イデア概念が入ってきたので COBOL育ちのオツムの弱い?というか言語論的素養のない オジさん達は戸惑っておるのです。 日本風の簡素な美を失うではないかぁ!と 敢えてプログラムを複雑にし、かつ動作効率まで犠牲に して、なぜ主語概念を導入したのか? それは次回に。 目次へ
では前回の疑問から: >敢えてプログラムを複雑にし、かつ動作効率まで犠牲に >して、なぜ主語概念を導入したのか? 通常の我々が作るようなプログラムは多くて(A)500〜1000ステップ (400字詰め原稿用紙25〜50枚程度)であります。それが企業の 基幹システムともなると(B)100万〜200万ステップ(5万〜10万枚 の原稿用紙!)が普通であります。 (A)程度であれば全てのプログラムはある程度頭に入りますが、 (B)になるととても不可能です。個々のプログラマーは自分が 全体の内の何をやっているのか?さえ良く分からないでしょう。 そこでクライアントプログラムに全て命令文を打ちこむ 要知主義が見なおされる次第です。これは言語の発展段階と 同じですね。最初は述語しかない。「危ない。」「逃げろ。」 「美味い。」とかね。 世界の認識が精緻になれば、それが分節化され 内容をブラックボックスにいれる主語が生成されて 行く次第です。 つまり不要知主義です。用が足りれば良い。頭脳負荷を軽減し、 敢えてバカの壁を築くことです。 要知主義は相手の全てを知りたい。博学多識を誇ります。 一方不要知主義の人は相手のプライバシー等は知りたくもない。 インターフェースつまり共通項の会話に満足する訳です。 ではここで前々回のプログラムを見てください。 //Welcome2.Javaです。 class Msg { String msg = "へようこそ!"; //言語名を引数にしてメソッドを作成。 void welcomeMsg (String gengo){ System.out.println(gengo + msg); } } class Welcome2 { public static void main(String[] args) { //クラスのインスタンス生成 Msg mg = new Msg (); //Javaを引数にメソッドを呼び出す。 mg.welcomeMsg("Java"); } } つまり相手クラスの welcomeMsg()メソッドさえ知って いれば良いのです。中味がどう実装されようがどんな 変数を使用しようが、クライアントの方は一切関知しません。 もっとこれを極端にしてみましょう。 //Welcome2A.Javaです。 class Msg { String msg = "へようこそ!"; //言語名を引数にしてコンストラクター作成。 Msg (String gengo){ System.out.println(gengo + msg); } } class Welcome2A { public static void main(String[] args) { //言語名を引数にしてクラスのインスタンス生成。 Msg mg = new Msg ("COBOL"); } } これはクライアント側main()でインスタンスを作成している だけです。クラス側のコンストラクターに全ての作業を 渡しているのです。 これを実行して見てください。黒い画面に・・・ COBOLへようこそ! と浮かびます。 これを見て懐かしさに泣く人もいます。 悔恨の念に苛まれる人もいるでしょう。 いつかCさえも・・・なんてもらい泣きする人も? 冗談はさておき、この実体が知の専門化、細分化を呼んでいるのです。 敢えて言えば知の後退をも引き起こしているのです。 何故か? 主語が肥大化し、述語が貧弱化するからです。 主語が肥大化するとは、ブラックボックスが増え、 特殊化するのです。述語が貧弱とは説明性、責任性の 欠如に繋がるのです。 さてこれがオブジェクト指向の求めた結果でしょうか? それは次回に。 目次へ
皆さん こんにちは 前回の: >主語が肥大化し、述語が貧弱化するからです。 >主語が肥大化するとは、ブラックボックスが増え、 >特殊化するのです。述語が貧弱とは説明性、責任性の >欠如に繋がるのです。 > >さてこれがオブジェクト指向の求めた結果でしょうか? アラン・ケイの理想でありましょうか? この疑問を技術論的に分析してみます。 当初プログラム言語は存在せず、スイッチの上げ下げであった。 これは純粋にマシーンに対する「客体的技術」であります。 そしてマシーンにさえ理解されれば、目的は足りた訳です。 主に計算機としての使用に限られていたからです。 ところが徐々にそれがアセンブリー言語から高級言語に 発展するとともに、人間の言語的要素を取り入れて 他の人間にも理解できることが重要な要素となってきました。 技術論的に申しますと「主体的技術」である制度や言語を 扱う様相を呈してきた訳です。つまりコンパイラーやリンカ デバッガーなど一連の機械語への翻訳機能が高性能になるに 伴ない言語的拘束条件化してきたものと思われます。 勿論プログラム記号そのものに意味や価値はありません。 またマシーンがそれを理解することは無いのは当然です。 作動すれば良いのですから。言葉の意味や価値を理解しない。 反射的に作動するだけってのはマシーンに限りません。 脊髄反射的人間も時々? 逆説的に言えば、人間の言葉によるコミュニケーションはバグを 含みつつ誤作動しており、決して相手の意図を正確に把握した ものではない。その点マシーンの方がシニフィエの多様性にも 関わらず厳密なシニフィアン行為を実行しておる訳です。 そこで最初の疑問に戻るのですが、オブジェクト指向言語を開発 したアラン・ケイはコンピューターを人間による思考の道具 にしたいと言う理想を持っていたのです。 技術論的には「思考の枠組み作り」に寄与させたいと。 人間の普遍的な思考形態をプログラム言語の文法に組み込むことに より、知的進歩を促そうと。(LISPやProlog同様に開発当初Smalltalkが AI言語の一つに数えられておりました。) ところが前回申しましたように、それには無駄なメモリーや動作を コンピューターに強いる為、1980年当時のパソコンでは遅くて 使い物にならなかった。その後、技術進歩が進展しそのボトルネック が解消されて現在はこの手法が全盛となったのです。 しかし、そのオブジェクト指向技術は主としてGUI(グラフィカル ユーザーインターフェース)例えばウィンドウやボタン、タスクバー などに使われたため、部品化されたプログラムとしてプログラム自体の 再利用性やユーザーの利便性は確かに高まりました。 でも前回述べたようにブラックボックス化されたことから反って プログラマにおける知の退廃を招いたのです。 ところで、優秀なプログラマは何故ビル・ゲイツが嫌いか? それはWINDOWSの簡便なGUIによってプログラマのこれまでの業務寄りの 仕事をユーザーに取られてしまい、かつWINDOWSの中味が公開され 無い為に単なるAPI使いになり下がり、知的フラストレーションが 鬱積したのです。 そのエネルギーがLINUXに集中されて、あのような商業ソフトも 脱帽するようなOSが生まれたのです。日本政府のシステム開発は 無償でソースを公開しているLINUX中心に行うことが決定しております。 ちょっと話が脇道に逸れてましたので、ここで プログラムサンプルを見て下さい。 //IO.Javaです。 //道具箱です。 import java.io.*; class C { static void out(String msg){ System.out.println(msg); } static String in(){ BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); String str = ""; try{ str = br.readLine(); }catch(IOException e){ out("Err"); } return str; } } //ここまで道具箱です。 class Msg { String msg = "へようこそ!"; //言語名を引数にしてコンストラクターを作成。 Msg (String gengo){ C.out(gengo + msg); C.out(""); //System.out.printlnがC.outで代用可能。 } } class IO { public static void main(String[] args) { C.out("言語名を入力して下さい。"); //入力文字をにgengoに保持します。 String gengo = C.in(); //クラスのインスタンスをgengoを引数に生成する。 C.out(""); Msg mg = new Msg (gengo); C.out("これは「"+gengo+"」の宣伝です。"); C.out(""); } } 実行して見て下さい。そしてVBでも、LISPでも、PROLOGでも、 「ひまわり」でも好きな文字を入力して下さい。 上記の道具箱の中味は、画面に文字をOPする部分と 画面から文字をIPする部分を短縮して 簡単なC.outとC.inと言うメソッドに変換しております。 Cは勿論コンピューターです。 特にC.inはシーインと発音するようにね。 このようにプログラムを変更することにより 格段にプログラムが簡単になりました。 つまり中味は説明しませんが: BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); String str = ""; try{ str = br.readLine(); }catch(IOException e){ out("Err"); } return str; これがC.inに圧縮されたのです。そしてどのクラスでも 使用できるようになったのです。 どうでしょう?言語や法制度的な進展と類似している と思いませんか?というより「情報の圧縮と構造化」そのものを目指して プログラム言語は進歩を続けておるのです。 さて思考のフレームワークとは何なのか? プログラム言語自体が思考の拘束条件であれば 人間に対する影響は? それを次回に検討します。 目次へ
皆さん こんにちは >さて思考のフレームワークとは何なのか? >プログラム言語自体が思考の拘束条件であれば >人間に対する影響は? 前回の質問を見られて、オブジェクト指向に馴染みの ある方々は、これでまた 1.クラス内部のカプセル化ー情報の隠蔽 2.クラス構造の継承、集約、構成 3.クラスのポリモリフィズムー多態性 うんぬんの話しを蒸し返されるのでは?とウンザリ…とか、 こんな基本的なことは本屋に山と積んであるJava本や オブジェクト指向開発関係の本に書いてあります。 今やベストセラーである「オブジェクト脳の作り方」にも 詳細な説明がありますので、そちらを読んで下さい。 では一体何を説明しようとしているのか? 全てのクラスはObjectという単一基底オブジェクトの 構造を継承している。オブジェクト指向の根本思想は Object指向という一神教的世界をイメージしている。 なんて陳腐なことをいまさら述べるはずもない。 クラスの階層構造と関係性こそ、間主観性概念の 関数構造に該当する。とか?…あまりネタをばらし過ぎると 後が苦しいので: 早速具体的な問題にアプローチしてみます。 皆さんは古代ギリシャのエピメニデスのパラドックスは ご存知でしょうか? これは、クレタ人のエピメニデスが、「クレタ人は嘘つきだ」と 言ったというものです。 もしエピメニデスが言った「クレタ人は嘘つきだ」 ということが真であると仮定すると、エピメニデスはクレタ人なので、 彼が言っている「クレタ人は嘘つきだ」は嘘(偽)となり、 クレタ人は嘘つきでないことになる。 また彼の言った「クレタ人は嘘つきだ」というのが偽であると仮定すると クレタ人は嘘つきでないことになり、エピメニデスはクレタ人なので嘘をついて いないことになり彼の言った「クレタ人は嘘つきだ」というのが真となり、 これも仮定に矛盾する。従って、エピメニデスの言った「クレタ人は嘘つきだ」 というのは真でも偽でもないというものです。(かなり有名なパラドックス なので皆さんご存知ですよね?) この証明のためJavaによる下記プログラムを作成し 実用的な思考のフレームワークを構築してみます。 //Paradox.Javaです。 //ウソつきクレタ人のクラスを作成しております。 class KuretaJinUso{ String kuni = "クレタ"; String seikaku = "ウソつき"; String kami = "大阪の神さん:"; //クラスのコンストラクターです。 //インスタンス生成時に自動的に呼ばれます。 KuretaJinUso(String name){ System.out.println(kuni+"の"+seikaku+name+"やで。"); System.out.println("パルメニデスの命題"); System.out.println("「クレタ人はウソつきだ」、が真ならば"); System.out.println("どうなるか神さんに聞いたろ"); System.out.println(""); } //ウソつきメソッドです。 void usotsuki(String hatugen){ System.out.println(kuni+"人は"+hatugen+" や。"); System.out.println(""); if(hatugen ==seikaku){ System.out.println(kami+seikaku+"がホンマのこと"); System.out.println("言うて矛盾やんか!"); System.out.println(""); } else{ System.out.println(kami+"言うとること命題とチャウで、アホか!") System.out.println(""); } } } //ウソつかんクレタ人のクラスを作成しております。 //内容はほぼウソつきクレタ人と同じです。 class KuretaJinUsotukan{ String kuni = "クレタ"; String seikaku = "ウソつかん"; String kami = "大阪の神さん:"; KuretaJinUsotukan(String name){ System.out.println(kuni+"の"+seikaku+name+"やで。"); System.out.println("パルメニデスの命題"); System.out.println("「クレタ人はウソつきだ」、が偽ならば"); System.out.println("どうなるか神さんに聞いたろ"); System.out.println(""); } void usotsukan(String hatugen){ System.out.println(kuni+"人は"+hatugen+" や。"); System.out.println(""); if(hatugen =="ウソつき"){ System.out.println(kami+seikaku+"のがウソ"); System.out.println("言うて矛盾やんか!"); System.out.println(""); } else{ System.out.println(kami+"命題とチャウで!"); System.out.println(kami+"ホンマにアンタはボケとんなぁ"); System.out.println(""); } } } public class Paradox{ public static void main (String args[]){ //最初はウソつきクレタ人のインスタンスです。 //maroとして生成しました。 KuretaJinUso maro = new KuretaJinUso ("マロデス"); //いくらでも好きな名前でインスタンスを生成して下さい。 maro.usotsuki("ウソつき"); //usotsukiメソッドを発言を引数にして呼ぶだけです。 maro.usotsuki("ウソつかん"); //次はウソつかんクレタ人のインスタンスです。 //majimaroとして生成しました。 KuretaJinUsotukan majimaro = new KuretaJinUsotukan("マジマロヤーナ"); majimaro.usotsukan("ウソつき"); majimaro.usotsukan("ウソつかん"); //このクライアントプログラムスッキリしてるでしょ? //もっと良い方法あれば教えてね。 } } これは非常に出来が悪い例です。阪神タイガーズのセリーグ優勝に かけて河内弁を使用したことが一層その品位を貶めたか? クラス構造もダブっており見られたものではない。 Javaの練習と思って前回の道具箱のメソッドを使用して もっと簡潔なプログラムに書き換えて見てください。 目次へ
皆さん こんにちは さてソシュールの言語学講義にある通り、書く行為、表現する行為、そして 思考する行為は密接不可分である。人は書きながら概念に意味や価値を 付与しているのであります。また読む行為、理解する行為、そして 思考する行為も密接不可分であり、人は読みながら、その概念に 意味や価値を自ら付与しているのであります。 書く者と読む者との間には時空を隔てた物理的断絶と個人差による 人間的断絶が不可避であります。どれだけ作者に迫ろうとしても そこには絶対的な壁が立ちはだかるのであります。 プログラム言語は当初人間の意図を機械に理解させ、操作する ことにより発展しました。徐々に技術進歩のお陰で、より人間に 近い言語になり、オブジェクト指向言語から人間の思考フレーム ワークまで取りこんだのであります。 論理順列、反復、条件分岐から汎化、特化、分類、継承、集約 配分、構成、多態性というフレームワークをプログラム言語に 持たせることにより現実世界の動き、事象を抽象的にプログラムの 世界に反映することが出来るようになったのです。 現在のプログラム開発環境では、書いたら即実行できます。 言いなおせば文章が他人の理解作業を経ずに即、直接物質化 されることではないでしょうか? 言語の間接性を廃し即物質的な力に変換が可能になったのです。 ある意味、「言葉は力なり。」の実現形態の一つであります。 昨今流行の開発形態であるエクストリーム手法においては ペア―プログラミングが推奨されております。 二人で同じ画面を見ながら開発することです。 人と人のコミュニケーションの間にマシーンを媒介させることに より言語をコミュニケーションを即実体化させることが出来るのです。 前回示したエピメニデスのパラドックスを人種や共同体に対する 自らの内面性との葛藤に置換えてプログラムしてみました。 //Paradox2.Javaです。 //道具箱です。入力 C.inは使用しません。 class C { static void out(String msg){ System.out.println(msg); } } //ここまで道具箱です。 //クレタ人のクラスを作成しております。 class KuretaJin{ String jinshu = "クレタ人"; String seikaku = "「ウソつき」"; String taishuu = "クレタの人々:"; void wameku(boolean tf){ if(tf == true){ C.out(taishuu+ "お前も"+jinshu +"ではないか?"); C.out("この"+seikaku+"のお陰で地中海の"); C.out("貿易において繁栄したのを忘れたか!"); C.out("奴を殺せ!"); C.out(""); } else{ C.out(taishuu+"良く言った。"); C.out("それでこそ真の"+jinshu+"じゃ。"); C.out(""); } } } //エピメニデスクラスをクレタ人クラスより継承して作成。 class Epi extends KuretaJin{ String name = "エピメニデス:"; String ryousin = "誠実の掟"; //エピメニデスのコンストラクターに全てを語らせます。 Epi(){ C.out(name+"もう我慢出来ない。真実を語ろう。"); C.out(""); //エピメニデスに3回葛藤させます。 for(int i=0;i<3;i++){ kokuhaku(true); wameku(true); kattou(true); kokuhaku(false); wameku(false); kattou(false); //エピメニデスの「告白」も外部クラスの「喚く」も //内部クラスを使った「葛藤」も全てエピメニデスの //クラス内で発生しています。 } } void kokuhaku(boolean tf){ if (tf == true){ C.out(name+jinshu + "は" + seikaku + "だ。"); //内部クラスのインスタンスを生成。 InnerKami ikami= new InnerKami(true); C.out(""); } else{ C.out(name+jinshu+ "は決して"+seikaku+"じゃない。"); C.out(""); } } void kattou(boolean tf){ if (tf == true ){ C.out(name+ "人々がが怒っている!どうしよう。"); C.out("殺されては元も子もない。人々に従おう。"); C.out(""); } else{ //内部クラスのインスタンス生成。 InnerKami ikami = new InnerKami(false); C.out(name+ryousin+"に背いてしまった!どうしよう。"); C.out("やはりここは"+ryousin+"に従おう。"); C.out(""); } } //エピメニデスの内部クラスとしてInnerKamiクラスを作成。 class InnerKami{ String kami = "神様:"; InnerKami(boolean tf){ if(tf == true){ C.out(kami+"良き哉!"+ryousin+"に従った。"); } else{ C.out(kami+"愚か者め!"+ryousin+"に反して何とする。"); } } } } public class Paradox2{ public static void main (String args[]){ //エピメニデスのクラスインスタンスを生成するだけ。 Epi epi = new Epi(); //述語性の曖昧さを取り除き、主語間の関連性で //全てを表わして見ました。 } } 実行してみて下さい。エピメニデスが3回葛藤します。 問題はその画面表示ではなく、このプログラムの構造性です。 クレタ人クラスからエピメニデスが導出され、そのエピメニデスに 内部クラスとして神の概念が組み込まれています。 そして外部であるクレタの人々の抗議や同意がエピメニデスのクラスの 中で内部クラスである神概念と同一レベルで動作しております。 エピメニデス自身もクレタ人として抗議していることが お分かりでしょうか? そして共同体から引き継いだ性格である「嘘吐き」と内部良心である 「誠実の掟」が神の媒介により葛藤している状況が明白に示されて おります。エピメニデスの引き裂かれたアポリアこそ、真に パラドックス足り得るのではないでしょうか? プログラムは時空を超えて意味をつなぐもの、物質の動作に変換され 断絶無く思想を伝え得るもの、と言う可能性を秘めております。 プログラムをするとは自己を生むことであります。 自己の思想を直接物質に刻むことです。 モーゼに与えられた十戒の石版のように。 そしてそれは変質することなく保存され増殖することが 可能です。 永遠に動き続けるのです。 これは生の超越であり、死の克服でもありえる。 されば思想を求めん者は、 即ち、プログラムを理解せざるべからず。 それを習得せざるべからず。 目次へ
あまり固い話しばかりでは肩が凝るので 神の実体を知る「kami自身に聞け!」プログラムを 作成してみました。どうぞお験し下さい。 //YabonaShitumon.javaです。 class Yabo{ String kami; //kamiの宣言だけです。何も代入してません。 //中味は誰も分かりません。 String yabo = "読者の皆さん:"; //yaboに意味はありません。(^^;) Yabo(){ System.out.println(yabo+"神よ!あなたは誰ですか?"); System.out.println("私は"+kami+"である。"); //初期化してない変数なんか呼んで大丈夫か? } } public class YabonaShitumon{ public static void main (String args[]){ //Yaboのインスタンスを生成。 Yabo yabo = new Yabo(); } } お分かりでしょうか? ますます肩が凝ったって? でも、結構深い意味を語っておるので御座います。 つまりNilとは何か?Null(無)ではなく、Nil(未定義)であります。 本来プログラムはメモリーに電気的な信号を埋め込む作業であります。 Nilとは未定義であります。01の2進数以前と言うか、2進数以後と言うか、 2進数そのものの基盤と言うか…。 不可称、不可量、不可思議であります。 つまりNilは有無を超越してNilであります。 Javaは全てのオブジェクトが根源的唯一のオブジェクトから継承されて おります。根源的唯一オブジェクトの似姿であります。 しかしSmalltalkは唯一根源オブジェクトの上に根本メソッド群=法があります。 またさらにその法を統一する統合オブジェクトが存在します。 さらにその上にその唯一のオブジェクトを統御する大法輪=メソッド群が 存在するのです。な、なんと4段積みであります。 (この仕組みがあの精密なIntrospection やReflectionを支えておる のであります。) さすが、ご本家Smalltalkは奥が深い! さらにその大法輪の上は? Nilの「無限の大海」だそうです。 目次へ
皆さん こんにちは クラス情報のカプセル化やスーパークラスからの継承に ついては例を示しましたが、ポリモルフィズムー多態性と インターフェースの使用について説明しておりませんでした。 ここで簡単に補足しておきます。 継承はスーパークラスの属性とメソッドを全てサブクラスが 暗黙の内に引き継ぎます。つまりスーパーを変えれば その影響が全てのサブに行き渡る次第です。 多態性とはスーパーのインスタンスにサブのインスタンスを 代入する事によりサブのメソッドを呼び出すことです。 もちろんサブのメソッドはスーパーと違う内容にオーバーライド されております。従ってスーパーにとってはサブの内容を 知ることなくサブの状況に応じた変化を同一メソッドにより 享受できるのです。 話すとややこしいですが、実例を見たらな〜んだと思われます。 スーパークラスを利用した場合とインタフェースを使った場合を それぞれ同じコンテクストでプログラムを書いてみました。 スーパークラスの例です。 //Poly.Javaです。 //道具箱です。 class C { static void out(String msg){ System.out.println(msg); } } //ここまで道具箱です。 class Msg { void callmsg (){ C.out(""); C.out("コンピュータ言語紹介(^^;)"); C.out(""); } } class Msgsub1 extends Msg { //Msgを継承してクラス作成。 String msg = "Welcome to "; String gengo = "JAVA! "; //親と同じメソッド名でオーバーライドします。 void callmsg (){ C.out(msg +gengo ); C.out(""); } } class Msgsub2 extends Msg { //同じくMsgを継承してクラス作成。 String msg = "へようこそ!"; String frm ="JAVA" ; //親と同じメソッド名でオーバーライドします。 void callmsg (){ C.out(gengo + msg); C.out(""); } } class Poly { public static void main(String[] args) { Msg ms [] = new Msg [3]; //親のクラス配列を作成しています。 ms[0] = new Msg(); ms[1] = new Msgsub1(); ms[2] = new Msgsub2(); //親の配列に親と子のインスタンスを代入。 for(int i=0;i<3;i++){ ms[i].callmsg(); //親のメソッドを呼び出せば・・・・ //アラ不思議!それぞれ親、子のメソッドが //呼び出されているではないか? } } } インターフェースの利用例です: インターフェースは自らインスタンスを 作ることは出来ません。 //Poly2.Javaです。 //道具箱です。 class C { static void out(String msg){ System.out.println(msg); } } //ここまで道具箱です。 interface Msg { // インターフェースを宣言します。 void callmsg(); } class Msgsub1 implements Msg { //Msgを実装してクラス作成。 String msg = "Welcome to "; String gengo = "JAVA! "; public void callmsg(){ //必ずpublicで実装する。 C.out(""); C.out(msg + gengo ); C.out(""); } } class Msgsub2 implements Msg { //同じくMsgを実装してクラス作成。 String msg = "へようこそ!"; String gengo ="JAVA" ; public void callmsg(){ //必ずpublicで実装する。 C.out(gengo + msg); C.out(""); } } class Poly2 { public static void main(String[] args) { Msg ms [] = new Msg [2]; //インタフェース配列を作成しています。 ms[0] = new Msgsub1(); ms[1] = new Msgsub2(); //インターフェース配列に子のインスタンスを代入。 for(int i=0;i<2;i++){ ms[i].callmsg(); //インターフェースのメソッドを呼び出せば //それぞれ実装された子のメソッドが //呼び出されているではないか? } } } どちらもcallmsg()だけでそれぞれ違う動作をさせて いるのがお分かりでしょう? 今回ご紹介したのはホンノ基礎的なオブジェクト指向言語の 構造と仕組みです。しかしこれまでの手続き型の言語とは 人間の思考フレームワークの取り込み方法にかなり差があること を感じております。自然言語もそれを話す人間に影響を与えます。 明治の文豪や政治家はほとんど西欧言語が読めて話せます。 それが文明開化に大きく寄与したことはご承知のとおりです。 プログラム言語も偶に休みに使用するぐらいであれば、あまり 影響はありませんが、プロとして常にそれを使って仕事を していればこの思考フレームワークの有無はかなり大きな差に なります。 ちょこちょこと「道具箱です」って作成したクラスは 言語構造そのものを圧縮して新たな言葉そのものを 生みだしているのがお分かりでしょうか? シニフィアンは同一でもシニフィエは無限に創造できます。 簡易なスクリプト言語の仕組みはこのような積み重ねです。 但しスクリプト言語からC言語やC++言語を生み出せません。 Pythonってスクリプト言語ご存知ですよね? JPythonというバージョンがあり全てJavaで書かれ Java環境で作動します。しかし逆は出来ません。 その意味で、出来るだけ粒度が細かく、かつOO型の思考 フレームワークも取りこんだ言語が望ましいのです。 今のところC++、C#、Javaの順番かなと私は考えております。 現在オブジェクト指向の次のアスペクト指向が話題に なっております。AspectJとかね。 つまりこれまでのクラス継承という縦糸にアスペクトという横糸を 通してタペストリーのようにプログラムを作ったらどうだ? という概念です。 開発環境IDEのクラス・ブラウザ―が今はツリー状ですが アスペクト指向が入るとエクセルのセル形式か?(笑い) このように言語概念を次々と革新して行く動きは、自然言語より 遥かに急速かつドラスティックです。 そしてそれが前回申しましたように物質に直結し、物質を動かす ので明証性が高い。 勿論人間の経験は無限大のメモリーを要求しますので システムには代行できませんが、論理や思考のフレームワークと しては充分実用レベルに達していると考えております。 目次へ
皆さん こんにちは 間主観性構造理論によれば、外部世界を人間は直接認識できない。 また自らの主体自身も直接は認識できない。 これは観念論であるとか、幻想論とかとは無関係な話です。 あくまでも常識的な認識論に基づいております。 人の個別世界は絶対的に独立して存在する。 存在が保有する関数構造や属性などを常に更新しながら、 開かれた外部と内部の交流を分節化し認識している。 従って真実は全て比喩で語られます。 直接そのもの自体を語れないために比喩でもってそれを 指し示すのです。ポインターのようなものです。 そこで上記間主観性構造理論をプログラム化して みました。例としてエピメニデスのパラドックスを 使用しております。 //Paradox3.Javaです。 //エピメニデス・クラスに全てのクラスを包含しました。 //彼の世界は一つになったのです。外部世界が内部世界に //変換されているのにご注目下さい。 class Epi { String name = "エピメニデス:"; String ryousin = "誠実の掟"; String jinshu = "クレタ人"; String seikaku = "「ウソつき」"; String taishuu = "クレタの人々:"; String kami = "神様:"; //全ての属性を集結させます。内部クラスから参照可能。 //エピメニデスのコンストラクターに全てを語らせます。 Epi(){ C.out(name+"もう我慢出来ない。真実を語ろう。"); C.out(""); //エピメニデスに3回葛藤させます。 for(int i=0;i<3;i++){ kokuhaku(true); kattou(true); kokuhaku(false); kattou(false); //エピメニデスの内部クラスであるクレタ人や //神様の声を使用した「告白」も「葛藤」も //全てエピメニデスのクラス内で発生しています。 } } void kokuhaku(boolean tf){ if (tf == true){ C.out(name+jinshu + "は" + seikaku + "だ。"); //内部クラスのインスタンスを生成。 InnerKami ikami = new InnerKami(true); C.out(""); KuretaJin kure = new KuretaJin(true); C.out(""); } else{ C.out(name+jinshu+ "は決して"+seikaku+"じゃない。"); C.out(""); KuretaJin kure = new KuretaJin(false); C.out(""); } } void kattou(boolean tf){ if (tf == true ){ C.out(name+ "人々が怒っている!危険だぁ。"); C.out("殺されては元も子もない。人々に従おう。 "); C.out(""); } else{ //内部クラスのインスタンス生成。 InnerKami ikami = new InnerKami(false); C.out(name+ryousin+"に背いてしまった!心が痛む。"); C.out("やはりここは"+ryousin+"に従おう。"); C.out(""); } } //エピメニデスの内部クラスとしてKuretaJinクラスを作成。 class KuretaJin{ KuretaJin(boolean tf){ if(tf == true){ C.out(taishuu+ "お前も"+jinshu +"ではないか?"); C.out("この"+seikaku+"のお陰で地中海の"); C.out("貿易において繁栄したのを忘れたか!"); C.out("奴を殺せ!"); C.out(""); } else{ C.out(taishuu+"良く言った。"); C.out("それでこそ真の"+jinshu+"じゃ。"); C.out(""); } } } //エピメニデスの内部クラスとしてInnerKamiクラスを作成。 class InnerKami{ InnerKami(boolean tf){ if(tf == true){ C.out(kami+"良き哉!"+ryousin+"に従った。"); } else{ C.out(kami+"愚か者め!"+ryousin+"に反して何とする。"); } } } } //巨大なクラスが中空に存在しているのがお分かりでしょうか? public class Paradox3{ public static void main (String args[]){ //現実はエピメニデスのインスタンスが生きるだけ。 //他には何もありません。認識が内部世界と外部世界 //の交流を表わしているだけです。 Epi epi = new Epi(); } } //道具箱です。思想内容とは無関係。 class C { static void out(String msg){ System.out.println(msg); } } //ここまで道具箱です。 実行される画面表示より、プログラム構造と仕様に注目下さい。 これまでプログラム言語はあまりにもその実用面に捉われて その人対人のコミュニケーション能力が無視されてきました。 言語学や記号論的な観点からも、自然言語と比較してコンピュータ 言語の実行・実証性及びシニフィアンの厳密さなどその有効性は 疑い得ないところです。 現実世界の構造化、抽象化、関連性の明確化などについて、 特にその解釈の誤りを生む余地が少ないという面で優れたもの があります。 言語厳密性で言えば、プログラム言語>仏語、独語>英語>日本語 ではないでしょうか? 私はプログラマーではありませんので、これまでJavaで実際のプログラム を書いたことはありません。(Hello World程度ならありますが) 最初のパラドックスのプログラムなんてひどいもんです。 プロから見れば現在のものもです。 言語論に興味があるので言語仕様はよく理解しているつもりですが 実際書くとなると結構間違うものです。そもそもバグメッセージが 分からない! しかし構想を練るところは、なかなか面白いものがあります。 それが次々と新たなアイデアや展開を生むところも。 プロパティーやメソッドの組み合せで人間の視角の影に なっている部分に気付く可能性もあります。 是非一度お験し下さい。 目次へ
皆さん こんにちは 前回のエピメニデス・クラスにクレタの人々を包含したことに より: 1.クレタの人々の叫びがエピメニデスの内部に取りこまれた。 外部世界の出来事が認識となって心象世界に反映した ことを表わしております。 2.外部世界は、(物自体や他者自体は)直接認識できない、 と言うカントの純粋理性批判の説が現前しております。 3.クレタの人々の叫びがギリシャ悲劇のコロス(合唱隊) 形式となり、エピメニデスの心象背景を形成しております。 4.エピメニデスの身体に流れる「クレタの血」が 叫んでいることを暗喩しております。 5.クレタ人達の叫びがエピメニデス内の「クレタの血」と 化したことにより、内面の神性や良心と同一平面で 争っていることが示されております。エピメニデス自身の 自我が引き裂かれ、葛藤している状況が明白になりました。 プログラム化することで、その構造性と関係性をより明確に 表現できることがお分かりと思います。 さて、これまでエピメニデスとクレタの人々しか登場して おりません。そこで同じクレタ人である二人の人物を プログラムに組み込んでみます。 お待ちかね、「マロヤーナ」と「アホマロデス」どうぞ! //Paradox4.Javaです。 //Epiクラスは変更ありません。 class Epi { String name = "エピメニデス:"; String ryousin = "誠実の掟"; String jinshu = "クレタ人"; String seikaku = "「ウソつき」"; String taishuu = "クレタの人々:"; String kami = "神様:"; //全ての属性を集結させます。内部クラスから参照可能。 //エピメニデスに全てを語らせます。 public void kataru(){ C.out(name+"もう我慢出来ない。"+ryousin+"で語ろう。"); C.out(""); //エピメニデスに1回葛藤させます。 for(int i=0;i<1;i++){ kokuhaku(true); kattou(true); kokuhaku(false); kattou(false); //エピメニデスの内部クラスであるクレタ人や //神様の声を使用した「告白」も「葛藤」も //全てエピメニデスのクラス内で発生しています。 } } void kokuhaku(boolean tf){ if (tf == true){ C.out(name+jinshu + "は" + seikaku + "だ。"); //内部クラスのインスタンスを生成。 InnerKami ikami = new InnerKami(true); C.out(""); KuretaJin kure = new KuretaJin(true); C.out(""); } else{ C.out(name+jinshu+ "は決して"+seikaku+"じゃない。"); C.out(""); KuretaJin kure = new KuretaJin(false); C.out(""); } } void kattou(boolean tf){ if (tf == true ){ C.out(name+ "人々が怒っている!危険だぁ。"); C.out("殺されては元も子もない。人々に従おう。"); C.out(""); } else{ //内部クラスのインスタンス生成。 InnerKami ikami = new InnerKami(false); C.out(name+ryousin+"に背いてしまった!心が痛む。"); C.out("やはりここは"+ryousin+"に従おう。"); C.out(""); } } //エピメニデスの内部クラスとしてKuretaJinクラスを作成。 class KuretaJin{ KuretaJin(boolean tf){ if(tf == true){ C.out(taishuu+ "お前も"+jinshu +"ではないか?"); C.out("この"+seikaku+"のお陰で地中海の"); C.out("貿易において繁栄したのを忘れたか!"); C.out("奴を殺せ!"); C.out(""); } else{ C.out(taishuu+"良く言った。"); C.out("それでこそ真の"+jinshu+"じゃ。"); C.out(""); } } } //エピメニデスの内部クラスとしてInnerKamiクラスを作成。 class InnerKami{ InnerKami(boolean tf){ if(tf == true){ C.out(kami+"良き哉!"+ryousin+"に従った。"); } else{ C.out(kami+"愚か者め!"+ryousin+"に反して何とする。"); } } } } //巨大なエピメニデスクラスが中空に存在しているのが //お分かりでしょうか? //現実の個人であるMaroyanaとAhomaroクラスを作成します。 class Maroyana extends Epi{ //マロヤーナをエピメニデス・クラスから継承。 String name = "マロヤーナ:"; {super.name = this.name;} //初期化による属性の変更です。 } class Ahomaro extends Epi{ //アホマロデスをエピメニデス・クラスから継承。 String name = "アホマロデス:"; String gizen = "偽善の心"; String akuma = "悪魔:"; //これらの属性について特に意味はありません。(^^;) { super.name = this.name; super.ryousin = this.gizen; super.kami = this.akuma; } //初期化による属性の変更です。 } public class Paradox4{ public static void main (String args[]){ //以前にご紹介したポリモリフィズムを使用してます。 //各クラスのインスタンスを親の配列に代入して //kataru()メソッドで一括呼び出しております。 Epi epi[] = new Epi[3]; epi[0] = new Epi(); epi[1] = new Maroyana (); epi[2] = new Ahomaro (); for(int i=0;i<3;i++){ epi[i].kataru(); } } } //道具箱です。内容とは無関係。 class C { static void out(String msg){ System.out.println(msg); } } //ここまでは道具箱です。 ここで注目頂きたいのは: 1.MaroyanaとAhomaroとも一切メソッドをオーバーライドして おりません。 2.その属性のみを変更し、superで親の属性に初期化代入 しております。 3.それにポリモリフィズムを適用しておることです。 この種のポリモリフィズムは決してJava本に掲載されて おりません。このホームページだけで公開した必殺技です。 目次へ
前回のプログラムで興味深いのはアホマロデスのクラスです。 >class Ahomaro extends Epi{ > //アホマロデスをエピメニデス・クラスから継承。 > String name = "アホマロデス:"; > String gizen = "偽善の心"; > String akuma = "悪魔:"; > //これらの属性について特に意味はありません。(^^;) > { > super.name = this.name; > super.ryousin = this.gizen; > super.kami = this.akuma; > } > //初期化による属性の変更です。 > } 偽善の心が良心に置き換わり、悪魔が神の位置に置き換わって おります。ところが行為そのものは誠実の掟と神とを属性に持つ エピメニデスやマロヤーナと何の変わりもありません。 これはどうしたことでしょうか? キリスト教の黄金律「汝の欲するところを、汝の隣人に施せ。」 は皆さんご存知と思います。 これは「汝の欲せざるところを、汝の隣人に施すなかれ。」と 解釈できます。 しかしながら、カントの判断力批判において、これは仮言命法で ある。つまり「もし〜ならば、〜せよ。」と同じだと言って 定言命法ではないと否定しております。 その理由は「俺も欲しないから、他人にも施さない。」が 担保できないからです。 つまり今回のパラドックスで言えば「他人にいくらウソをつかれて も俺はかまわないから、俺は他人にウソをつく。」を、この黄金律では 否定できません。 従ってカントはあくまで定言命法「ウソはつかない。」と言う 定言判断によるもの以外は認めておりません。 「たとえ〜でも、敢えて〜せよ。」であります。 このパラドックスのコンテクストから言えばクレタ人の大衆から 民族の恥を暴露する裏切り者として殺されても、「真実を 述べよ。」という厳格性を持ちます。 カントの「自らと隣人の人格・人間性こそ目的であり それを決して手段としてはならない。」という第2普遍命題に あたる訳ですね。 そこで話を偽善と誠実に戻しますが、アホマロデスが同じ仲間である クレタ人の恥を暴露することにより、自らの高潔さを装う為に 「クレタ人はウソつきだ。」と叫んだ。 エピメニデスは自らの所属集団特有の醜悪な虚偽性に我慢ならず 自らも含め「クレタ人はウソつきだ。」と叫んだ。 当然クレタの民衆は怒り両者に抗議する。 アホマロデスは卑劣ですから、すぐ態度を改めるが、偽善の心は 捨てきれない。 エピメニデスもカントの普遍命題を死守するほどの覚悟なく、 態度を改めるが、誠実の心は捨てきれず自責の念に悩む。 その行為の拠って立つ理由は天地の差がありながら、行為は 同じである。 エピメニデスに対してカントのように 「たとえ死んでも」とは言えないのじゃなかろうか? クレタ人の中にも同じように感じながら、自分自身が陥る集団からの 悲惨な疎外が予測されるのために真実を発言出来ない人 が多いのではないだろうか?孤独の恐怖に耐えられないのが普通です。 その引け目と恥辱がより強い反発となって真実を告発する者に 向かうのではないでしょうか?一種の根深い嫉妬と化して。 権力や富や名誉についても人は他人を嫉妬するが、それは 同列競争における嫉妬です。しかし集団自体の虚偽性を暴く行為は 競争とは逆方向の嫉妬を生みます。なぜならそれがより真実に近い からです。集団が基盤とする虚偽性は集団自身を支えるものでも あるからです。裏切りに対する憎しみ+嫉妬心ですから強烈ですよね。 そこでさらにこのパラドックスを究明するために、 マロヤーナやアホマロデスという現実の他者も エピメニデスの世界にとりこんでプログラム化して みました。 //Paradox5.Javaです。 //エピメニデス世界クラスにマロヤーナもアホマロデスも //包含しました。ついに世界は一つになったのです。 class EpiWorld { String name = "エピメニデス:"; String ryousin = "誠実の掟"; String jinshu = "クレタ人"; String seikaku = "「ウソつき」"; String taishuu = "クレタの人々:"; String kami = "神:"; void setName(String s){ this.name = s; } void setRyousin(String s) {this.ryousin = s;} void setKami(String s){this.kami = s;} //全ての属性を集結させます。内部クラスから参照可能。 //作業は全てエピメニデスのコンストラクターに集結。 EpiWorld (){ kataru (); Maroyana yana = new Maroyana(); Ahomaro aho = new Ahomaro(); } //エピメニデスに語らせます。 public void kataru(){ C.out(name+"もう我慢出来ない。"+ryousin+"で語ろう。"); C.out(""); //エピメニデスに1回葛藤させます。 for(int i=0;i<1;i++){ kokuhaku(true); kattou(true); kokuhaku(false); kattou(false); //エピメニデスの内部クラスであるクレタ人や //神様の声を使用した「告白」も「葛藤」も //全てエピメニデスのクラス内で発生しています。 } } void kokuhaku(boolean tf){ if (tf == true){ C.out(name+jinshu + "は" + seikaku + "だ。"); //内部クラスのインスタンスを生成。 InnerKami ikami = new InnerKami(true); KuretaJin kure = new KuretaJin(true); } else{ C.out(name+jinshu+ "は決して"+seikaku+"じゃない。"); C.out(""); KuretaJin kure = new KuretaJin(false); } } void kattou(boolean tf){ if (tf == true ){ C.out(name+ "人々が怒っている!危険だぁ。"); C.out("殺されては元も子もない。人々に従おう。"); C.out(""); } else{ //内部クラスのインスタンス生成。 InnerKami ikami = new InnerKami(false); C.out(name+ryousin+"に背いてしまった!心が痛む。"); C.out("やはりここは"+ryousin+"に従おう。"); C.out(""); } } //エピメニデスの内部クラスとしてKuretaJinクラスを作成。 class KuretaJin{ KuretaJin(boolean tf){ if(tf == true){ C.out(taishuu+ "お前も"+jinshu +"ではないか?"); C.out("この"+seikaku+"のお陰で地中海の"); C.out("貿易において繁栄したのを忘れたか!"); C.out("奴を殺せ!"); C.out(""); } else{ C.out(taishuu+"良く言った。"); C.out("それでこそ真の"+jinshu+"じゃ。"); C.out(""); } } } //エピメニデスの内部クラスとしてInnerKamiクラスを作成。 class InnerKami{ InnerKami(boolean tf){ if(tf == true){ C.out(kami+"良き哉!"+ryousin+"に従った。"); C.out(""); } else{ C.out(kami+"愚か者め!"+ryousin+"に反して何とする。"); } } } //現実の個人であるMaroyanaとAhomaroクラスをエピメニデスの //内部クラスとして作成します。 class Maroyana { //コンストラクターで属性変更。 Maroyana(){ setName("マロヤーナ:"); setRyousin("女の意地"); setKami("女神:"); kataru(); } } class Ahomaro { //コンストラクターで属性変更。 Ahomaro(){ setName ( "アホマロデス:"); setRyousin( "偽善の心"); setKami( "悪魔:"); kataru(); } } } //巨大なエピメニデス・ワールドが誕生しました。 public class Paradox5{ public static void main (String args[]){ //main はエピワールドのインスタンスを生成するのみ! EpiWorld epi = new EpiWorld(); } } //道具箱です。内容とは無関係。 class C { static void out(String msg){ System.out.println(msg); try{ Thread.sleep(1500); }catch(InterruptedException e){} //一秒半毎にメッセージが出るように変更。 } } //ここまでは道具箱です。 エピメニデスの世界が急速に膨張しております。 メッセージもゆっくり出力されるように 変更しました。 徐々に徐々に異様な世界が眼前に展開されます。 しかしmainは、クライアントは、述語的世界は、 たったの一行であります。 この戦慄すべき非対称性を味わって下さい。 環境も他者も全てを取り込んで成立している巨大なエピメニデスの 自我構造であります。そして現実は生成の一行だけ。 ゲーデルの不確定性原理もこの非対称から生まれております。 体系の内部から体系そのものを証明できません。 現実には自己も客体も直接認識出来ません。クラス構造 を通して分節化することにより辛うじてゲシュタルト的に認知 しているのがお分かりでしょうか?そしてクラス構造自体は 自己も世界も他者も全て含まれておるのであります。 モノローグ(独白)的な自己は存在せず、バフチンの提唱する 多声性の世界がコード構造によって明らかになっているのが お分かりでしょうか? 人間存在は本来多様で引き裂かれた葛藤を含んでおります。 辛うじて綱渡りのように自己の同一性を保っておるのでは ないでしょうか? 目次へ
皆さん こんにちは これまでの説明の中でJavaの内部クラス機能を多用して おります。全部のクラスをEpiWorldクラスの中に集結し、 プログラムを一元化したりしております。 本日は内部クラスの機能、特性についてご説明します。 実は一般のプログラマーは普通はあまり使わない機能なんです。 せいぜいイベントリスナーといってマウスをクリックすると どうする、こうするを登録するのに使用する程度です。 何故他の皆さんは使わないのか? はっきり言って使いづらいからです。 つまりクラス情報を完全密封化するため、 外から見えない、触れ得ないのです。 使うのに手間がかかり、かつプログラム自体がネストするため 読みづらく、作動効率も落ちるのです。内部クラスに 触れる為には内部クラスのすぐ外側のクラスが内部クラスの インスタンスを生成しない限り、永遠に闇の中に沈んでいる のです。不可知性、不可侵性の奥に潜んでいるのです。 ところがそのクラス自体の明知性たるや、全ての外部クラスの 属性やメソッドを直接自らのクラス内にあるがごとく 支配できるのです。そして何重に覆われていようが 外部のクラスにも普通にアクセスできるのです。 ここで分かり易いサンプルを示しましょう。 //InnerClass.javaです。 /*クラスAの中にクラスBがあり、クラスBの中に クラスCがある三重にクラスがネストした形に なっています。 */ class A{ A(){B b = new B ();} public void aa(){F.out("A:中からC君呼んだ?");} public void aaa(){C cc = new C(); //クラスCをクラスBを飛ばして直接呼ぼうとしてます、が F.out("A:CはBに隠れて直接見えない。");} class B{ B(){C c = new C ();} public void bb(){F.out("B:中からC君呼んだ?");} class C{ C(){F.out("Cが起動して呼んでます。"); aa(); bb(); D d = new D(); d.dd(); F.out("以上Cが呼びました。"); } //なんとCは内部他クラスのaa(),bb()は直接! //外部他クラスのdd()も明示的に呼べます。 } } } class D { public void dd(){F.out("D:外からC君呼んだ?");} } class E { public void eee(){C c = new C(); //クラスCを呼ぼうとしてます。が F.out("E:CなんかAに隠れて見えないよぉ!");} } public class InnerClass{ public static void main (String args[]){ //AとBのコンストラクターでそれぞれのインスタンスを //作り初めてCを呼び出せる。 A a = new A(); a.aaa(); //Aが中から直接呼んでも? E e = new E(); e.eee(); //Eが外から呼んでも? C c = new C(); //全能のクライアントであるmainが呼びます、が F.out("mainからでさえCは見えない!"); } } //クラスCを使ったため道具箱がFになっています。 class F { static void out(String msg){ System.out.println(msg); } } //ここまで道具箱です。 どうでしょう?クライアントであるmainからも見えない。 この不可知性、不可侵性の闇の深さ、それに反してその 明知性、全能性の高さ。 InnerClassは只者ではないと思いませんか? 知恵と能力には限りなく開かれ、その実体と構造は深く 秘められております。それは何を暗喩しているのでしょうか? 目次へ
)皆さん こんにちは あ、さて。これまで私が一方的に説明しまくって おりました関係上、「折角の腕を披露出来ない。」という フラストレーションが溜まった方々が居られるのではないかと 考えました。 そこで今回は皆さんに問題を示すことにより、その解答を募集 する方法に切り替えます。 では問題です。 現実の政界における生々しいパラドクシカルな状況?を プログラムしてみました。(プログラム構造はエピメニデスの パラドックスを流用します。) //Paradox6.Javaです。 class EpiWorld { String name = "小泉:"; String yobina = "総裁"; String ryousin = "政治家の良心"; String jinshu = "自民党員"; String seikaku = "嘘つき"; String taishuu = "政界の圧力:"; String tou = "自民党"; String kami = "神様:"; void setName(String s){ this.name = s; } void setYobina(String s){ this.yobina = s; } void setRyousin(String s) {this.ryousin = s;} void setKami(String s){this.kami = s;} //全ての属性を集結させます。内部クラスから参照可能。 //作業は全て総裁のコンストラクターに集結。 EpiWorld (){ kataru (); Maroyana yana = new Maroyana(); Ahomaro aho = new Ahomaro(); } //総裁に語らせます。 public void kataru(){ C.out(""); C.out(name+"もう我慢出来ない!"+ryousin+"に基づいて発言しよう。"); C.out(""); //総裁に1回葛藤させます。 for(int i=0;i<1;i++){ kokuhaku(true); kattou(true); kokuhaku(false); kattou(false); //総裁の内部クラスである党員達や //神様の声を使用した「告白」も「葛藤」も //全て総裁のクラス内で発生しています。 } } void kokuhaku(boolean tf){ if (tf == true){ C.out(name+jinshu + "は" + seikaku + "だ。"); //内部クラスのインスタンスを生成。 InnerKami ikami = new InnerKami(true); KuretaJin kure = new KuretaJin(true); } else{ C.out(name+jinshu+ "は決して"+seikaku+"じゃない。"); C.out(""); KuretaJin kure = new KuretaJin(false); } } void kattou(boolean tf){ if (tf == true ){ C.out(name+tou+ "が怒っている!危険だぁ。"); C.out("除名されては元も子もない。"+tou+"に従おう。"); C.out(""); } else{ //内部クラスのインスタンス生成。 InnerKami ikami = new InnerKami(false); C.out(name+ryousin+"に背いてしまった!心が痛む。"); C.out("私は本当の"+seikaku+"になってしまった。"); C.out(""); } } //総裁の内部クラスとしてKuretaJin(党員)クラスを作成。 class KuretaJin{ KuretaJin(boolean tf){ if(tf == true){ C.out(taishuu+yobina+ "よ、お前も"+jinshu +"ではないか?"); C.out("この"+seikaku+"のお陰で"+tou+"の"); C.out("政界で辛うじて生き残っているのを忘れたか!"); C.out(yobina+"を強制除名せよ!"); C.out(""); } else{ C.out(taishuu+"良く言った。"); C.out(yobina+"よ、それでこそ大人の"+jinshu+"じゃ。"); C.out(""); } } } //総裁の内部クラスとしてInnerKamiクラスを作成。 class InnerKami{ InnerKami(boolean tf){ if(tf == true){ C.out(kami+"良き哉!"+yobina+"は"+ryousin+"に従った。"); C.out(""); } else{ C.out(kami+"愚か者!"+yobina+"は"+ryousin+"に反して何とする。"); } } } //現実の個人であるMaroyanaとAhomaroクラスを総裁の //内部クラスとして作成します。 class Maroyana { //コンストラクターで属性変更。 Maroyana(){ setName("田中真紀子:"); setYobina("真紀子"); setRyousin("お騒がせの心"); setKami("おばさんの女神:"); kataru(); boyaki(); } public void boyaki(){ C.out(name+"どうすれば良いのかしらん?"); C.out(""); } } class Ahomaro { //コンストラクターで属性変更。 Ahomaro(){ setName ( "鈴木宗男:"); setYobina("ムネオ"); setRyousin( "ヤケッパチ暴露心"); setKami( "脂ぎった神さん:"); kataru(); boyaki(); } public void boyaki(){ C.out(name+"世の中甘くないねぇ。"); C.out("なあ辻元議員!"); C.out(""); } } } //巨大な自民党総裁・ワールドが誕生しました。 public class Paradox6{ public static void main (String args[]){ //main はエピワールドのインスタンスを生成するのみ! EpiWorld sys = new EpiWorld(); } } class C { static void out(String msg){ System.out.println(msg); try{ Thread.sleep(1500); }catch(InterruptedException e){} //一秒半毎にメッセージが出るように変更。 } } では問題です。 上記のプログラムによって、画面に表示された文章をテクストファイルに 落とすためにはどうプログラムを修正すれば良いのでしょうか? mainのプログラムと同じディレクトリーにtest.txtが 作成してあると想定して下さい。 DOS CMDで>test.txtは無し。(笑い) 参考プログラムです。ヒント? String str = ""; try{ PrintWriter output = new PrintWriter(new BufferedWriter (new FileWriter("test.txt",true))); //追加モードにしておきました。 output.println(str); output.close(); }catch(IOException e){} } システム寄りのPrintWriterについては予め例示して おきます。これは思想には無関係ですから。 ここで、皆さんに質問は、それぞれの構造の中で都度呼ばれている 文章をその順番通りどうやってテキストデータに記憶させるか? これを問うて居る次第です。 当たり前の話しではありますが、人間の記憶のメカニズムを 反映しております。 奮ってご応募お待ちしております。 (なお出来ればクライアントにゴチョゴチョ書きこまず スッキリとクラスの中で解決して下さい。 mainはEpiWorldを生成するだけです。 目次へ
皆さん こんにちは どうでしょう?皆さんはクラスCの道具箱に眼を 付けたでしょうか?以前にも説明致しましたが、 実はこれがアスペクト指向の一端を形成しておるのです。 クラスやmainで使用するメソッドを簡単にする圧縮機能と 同時に各クラスを横断して機能するアスペクトにもなって いるのです。 では通常のArrayListを使用する例をご覧ください。 問題と同じ部分は省略します。変更部分のみです。 //ParaArray.Javaです。 //ArrayListの例です。 import java.io.*; import java.util.*; //ioとutil機能を使う為のimportです。 EpiWorld (){ kataru (); Maroyana yana = new Maroyana(); Ahomaro aho = new Ahomaro(); C.fin("test.txt",true); } //test.txt に追加モードでファイル出力します。 public class ParaArray{ public static void main (String args[]){ //main はエピワールドのインスタンスを生成するのみ! EpiWorld sys = new EpiWorld(); } } //道具箱に新機能を追加します。 class C { static String str = ""; static ArrayList ary = new ArrayList(); //ArrayListを作成します。 static void out(String msg){ System.out.println(msg); ary.add(msg); //outが呼ばれる都度aryにそれを追加。 } static void fin(String txt,boolean tf){ try{ PrintWriter output = new PrintWriter(new BufferedWriter (new FileWriter(txt,tf))); for (int i=0;i<ary.size();i++){ str = (String)ary.get(i); output.println(str); } output.close(); }catch(IOException e){} //aryを使用したファイル出力用のメソッドです。 } } //ここまでは道具箱です。 道具箱に追加機能を書き込むことにより、他のクラスやクライアント にはほとんど影響を与えておりません。EpiWorldに一行C.fin()が追加 されただけです。クライアントは相変わらずEpiWorldを生成するのみ! クラスの継承や多態性だけではなく、アスペクトの考え方をご理解 頂けたでしょうか? 目次へ
皆さん こんにちは 凡そ前回の説明で概要はお分かりと思いますが 実はもっと簡単な手があるのです。 つまりArrayListなんてコレクションフレームワークを 使わずに出来るのです。下記プログラムを見られたら な〜んだと感じるでしょうが、意外と使われておりません。 Stringがオブジェクトであることをウッカリするのでは ないでしょうか? これまでのプログラム構造についての特徴は一旦、継承など を利用して外部にクラスを作っては、それを内部クラスに 取り込んでおります。クラスが巨大化して複雑化して 行く様子をお見せするために、敢えてそう言う手法を とった次第です。(実際のプログラムではクラスをもっと 分散化して協調作動するように設計されると思います。) クラスが客観化された概念を表わし、クライアントが 現実の述語化された意識を表わすことを明示的に ご理解頂きたかった訳です。 さらに心懸けた点は 1.クライアントを最小に抑える、 2.外部からのアクセスを防ぐ、 3.道具箱であるアスペクトの 活用を図るの三つです。 1.は言うまでのもなく、クライアントに余計なことを させない。単純なインスタンス生成だけで全てが稼働することが 理想です。オブジェクト指向の薄い人ほど、クライアントに ゴジャゴジャ書きたがる。体系的なモノの捉え方が出来ないから です。レトリックにおける換喩、提喩、隠喩の区別も分からないのです。 2.外部からのアクセスを防ぐのは内面性の独立を守る為の 当然の処置です。代わりにプログラム構造を柔軟にして 変化に対応できるようにしております。 3.staticはメモリーを食うので本来はあまりお薦めできない。 しかし今回のようなアスペクト的に使用すると思わぬ効果を 発揮します。これは案内書にはあまり掲載されておりません。 共通サブルーチン(関数)又はRubyにおけるMixInモジュール のような使用法に近い感じです。 さらに、これを敷衍致します。 つまりオブジェクト指向と言うと決まって汎化、特化とか概念操作 がまず説明されます。そして類似性や近接性とか認知言語学的な 用語が駆使され、非常に敷居が高くなっております。はては 意味論なんてまるで哲学的な議論まで飛び出す始末です。 果たしてプログラマーの方たちに理解できるでしょうか? 全体否定の反証は少なくとも一例が立証されれば良い。という 論理学の基礎程度は分かってないと厳しい。 そこの論理的、概念思考的なところが日本のプログラマーは 弱いのです。一方、思想系の人間は得てして口は立つが 腕がついて行かない。理数系に弱いのです。 これが原因で今や欧米系、だけではなくインドや中国にまで 日本のプログラミング業界は追い越されそうになっております。 若干脱線致しましたが、日本のソフトウェア業界の置かれている 状況の一端をご紹介しました。 では正解例その2です。 //ParaFin.Javaです。 //簡単な実装です。 import java.io.*; //io機能のみ使用します。 プログラムの最初からMainまでは前回例と一緒だから 省略します。 違いは道具箱の中身の2行だけです。 //道具箱です。新機能追加します。 class C { static String str = ""; static void out(String msg){ System.out.println(msg); str = str + msg+"\n"; //画面に表示されたmsgを都度strに代入。これだけ!! } static void fin(String txt,boolean tf){ try{ PrintWriter output = new PrintWriter(new BufferedWriter (new FileWriter(txt,tf))); output.println(str); //strを出力するだけです。(笑い) output.close(); }catch(IOException e){} //ファイル出力用のメソッドです。 } } //ここまで道具箱です。 あまりの簡単さにアングリされたでしょう? プログラムの面白いところは「無茶苦茶」簡単なことが 分からないと、「無茶苦茶」時間を食うところです。 同じ入社5年目のプログラマーで生産効率が1:30違います。 10年目だと1:100になります。 従って優秀な人間を10人集めたプロジェクトが、500人の プロジェクトに勝ったりします。コストは当たり前ですが、 納期、顧客満足度でも! さて次回から「残念ですが」このパラドックスから 離れ再帰についてご説明します。 ニーチェの永劫回帰とも絡め、一層思想色を 深めて行くつもりです。 目次へ
前回の: >レトリックの換喩、提喩、隠喩の区別も分からないのです。 若干この辺り誤解を与えそうなので補足をしておきます。 例えば: 一般的に換喩は近接性を表わす比喩であることから クラス集約、コンポジションの考えた方を表わす。 提喩は類、種の区分からクラス継承に使用する。 隠喩はそれらを総合的にかつ間接的に使用して 類似性を表わすためアスペクト的なモジュールを 作成する時に考慮に入れる…とまあレトリックを オブジェクト指向に取り入れればこのように解釈 されます。 しかしこれは当然意味論を含みます。 はて? このようにプログラムを構成すれば「人間」に とって理解し易い、ということであってシステムが そのように反応する訳ではありません。 だから私が色んな形でプログラムを組むことに よって同一の画面表示を提示しておるのです。 極端な例としてクライアントにゴチャゴチャ書く人に 対して、インスタンスを一つ生成することで同じ目的を 達することも出来ますよ。と説明した次第です。 シニフィアンの多様性とシニフィエの単一性という 非対称の世界が広がっておるのです。 鉛筆は決して「こんな事を書いてはおかしい。」とは 言いません。コンピューターも同じです。最低限の 文法に沿っておれば、どのような構造であっても プログラムは作動致します。 かるが故に道具としてのコンピューターは透明なのであります。 かるが故に「思考の為」の道具であると申しておるのです。 あくまで手段であります。 それをこうあらねばならぬと自ら自縄自縛に陥って ヘンテコリンなコンポーネントやコーディング規約 を後生大事に使用したり遵守したりするプログラマーが 絶えないのです。難解な哲学的な言辞を弄することにより、 人を煙に巻く似非講師が繁殖するのです。 (勿論Aranskは、こんな似非講師では決して「あります。!」 自分でも煙くって…) 本来プログラム作成は自由な創造活動であります。 以前に述べたNil(未定義)の大海に存在するものを 再発見する行為であります。 それをコスト効率や規格化で歪めているのが、現在の 業界の姿です。コーダー化するプログラマー達に 創造の喜びがある訳がないのです。 これは何を意味しておるのでしょうか? >かるが故に道具としてのコンピューターは透明なのであります。 >かるが故に「思考の為」の道具であると申しておるのです。 >あくまで手段であります。 この主張を裏返すと「人間は決して手段では有り得ない」と言う 命題が導出するのであります。 単なる機能的な道具では絶対に無いのであります。 人間は「人間が良く生きる」という至上の目的の為に 存在しておるのであります。 目次へ
皆さん こんにちは 本日は再帰処理について説明し、その思想性を明らかに します。(Recursive Operation) まずはサンプルを見て下さい。これはN!を求める メソッド(関数)であります。(例の1*2*3*4*・・・・ という計算です。7!以内でやって下さいね。 /Saiki.Javaです。 class Saiki { static int fact (int n){ if (n==0){ //nが0になったら1からスタート。 n=1; } else{ n=n*fact(n-1); //factを自ら呼んでいます。 } return n; } public static void main(String[] args) { int x = fact(5); C.out("5!は:"+x+"です。"); } } //いつもの道具箱です。 class C { static void out(String msg){ System.out.println(msg); } } 非常にシンプルな例です。答えは当然120ですね? あ、さて、 この再帰と普通の代入はどう違うのか? まず代入です。 n=n+1; 右辺のnに1を足して左辺のnになるのです。 ここにおける右辺のnが現在ならば左辺のnは 将来のnということになります。 それでは再帰は? f(n){ n=n*f(n-1);return n;} と簡単に書きなおして見ます。 外側のfと内側のfはどのような関係でしょう? 再帰の場合は外側のfが現在で内側のfが将来なのです。 みずからの中で将来の自分自身を呼び出しておるのです。 この辺りの説明でゾクッと来た人は思想的資質がある。 それが?どうしたの。なんて感度の鈍い人は早々に このHPから退出お薦めします。 そしてif (n==0){n=1;//nが0になったら1からスタート。} この条件が無ければ永遠に再帰し続けるのです。 ここで電流が体に流れない人は、即刻Exitです。 >みずからの中で将来の自分自身を呼び出しておるのです。 これはハイデッガーの現存在の未来への投企性につながり、 >この条件が無ければ永遠に再帰し続けるのです。 これはニーチェの永劫回帰そのものではないでしょうか? システム的に再帰を説明すると最初はn=5でスタートします。 そして5*のところまで来たらfact(n-1)で 4を引数にして「未来に戻る」のです。4*のところまで来たら fact(n-1)で3を引数にして「未来に戻る」のです。・・・・・・ シニフィアンfactで未来に先送りし続けているのです。 どうです。いくら鈍い人でもここまで言ったら分かるでしょう? >シニフィアンfactで未来に先送りし続けているのです。 これなんてまるでラカンの主体S(A)思想と一緒じゃないですか。 こうしてグリグリ将来に先送りしていた行為が >if (n==0){n=1;//nが0になったら1からスタート。} これで、nが0になったら、始めてn=1から今までの行為が 巻き戻るのです。再び5に向かって計算が開始され最終結果を リターンするのです。 どうです?この暑いのに寒気がして来たでしょう? この逆行と巻き戻しは何を意味しているので ありましょうか? nとは関数にとって何か? それは寿命である、と同時に1〜5までの経験、であります。 一部のプログラム言語では末尾再帰(Tail Recursion)を 提唱しております。ぐりぐりとスタックを積み上げずに変数にその場で 計算した結果を代入することでスピードとメモリーをセーブする 手法です。 これは邪道であります。 なんの為の再帰でありましょう?ぐりぐりと終点なしに先送りする 過程そのものに価値があるのです。ひょっとすると無限にループする 可能性を秘めて過去に沈潜して行く行為が、その断固たる決断性 に意味があると思う次第であります。 ではif (n==0)とn=1;は? これについては皆さんがお考え下さい。 目次へ
再帰の意味の説明が言葉足らずではなかったか? と反省し若干思想面で補足いたします。 プログラム本体は省略します。 >まず代入です。 > >n=n+1; > >右辺のnに1を足して左辺のnになるのです。 >ここにおける右辺のnが現在ならば左辺のnは >将来のnということになります。 この辺りは言うまでもなく、一般的な時間認識を 表わしております。現在、過去、将来におけるnの 自己同一性を保ちながら現在において事象が発生し それを将来に引き継いでおります。 > >それでは再帰は? > >f(n){ n=n*f(n-1);return n;} > >と簡単に書きなおして見ます。 >外側のfと内側のfはどのような関係でしょう? > >再帰の場合は外側のfが現在で内側のfが将来なのです。 >みずからの中で将来の自分自身を呼び出しておるのです。 > >これはハイデッガーの現存在の未来への投企性につながり、 とご説明致しましたが、意味はお分かりですよね? 人間は将来の絶対的な死に直面しながら、というより直面する ことにより、現存在の行為を限られた未来への投企的行為として 把握する。頽落的現状生活からの脱出を目指すのでしたよね。 > >そしてif (n==0){n=1;//nが0になったら1からスタート。} >この条件が無ければ永遠に再帰し続けるのです。 >これはニーチェの永劫回帰そのものではないでしょうか? いくらなんでも、これは説明不要ですよね。 永遠に回帰するとは「未来に戻る」ことです。 「戻る」とは過去へです。 つまり永遠の現在が連続しているという意味です。 > >システム的に再帰を説明すると最初はn=5でスタートします。 >そして5*のところまで来たらfact(n-1)で >4を引数にして「未来に戻る」のです。4*のところまで来たら >fact(n-1)で3を引数にして「未来に戻る」のです。・・・・・・ >シニフィアンfactで未来に先送りし続けているのです。 > >これなんてまるでラカンの主体S(A)思想と一緒じゃないですか。 人間の主体が去勢されることにより、内部に無が生じ その大文字のS(Subjet)が否定され抑圧される。 その後に鏡像S1がその代理として現れシニフィアン の世界へS2,S3,S4と内部に無を孕んだまま未来に先送り されるラカンの思想を言っております。 > >こうしてグリグリ将来に先送りしていた行為が > >>if (n==0){n=1;//nが0になったら1からスタート。} > >これで、nが0になったら、始めてn=1から今までの行為が >巻き戻るのです。再び5に向かって計算が開始され最終結果を >リターンするのです。 > >どうです?この暑いのに寒気がして来たでしょう? > >この逆行と巻き戻しは何を意味しているので >ありましょうか? > >nとは関数にとって何か? >それは寿命である、と同時に1〜5までの経験、であります。 > この寿命は比喩です。人間の意味的世界における認識的暗喩で あります。 ご承知の通り、空間も時間も認識概念関数であります。 物質的には脳細胞の変容が生み出すものです。 では、 人間の生に関する再帰的な結論: この「一回限りである。」とは「同時に」かつ「それ故に」 「永劫回帰」である。 この「不可逆である。」とは「同時に」かつ「それ故に」 「永遠の現在」である。 パラレルワールド理論から、 この永遠の現在に 釈迦は菩提樹の下で悟りを開き、孔子は魯の原野を彷徨し、 イエスは十字架に付けられておるのであります。 「同時に」かつ「それ故に」 目次へ
皆さん こんにちは 思想的な再帰機能は分かったが実用的にはどう使うんだ? というご質問にお答え致します。 例えば: 現在の自民党内に「派閥が存在します。」 そこで小泉さんの為にそれらの党員達を区分登録し 一括表示、プリントできるプログラムを作成 しました。 import java.util.*; import java.io.*; // Iterator Collection ArrayListを使うために必要 /** * 自民党、派閥と議員を一緒に扱うための Kankeishaインターフェイス **/ interface Kankeisha { /** * 表示します **/ public void hyouji(); } /** * 党員を表すクラス。Kankeishaを継承しています **/ class Touin implements Kankeisha { private String name; // 属性です名前を保持します /** * 名前を渡してクラスを具体的なTouin(オブジェクト) * にするコンストラクタ * @param name 名前 **/ public Touin(String name) { this.name = name; } /** * Kankeishaは表示できるのでTouinも表示します **/ public void hyouji(){ C.out(name); // 名前を表示します } } /** * Groupを表すクラス。Kankeishaを継承しています **/ class Group implements Kankeisha { private String name; // 属性です名前を保持します private Collection kankeishas = new ArrayList(); // これが1:Nの関係を表す属性。Kankeishaを複数もっている /** * 名前を渡してクラスを具体的なGroup(オブジェクト) * にするコンストラクタ * @param name 部門の名前 **/ public Group(String name) { this.name = name; } /** * Groupに所属するGroupやTouinを追加します。 * @kankeisha GroupもしくはTouinのオブジェクト **/ public void addKankeisha(Kankeisha kankeisha) { kankeishas.add(kankeisha); } /** * Kankeishaは表示できるのでGroupも表示します **/ public void hyouji(){ C.out("\n" + name); // Groupの名前をまず表示 \nは改行 C.out("----------------"); // 区切り線の表示 Iterator iterator = kankeishas.iterator(); // このGroupに所属するGroupを操作するオブジェクトです。 while(iterator.hasNext()){ // Java型のお約束便利なForループ Kankeisha kankeisha = (Kankeisha)iterator.next(); // ループで1件分のKankeisha取得(touinもしくはGroup) kankeisha.hyouji(); //hyouji()を自らのメソッド内で呼び出す「再帰」です。 } } } /** * Groupとtouinを管理するHabatsuであるMainです。 **/ public class Habatsu { /** * java実行時に呼ばれるメソッド **/ public static void main(String[] args) { // 党員の派閥分けです。小泉さんは //jimintou所属にしました。 Touin fuku = new Touin("福田さん"); Touin ao = new Touin("青木さん"); Touin kato = new Touin("加藤さん"); Group sekoiGroup = new Group("セコイ派"); sekoiGroup.addKankeisha(fuku); sekoiGroup.addKankeisha(ao); sekoiGroup.addKankeisha(kato); Touin kame = new Touin("亀井さん"); Touin eto = new Touin("江藤さん"); Touin hasi = new Touin("橋本さん"); Group owaraiGroup = new Group("お笑い派"); owaraiGroup.addKankeisha(kame); owaraiGroup.addKankeisha(eto); owaraiGroup.addKankeisha(hasi); Touin koi = new Touin("総裁ー小泉さん"); Group jimintouGroup = new Group("自民党"); jimintouGroup.addKankeisha(koi); jimintouGroup.addKankeisha(sekoiGroup); jimintouGroup.addKankeisha(owaraiGroup); jimintouGroup.hyouji(); // 再帰的表示ロジックですから一行だけ! C.fin("test.txt",true); //test.txtに表をOPします。 } } //道具箱です。 class C { static String str = ""; static void out(String msg){ System.out.println(msg); str = str + msg+"\n"; //画面に表示されたmsgを都度strに代入。 } static void fin(String txt,boolean tf){ try{ PrintWriter output = new PrintWriter(new BufferedWriter (new FileWriter(txt,tf))); output.println(str); //strを出力するだけです。(笑い) output.close(); }catch(IOException e){} //ファイル出力用のメソッドです。 } } //ここまで道具箱です。 無事プリントされたでしょうか? 目次へ
Javaにおける言語機能で思想的な意味合いのあるもの については、ほぼ説明し尽くした感があります。 これ以上進めてもGUIやイベントドリブン、ネットワーク EJBなど技術的な要素のみで言語構造自体に面白みがない。 プログラムを代替化のツール、省力化の道具として見ると、 限りなく人間の能力が痩せて行きます。 プログラムするたびにブラックボックスが増えます。 情報圧縮が発生します。つまりマシーンに作業を委譲すると同時に 能力低下が不可避になってしまうのです。コーダーやメンテの ようにマシーンに対して人間が従属的な位置に立たされてしまう。 そうじゃなくて、プログラミング作業自体に人間の知的能力を 増進する効果は無いのか? 人間が気付かない視点の発見は無いのか? 異質性に触れる事により人間自体が成長することは無いのか? プログラム構造から自然言語より透明に、より包括的に、 よりダイナミックに認識が伝達されそれがさらに深まる きっかけにならないのか? 今のところオブジェクト指向言語から関数型言語や論理型言語に 範囲を広げて上記に述べたような可能性を探しております。 取り敢えず、プログラム言語思想はネタが出来るまで 小休止します。 コンピューターに意味論を求めたのが、AIや第五世代コンピューターの 失敗に繋がったと考えています。 意味ではなく構造を! 感性ではなく認識手法を! あくまでコンピューターの透明性を活かすべきだと 愚考する次第です。 プログラマー全体のインテリジェントレベルが高まれば、次は量子 コンピューター用の言語だ。 楽しみでは御座るまいか、ご同輩! 立体構造的で重層的で状態推移的な世界が複数同時に ダイナミックに動く。それが時々意図的に、かつ偶然に 交叉する。プログラミングの世界は、まだほんの 入り口にも達していない。未来は前途洋々と開けております。 Let's get it over! 目次へ