初めの一歩

はじめに、特定のプログラミング言語の紹介というのでなく、コンピュータはどんなふうに動かされているのか、みたいな、もっと一般的な観点からの話を書いてみようと思います。コーナー毎に完結できるようにしたいという方針できていますので、このサイト内の他のページの話との部分的なダブりは避けられません。まあ、与えられたサイトスペースはテキストじゃあ到底埋められない程いっぱいあるし、見方が違えば、言い方ちがってくるでしょうし。同じことを角度を変えて何度も考えるのは、事柄の理解にいちばん役立つやり方だと私は思います。世界は一面だけで成り立っているわけじゃないのですよ、ええ(^^;;)。

OS上のアプリケーション

さて、あまり原始的なところから初めてもしょうがないので、OSを前提として、その上のアプリケーションをプログラミングするというところから話を進めて行きましょう。OSとかアプリケーションの意味は大体分かりますよね。OS(オペーレーティングシステム)というのは、MacとかWindownsとかLinuxとかいう例のアレ(^^;;)で、アプリケーションは、何か特定の作業するために起動する、ワープロとか、ウェッブブラウザとかで、普通に売っているソフトウェアというのは、これに当たります。ご承知のように、こういったアプリケーションは、特定のOSの上で動かされることを前提としてつくられています。

コンピュータやその他外部装置があって、OSという基本ソフトウェアが、それを統括しています。統括している、という意味は、機械の側で電気的に起こる状態変化、例えば、マウスを動かしたり、クリックしたり、キーボードのキーを押したり、等々といった出来事を、OSが統一的な規格に従った入力としてアプリケーションに提供する、ということです。そうすることで、アプリケーションの側では、特定の機種の装置はどういう仕様で信号を送ってくるのか、ということにいちいち配慮する必要なく、OSの決めた方法に従っておけばいいことになるわけです。つまり、OSはそういう機械の仕様の違いを吸収するということを、その主要な目的の一つとして持っています。もっとも、OSだって、あらゆる仕様に予め対応しておくことはできませんから、外部装置をつなぐときには、デバイスドライバ、という、機械とOSをつなぐためのソフトウェアもないといけないんですがね。今だと、OSが機械に対応するというより、Windowsに機械メーカーの方が合わせてる状態なんでしょうが。

そんなわけで、アプリケーションのプログラミングとは、OSからの信号に応じて、場合によってはOSの機能にもお願いしつつ、条件に応じて必要な電気信号処理を継続して行くような、コンピュータへの命令の束を作り上げることです。つまり、アプリケーションというのは、全体としていえば、機械からの信号を受け取りつつ、条件に応じてコンピュータ命令して、実現したい結果を手に入れるための、機械への指図の集まりです。しかし、機械が次にすべきことを一つ一つ指定していくというのでは、恐ろしく煩雑な上に、ものすごく長くなってしまいます。これを分かりやすくまとめて表現する方法として、プログラミング言語、という人工言語があみ出されるわけです。

プログラミング言語小史

上に書いたアプリケーションの動作に、"条件に応じて"というのが、いちいちついていたことにお気づきでしょうか(意図したわけじゃないんですが)。条件に応じて手順を変えることができないアプリケーションには、あまり有意義な作業は期待できないでしょう。このような意味で、条件判定というのは、プログラムの中で、データ処理(計算)に並ぶ最も原始的な動作の一つであるということができます。

その結果として、大抵の場合、条件判定は機械のレベルで組み込まれています。つまり、機械への直接の命令として、ということです。例えば、Macintoshが採用しているPowerPCというコンピュータだと、この数値とこの数値を比べて、同じならどうする、違うならどうするという機構が、三つくらいの命令で実現されています。これは、条件が成り立てば別の命令のところにジャンプするけれども、成り立たなければ、ジャンプなしで、そのまま次の命令に移る、というかたちで実現されます。命令としては、ジャンプする先を登録する命令、値を比較する命令、条件が合えばジャンプという命令になります。

コンピュータのプログラミングの基本として、この条件を性格にきちんと書き分けることは非常に重要になります。一般に、"アルゴリズム(algorithm)"とかいわれているのは、このことを指しているわけです。起こりうる状態をきちんと網羅して、それぞれに正しい対応方法を結びつけることが大切なわけで、正確で、無駄のないアルゴリズムが理想、ということになります。

コンピュータへの命令と直接に結びついているプログラミング言語は別としても、初期のプログラミング言語は、上のような、機械に組み込まれた条件判定をなぞるような形で、諸条件への応答を表現することが多かったようです。有名なのが、GOTO文によるジャンプです。

GOTO文というのは、予めどこかに印を付けておいて、特定の条件が成立したときには、その印のところに飛ぶ、という命令です。初期のBASIC言語などは、全行に行番号という印がついていました。ジャンプした後、あるまとまった処理が終わって前にきたところに戻りたいときには、戻るところにも印をつけておいて、そこにジャンプするわけです。このGOTO文をあまり使いすぎると、実行がプログラムのあっちこっちにジャンプすることになって、プログラムをものすごく読みにくくするわけです。

このGOTO文への非難は暴走しまして、一時期は、GOTOと書いてあるプログラムは全部ダメなプログラムだと言い張る人さえいたそうです。それは過剰反応としても、ジャンプは、機械ならともかく、人間には追跡不能->理解不能という結果をもたらすことが多いことは承認され、別の記述法が奨励されました。これは、つまり、if-elseを用いて、"こうならば、これをする。そうでないなら、こっちをする"ということを、その場に書き込んできちんとまとめるということです。これが、"構造化プログラミング"と呼ばれる方法の最小基本単位を成すものです。構造化プログラミングはこれだけに止まるわけではありませんが。

ときどき、構造化プログラミングに対応しているという意味で、構造型言語とか、構造化言語、というプログラミング言語の分類をする場合があります。しかし、正確には、構造化プログラミングはプログラミングの手法であって、プログラミング言語の特性ではありません。多分、何らかの形でif-else条項(クローズ)が書けるという程度、歴史的にいえば、GOTO文によるジャンプなしでもプログラミングできる言語とかいうような意味でしょう。プログラミングの手法と言語の特性をごっちゃにするという点では、後発の「オブジェクト指向言語」という言い方も似通っています。構造化言語というのは、オブジェクト指向という考え方が言語の設計段階で色濃くは入っていない、という意味で使うのだと思います。強いていうなら命令型(imperartive)言語という方が正確ですが、突き詰めて考えると、オブジェクト指向も命令型といえなくもない(命令先がコンピュータからオブジェクトに変わるだけ)ので、これでは、区別の目的が達成できませんね(^^;;)。命令型言語という括り方は、関数型言語と呼ばれるものと区別するにはいいのかもしれません。
なお、GOTO文は繰り返し(ループ)に用いられたりもしたんですが、このループの話はまた、後にしときます。

ところが、プログラムが複雑化するにつれて、条件判定の項目数はどんどん増えて行きます。いろんな"場合"がでてきますからね。長~い場合分けのリストを見て、ああ読みやすいと思う人はあまりいません。構造化されたって、読みにくいものは読みにくい。長くなると、混乱してミスしてしまう機会も増えます。単純に書く量が増えるだけでも、それだけ時間が余分にかかるようになります。何とかしてアプリケーションのためにプログラムとして書かなければならないコードの量を減らさなければ、このままだと地球上の人間のほとんどがプログラムを書くようにならないと、コンピュータ社会は維持できなくなるという議論まであったようです。

そんな中、ある特別な書き方をしておけば、一度書いたプログラムの用途が、普通の書き方をするよりもずっと広がるという議論が登場しました。これが、オブジェクト指向プログラミングと呼ばれる考え方です(その前にサブルーチンという考え方があって、動的ライブラリとかもそんな話ですけれども。)。一度書いたものが何度も使えるなら、全体として書かなければならないプログラムの量は減らせるというわけです。現時点で考えれば、この主張は、商売のための、ある種の詐欺だったような気がしないでもありませんが、この、オブジェクト指向という考え方と表裏一体になっていた、GUI(グラフィカル・ユーザ・インターフェイス: Graphical User Interface)、つまり、ウィンドウやメニューやダイアローグをマウスなどで操作してコンピュータを操るという機構ですが、これが広く受けいれられたせいか、現時点ではオブジェクト指向でプログラミングすると便利であることには間違いありません。

オブジェクト指向プログラミングというのは、オブジェクトと呼ばれる対象をプログラムの中で作り出して、それにメッセージを送って仕事をしてもらうという考え方(たとえ話、比喩)でプログラムをデザインすることです。このような考え方をもっともらしく表現できる仕組みをもったプログラミング言語のことをオブジェクト指向言語と呼ぶわけです。条件判定は、どのオブジェクトにどのようなメッセージを送るかということに還元されてしまい、必要ならばオブジェクトが残りの条件に感応して、適切な効果をもたらすというようになるわけです。Mops言語は、このオブジェクト指向言語に当たります。

Mopsの基礎になっているのは、Forthというプログラミング言語です。Forthは、1970頃には実質的には完成されていた古い言語なので、現在いわれるような意味でのオブジェクト指向という考え方は反映されていません(最初のオブジェクト指向言語といわれるのは、Simula67でしょう。67は1967年ということです。これは多分、規格発表の年で、Simula言語で1967年に実際に普通にプログラムを組めたわけではないでしょう。Forthは完成よりも実際の使用が先行しました。)。このForthを拡張して、オブジェクト指向の形でプログラミングを表現(設計)できるようにしたのがMopsです。このような、拡張としてオブジェクト機能を持つ言語はハイブリッド言語と呼ばれています。この点、有名なプログラミング言語としては、Java、C++、あるいは21世紀MacintoshではメジャーのObjective-Cなどと同類ということになります。これらは、やはり1970年代の初めにできた古い言語であるC言語を基礎として、オブジェクト指向拡張を付け足したものです。

どうすればいいのか

このようにみても、プログラミング言語が、条件、状況、場合に応じて適切な処理を繰り出す機構を、どのような形で表現するかという観点にそって発展してきたことがわかります。つまり、条件分岐(ジャンプ)->場合分け条項(if-elseやcase-switch)->オブジェクトとメッセージの組み合わせ、と。そして、諸条件への対応を、あまり煩わしい手だてを要することなく、うまく処理できることを、柔軟性(flexibility)があるとか、動的(dynamic)だとかいって宣伝しているわけです。実際のコンピュータの中では今でもジャンプを繰り返しています。つまり、それを各言語がどのように表現するか(隠すか)、そのやり方が変わってきているのです。

プログラミングは、結局のところ、色々な条件に応じてその条件に適切な処理を結びつけるということにつきます。論理的に起こりうる状況を網羅し、これらに適切で無駄のないデータ処理手続(計算なども含む)を結びつけてあれば、バグ(欠陥)のないプログラムになるといえます。

うまいプログラミングは、場合分けが適切で無駄がないことと、それぞれに連なる手続が適切で無駄がないことで判定できるでしょう。プログラミングをするのに、特別な才能は必要ありません。きちんと物事を整理して考えることができればいいわけで、これは訓練で何とでもなるでしょう。確かに、他人が思いもつかないようなうまい方法を思いついたり、誰もできなかった結果を実現したりするには、才能が必要です。それはプログラミングだからそうだという話ではありませんよね。面白いアプリケーションをつくるには、やはりセンスというか才能が必要です。よくあるフリーのアプリケーションをみても、作り手のセンスの良さがはっきりと見て取れることがあります。ですが、目的が決まっていれば、その目的を実現するプログラミングをするのに、そのようなセンスが絶対に必要、ということはないと考えます。

やや大袈裟な話をすれば、数百年前には、文字が読める人というのは限られており、書物から知識を得ることができるには特別な才能(血筋も?)必要だと考えられていた時代がありました。確かに、現在でも、どんな本でも本当にきちんと読めるのには才能が必要ですし、人を驚かすような鋭い文芸批評ができるためには相応の才能は必要ですが、小説を読んで自分なりに楽しむのに、どの程度の才能が必要でしょうか。好き嫌い、得意不得意の問題はあるでしょうが、それほど高いハードルじゃないと思います。プログラミングも、結局はそんなところじゃないでしょうか。べつに、抜きん出なくてもいいじゃないですか。そこそこできれば。

ですから、プログラミングは、誰にでもできるものだと思います。楽しいと思うかどうかは、人それぞれですが。問題を、自分なりにでも、どっかに書いているものを参考にしてでも、きちんと整理して処理するように努力することです。論理的に考える、というんでしょうか。それは人によっては苦痛かもしれませんが、面白いと思うことができれば、どうということはないでしょう。仕事じゃないなら、いやなことはやらなきゃいいんです。で、できるだけ、嫌なことを避けて望みの結果を得ようともがくのも、悪いことではない、いやむしろ良いことだ、といわれています。

気の持ち方

そういうわけで、シャカリキというか、鉢巻きをしてお勉強しようとするのじゃなくて、面白がってちょこちょこいじってみよう、というのが私の勧めです。Mopsはそのためには、ものすごく都合良くできているんですよ。それで、よく、プログラミングそのものへの入門として優れているともいわれるわけです。ただ、語順が"普通の"プログラミング言語(や数式)と違うので、人によってはものすごく取っ付きにくいともいわれます。もう、おつむに柔軟性がなくなってしまっている人は困っちゃうんですが、Mopsをいじるのはリハビリにはなるかと思います。冗談はともかく、仕事としてやるならもちろんのこと、趣味でやる場合でも、なるべくなら複数のプログラミング言語に触れておくべきでしょう。特に、C言語の基本的な書き方の決まりを知らないと、OSの機能を直接利用したいときにどうしていいか分からなくなります。特にC言語を"履修"しなくても、プロトタイプの見方くらいは分かるようになるよう説明したいと思います。しかし、凝り固まってしまうのは、いずれにしても良くないことです。

Mops、というか、もとになっているForth言語の特徴なのですが、プログラミング言語には、大きくわけて、Forth系とそれ以外とに分かれるといえる程、"普通"に使われているプログラミング言語と異なっています。Mopsを始めるには、はじめのうちは、プログラミング言語とはこういうもの、という先入観を全部捨てなければならないかもしれません。実際には、すこし慣れてくるとMopsの方がずっと単純明快であることが解り、これを基点にして、他のプログラミング言語はどういうヒネリを加えてそのようになっているのか、が分かってくるのですが。

そんなわけで、Mops/Forthを習得しようとその言語特性の暗記やプログラミング上のパズルの演習に興ずるのも否定はしませんが、私はむしろ、Mopsをいじりながらプログラミングそのもののイメージ、つまり、コンピュータにあることをさせるためには、どんな類のことをしなければならず、それをプログラミング言語はどんな風に解決しているのか、というイメージをつくっていくことをお奨めします。応用がききますから。応用がきくということは、どの言語をつかっても、プログラミングの色々な局面でどうすればいいかがわかるようになるということです。こういったことを理解するには、どの言語でプログラミングしても習得できるものだろうと思うんですが、Mopsでは他の言語よりも早くある程度の理解に到達できると思われるのです。ともかく、この一筋に賭けるというのじゃなくて、少し気持ちにゆとりを持ってやってみましょう。"他の言語も色々手を出したけど、どれもぱっとしない"という人も、もしかしたらMopsには向いているかもしれません(^^)。

Mopsを使うのは、趣味のためでしょう?楽しんだ者勝ちです。いや、お仕事に使えないわけじゃないですが。







最終更新:2019年01月01日 19:57