プログラム言語の哲学的考察 [コンピュータ言語]

Objective-C を、お更いしている内、変な疑問と法則とは大げさですが、そんなものが生じました。良くある入門書を読んでみても、ちっとも頭に残らない程、記憶音痴な私には、頭に残すために自分なりに工夫をしなければならないので、最近考えついた、化学の原子の状態を頭に入れながら、対応する箇所に文字を入れながら、試行錯誤して行くと、今の自分(self)が機械言語のプログラムと同じことをしている自分(self)に気付いたのです。つまり、私にとってプログラムとは、暗記するものではなかったのです。これは一つ明るい展望が開けました。

では、そのごく一分で説明すると(一分が全てでも有りそうです。)
プログラム言語では、始まりと終わりが必ず有り、対で良く使われます。プログラムをかじった人なら、次の文が何を意味するかは、殆どの人が分かるでしょう。

/* comment */

これは、良く見かける文です。コンパイラーは、これを無視して、又は読み飛ばすとされています。確かにプリプロセスの段階では、この部分は出て来ません。
しかしよく考えると、機械は、これを最初からコメントと判断は出来ない筈です。只人間の方が勝手にそう思い込んでいるとした方が、後々思考の面で有利に働きます。では、機械はどう読んでいるのかとすれば、このスラッシュ記号は、インターネットで良く使われ、http://www.xxx.oo.xx/oo/xxx/ と言う様な形で、出て来ます。それでは、上のスラッシュとこのスラッシュを機械が区別するのかと言うと、しない筈です。また、この記号は除算でも使われます。機械は、これも区別出来ない筈です。では、読み飛ばしている方法とは何かと言えば、次の * 記号です。試しに、この対の * を取ってコンパイルしてみましょう。何と吐き出したでしょうか。
Expected identifier or ‘(‘before’/‘token
赤字のエラーで、直訳すれば、予期された識別子か ’(‘’/’ の印の前 と言う訳になり、もっと砕いて言えば、識別出来ません、とでもなるのでしょうか。つまり、機械は通常の仕事をしようとしているところ値が無いので、できないと言っているように受け取れます。
では、// comment はどうなるでしょうか。どちらも値が無いので、仕事をする事無く、次のスラッシュを終了記号と捉え、キャリッジリターンを読み、一行を終え、次の行に移動することになります。とは言うものの読み込んではいるようです。
では、http:// の場合は、どう捉えたら良いでしょうか。同じように考えれば、ここで終わりなのですが、キャリッジリターンも無ければ、次の行が有りません。取り敢えず次の箇所を読み込んで行くのですが、@で始まるドメインが最優先に探され、目的地まで辿り着きます。この仕組みは、ディレクトリの概念でも述べましたが、混乱すると悪いので省略させてもらって、次の * の役割です。
アスタリスク * は、コンピュータ上でも色々な使い方が有るとされています。
乗算、ポインタ、ワイルドカード… といった言われ方をされますが、これは、最初に覚えた覚え方の問題、錯覚で、機械は別に区別はしていないとしか言いようが有りません。私もよくよく考えたのですが、前後のある型の種類によって、違ったように見えるとでも言いましょうか、前後が数字なら、掛け算をしているように思え、文字なら右側に対応する文字を探し当て、そのアドレスに辿り着く感じです。
それで、/* comment */ に当て嵌めると、割り算をしようと右には掛け算のマークで、その右側は、ストリングです。なので、comment文字を探そうとしますが、同じアスタリスクマークが有り、もう探さなくても良いよ〜と指示が有ります。それで次を読むと、最初のスラッシュの終わりのマークです。書類上は保存されますが、コンパイル時には何も出来なくなり、所謂コメントとなる、と考えると、後々躓くことが少なくなる筈です。

それを踏まえた上で、今度もまた、良く見かける簡単な文です。

#define _NSWINDOWS_DLL_GOOP __declspec(dllimport)
#define APPKIT_EXTERN extern "C" _NSWINDOWS_DLL_GOOP
#define APPKIT_EXTERN _NSWINDOWS_DLL_GOOP extern

# のマークは、色々な呼び方が有りますが、ここでは、パウンドと呼ばせてもらえば、#に続く文字は他にも if とか pragma とか色々ありますが、実際のところコメントと同じコンパイルされる訳ではないので、使う本人さえ混乱しなければ、何でもOKのようです。定義として使うのであれば、スタンダードに、define とすれば、誰にでも分かるというものです。
さて、問題は次の空白です。space は、文字を区分するためには必ず必要な空文字ですが、プログラム言語上では、もっと別で大事な意味が有りそうです。この使い方、空白概念さえ掴めれば、もう大した障害はない、とさえ言っても大げさでないといえるくらいです。と言っても、大げさですが、では説明です。
まずはコンパイラーは、この一行を、何と読み込むでしょうか。最初に#を読み、defineを読み込んで、空白にぶつかります。なのでここで、defineを認識して記憶します。しかし、まだ終わりの指示子は有りませんので、先を読み込みます。次は _ アンダースコアと呼ばれる接頭子で、unixでよく使われる、重複文字のマクロ定義を変更する、追加する場合、非常に便利な使われ方だと理解しています。で、_NSWINDOWS_DLL_GOOP という文字の入れ物を作るとしました。
最初の一行には、( )が使われていますが、対対称の完了型なので、カッコの中の要素を、declspecに引き継がせている、拡張させている、関数でもある、と取れます。日本語に合えて訳せば、dllインポートとしての宣言スペックと私は認識しています。通常であれば、関数として理解するかもしれませんが、しかし機械のプログラムの世界では、よく数学で教える関数とは所詮意味合いが違います。ここでは、これでしか説明はしませんので、コードの本文で出て来る様な( )を同じ意味になるように、自分で置き換えると自主学習になると思います。つまり、ここでもまた、機械は使われ方を区別しているわけではないと言いたいのです。
さて、この一行を最後まで読み込んで、キャリッジリターンまで行けば、次の行に進むわけですが、#の終了となるもう一つの#が有りません。文終了のセミコロンである;も有りません。つまり、この一行は、完結していないことになります。
コンパイラーを設計する場合、これをエラーとしても良い筈ですが、それを逆利用するのも手であることは、この構文がまだ使われていることでも明白です。又丸っきり使わない手も有り、JAVA言語では使われていません。
では、対称性を破ったこの一文を、コンパイラーはエラーをどう処理するのでしょうか。ここが私の独自の発想です。
コンパイラーは、これを無かったことにしたい分けです。又は、独自に対称性を作りたいわけです。なので読み込んだ最後の方から、一に帰そうと前の文字のアドレスに、放り込みます。所謂代入です。ところが、#define は、ワンセットですから、記号扱いとなり代入出来ません。つまり、別の値を持った _NSWINDOWS_DLL_GOOP がメモリ上を彷徨うことになります。文も完結していないので、いつでも呼び出しが出来るように、準備万端な状態にもなります。

次の行は、空白が4つも有り、使って良いのか分からない、” “が出て来ます。さて、これは文字、文字列を固定する指示子ですので、代入出来ません。なので、extern に代入され、最後にAPPKIT_EXTERNに代入されます。
3行目はこの逆のパターンで、APPKIT_EXTERNには、別の角度も代入されますから、アクセス段階でエラー回避が強化されます。

この定義された APPKIT_EXTERN は、マクロであり型にもなり、; もないので、汎用性のある入れ物になります。
これが、理解出来れば、コンパイラーは、最後まで同じことをしているだけです。
例えば、プロトタイプとか有りますが、文として文の代入する入れ物が無ければ、コンパイラーは、エラーとして吐き出します。
よく勘違いしそうなのが、[ ] の使われ方で、配列と記憶していると思いますが、Objective-Cでは、[ : ] といった使われ方で、やはり代入の一つの方法で使われ、コンパイラーが区別しているように見えますが、残念ながらコンパイラーは単純な言われたことしか出来ないので、同時に両方を区別できません。ファイルの拡張子.c, .m は、同時にコンパイル出来ますから、平等に読んでいるわけで、区別しようが無い筈です。つまり、Objective-Cでは、[ ]の中にある値だけ、値が有り、それを代入、又は値渡し出来ることになります。ただし、ユーザが迷う様なことは避けなければならないので、それぞれの言語の混合は避けているだけです。

こうなると、入れ物となる袋には色々な種類が有り、取り出す順番、方法が大事となり、中には袋の中に又別の袋が有ったり、同じ種類の袋出ないと取り出せなかったり、今は取り出したくないので、チャックしたりと色々な方法が自然と生まれて来ます。
只あんまり袋が多過ぎたり、変な入れ方をしたりすると、普通の買い物でも迷うように、迷ってしまいます。

プログラム言語は、主に英語圏の産物なので、どうしてもアジア圏の変換を求められる地域では敬遠されがちですが、丸っきりアルファベットを見るだけで、嫌悪感を感じる人は別とすれば、記号の集列ですので、ハンディの差はそんなに無いと言いたいところです。

私も、プログラムは誰かに教わったことも無く、組んだことも無いですけれども、素人考えになるかも知れませんが、日頃疑問に思うことを述べさせてもらいました。
何かの参考になれば、幸いです。
nice!(0)  コメント(0)  トラックバック(0) 
共通テーマ:学問

この広告は前回の更新から一定期間経過したブログに表示されています。更新すると自動で解除されます。