「ようこそ」ページへ
目次へ
<< 前へ  次へ >>

Mopsプログラムの基本単位はワード

Mopsで既に定義されて準備されているコードの基本単位は"ワード(word)"と呼ばれます。コンピュータ科学の方面には別の意味のワードも使われるので、はじめのうちは注意しないといけません。コンピュータ科学でのワードは機械の記憶の基本単位のことで、32ビットコンピュータなら32ビットで1ワード、64ビットコンピュータなら64ビット1ワードということです。MopsというかForth系一般ですが、そこでいうワードは、他のプログラミング言語でいう関数や手続というものに当たります。正式なコンピュータ用語(あるいはFortranとか)ではサブルーチン(subroutine)と呼ばれるものです。

サブルーチン

では、サブルーチンってなんでしょう。ルーチン(routine)は"決まり切った作業"という意味で、それにサブ(sub: 下位のとか副次的なという意味)がついたのが、この言葉の成り立ちです。サブがあれば、スーパーというかメイン(main:主要な)があるわけです。実際、メインルーチンというのもあります。メインルーチンは、プログラムの一番最初に実行されます。そして、適当に必要になったところで、サブルーチンを呼んで、必要な仕事の手助けをしてもらうわけです。

そんなわけで、サブルーチンというのは、あるまとまった処理をするコードの集まりです。どうしてこういうものが必要になるかというと、例えば、同じパターンの計算をプログラムのあちこちで何回も何回も実行しなければならない場合というのがあります。このとき、その場所にいちいち同じコードをくり返し書かないといけないとすれば、作業も大変ですし、プログラムも長くなってしまいます。サブルーチンがあれば、これを一カ所にまとめて書いておき、必要なその都度名前で呼び出すことによって、コードを大幅に節約することができるわけです。

ワードの定義

で、このサブルーチンがMopsではワードとよばれるわけです。Mopsの中には、すでにかなりの数のワードが定義されています。これらを組み合わせて、自分で新しいワードをつくることもできます。ワードをつくるときにはその内容を決めることになるので、ワードを定義するといいます。いったん定義されると、はじめから定義されていたものと自分が定義したものとは区別されません。

普通のワードの定義のときにはコロン記号":"で始めます。そのためコロン定義(colon definition)と呼ばれます。そしてワード名、それから内容を書いて、セミコロン記号";"で定義を閉じます。

: SUMIMASEN  m(_ _)m   ;

いや、まあ、こんなのはありませんが。すでに定義されているワードを呼び出すには、その名前を書きます。

: OWABI  SUMIMASEN  MOHSHIMASEN  YURUSHITE   ;

上でコロン記号とセミコロン記号と書きましたが、本当はこれらは単なる記号ではありません。これ自体きちんと定義されているワードで、一文字でできた名前をもつワードなのです。Mopsのワードは半角空白か改行で周囲と区切らなければなりません。逆に一つのワード名は中に空白を含むことはできません。これは、Mopsのワード名をつくるときの数少ない制限の一つで、もう一つは、Mops独特のメソッドとの関係上、ワード名の最後にコロンを使うことはできません。制限はこれだけです。漢字かなも大丈夫でした。ビックリ。

コロン定義するワード名に大文字小文字の区別はありません。実際には、すべて大文字に変換された上で記録されます。

Mops/Forthプログラミングの原則

ワードはできるだけ小さく、細かい作業単位で区切るのが原則です。そのようなワードを少数ずつ組み合わせながら、次第に1ワードの行う現実の作業を複雑化し、抽象化して行きます。この過程は、統合による単純化、明確化の過程であるべきです。理想的には。

ともかく、あまり長〜い定義を持つワードは極力つくらない、というのが原則です。このような考え方をすることによって、問題をより明確に把握できる上に、再利用可能性の高いワードをつくることができ、さらには、コードの保守、つまり改訂や修正がしやすくなるということです。あまりキツくは考えず、努力目標ということで良いと思いますが。

サブルーチン呼び出し? -- ちょっと入り組んだ話

サブルーチンを"呼び出す"といいましたが、それはどういうことでしょう。お察しの通り、初回にふれたジャンプをするわけです。つまり、呼んでここに来てもらうというより、サブルーチンのコードがあるところに飛ぶのです。

ただし、実をいうと、このジャンプにも二種類あります。これらは普通、機械語の命令として組み込まれています。

一つ目のジャンプは、本来の意味のジャンプというか、行ったきりになるジャンプです。戻ってくることを考えない、鉄砲玉ジャンプとでもいいますか。この場合、行った先のコードで、そこの部分が完了したらどこに行くという具体的な情報を自前で持っていないといけません。まあ、全プログラムを終了してもいいんですが。

もう一つのジャンプは、ジャンプした先のまとまった処理が終わった後には戻ってくるということを前提としたジャンプです。これは、ジャンプ前にいた場所のコードが、後で戻ってきて欲しい場所の番地(アドレス)を、ジャンプ前に予め保管しておくことで実現されます。飛んで行った先のコードには、そこでのまとまった処理が終わった後具体的にどこに行けばいいのかという情報は書き込まれていません。ですが、戻る場所を格納しておく場所は予め全体として決めておくので、それはわかっているわけです。ですから、終わったらその格納場所を見て、そこに記録されている場所に戻ることになります。

で、サプルーチンの"呼び出し"というのは、後の方のジャンプのことを指します。サブルーチンというのは、作業が終わったら呼び出し元に戻るというのが原則ですから。この「必ず戻ってくる」ということを考えると、"赴き"ではなく"呼び出し"といってもいい気がしてくるのではないかと思います。その"働き"にちょっと一時的に来てもらう、というか、ん〜、かえってわかりにくいですかね。ともあれ、この機構は、機械語として組み込まれたこの機構をサブルーチンで利用しているというよりも、ソフトウェアのサブルーチンの機構を実現する手間を省くために機械が対応したものだろうと思います。

Forth環境というのは伝統的に、といいますか、一番はじめから、この"呼び出し"のプロセスを自前で持っていました。つまり、ソフトウェアとして実現していたのです。Mopsはネイティブコード方式なので"呼び出し"は機械語で実装されている方法を使っています。機械に組み込まれた方法を使った方が直接的だから当然速い、と思われるかもしれませんが、実は必ずしも当然じゃないらしいのです。まあ、PowerPCは機械語バージョンの方が速いようですので、Mopsに関しては最も速い方法を採用しているといえます。ところが、ちょっと前の普通のCPU(インテル系とか)だと、そうじゃないらしいのです。

この局面に関しては出来が悪い機械もある、といえないこともないのですが、実は、後からコードを追加していくことができないといけない Forth系の特性も絡んでいまして、どこにどのような形でジャンプするのかによって、標準と違うと予想をしくじったりとか、ひどく手間取ったりするらしいのです。こういう機械では、平均すると、ソフトウェアの方で呼び出しの作業をしてやった方がロスが少なかったりすることもあるのだそうです。最新のものはそうでもないらしいですが。ですから、Forthが特に呼び出しの手順をソフトウェアとして準備していることは、今でも意味はあることらしいです。とくに、コンピュータ科学としてはこの機構を知ることは基本とすべきだともいえますね。ソフトウェアで作ってある結果として操作可能性も高まります。Mopsではこの部分をいじるのは危険ですが、仕組みを理解することはできます。

いずれにせよ、呼び出しというのは、少しではありますが、ベタでコードを実行していく場合よりも手間取るわけです。そのため、 Forthの原則通り細かく細かくサブルーチンを分けてつくると、一般に時間のロスは大きくなるわけです。まあ、サブルーチンの呼び出しの際の余分な手間(オーバーヘッドといいます)というのはジャンプに関するものばかりではありません。C言語などの普通の関数呼び出しでは、その他のオーバーヘッドというのが、かなりあるように思われます(仕組みからの推論 -- パラメターや局所変数の値、その他戻ってくるときまで残しておかなければならない値を全部どこかにしまっておかないといけない。どの程度手間かは機械の仕組みに依存する。)。そうすると、この部分がほとんどないMopsなどでのワードの呼び出しのオーバーヘッドは、他の言語の場合よりも軽くみていいということはいえるわけです。

あまり効率ばかり気にしてもしょうがないのですが、こういうことを考えるのは、コンピュータが実際にどういう風に動かされているのかを意識する結果になるので、一般的には良いことだと思います。観念的な論理の世界だけでプログラミングを思考する、というのも、面白いといえば面白いですけどね。

ワードは基本単位--補遺

このページの内容は、ワードはサブルーチンということで説明してきました。狭い意味でのワードに限れば、これはそれほど外れていないともいえます。しかし、ワードは「プログラムの基本単位」というときには、実はもう少しワードを広く考えています。つまり、名前を付けて呼び出せるものは全てワードだと考えているのです。具体的には、いわゆる関数やプロシジャーに当たるものの他に、変数も含まれます。さらに、Mopsではクラスやオブジェクト(インスタンス)も含まれてきます。このように考えると、Mopsプログラムは、まさにワードから成り立っているのです。先走りで恐縮ですが。


<< 前へ  次へ >>
目次へ
「ようこそ」ページへ