MCL(64)

インデックスに戻る

前のMCLへ  次のMCLへ

▼ My Computer Life (64)

64. プログラミング言語(後編)

 という事で、プログラミング言語の後編。

 前回は、FORTRAN系、COBOL系、ALGOL系の解説をした。今回は、ちょっと風変わりな言語から紹介してみる。

 まずは、子供向けの、グラフィカルな趣向のLOGO(1967)だ。
 LOGOは、子供が簡単に、プログラムの仕組みを学べるように作られている。タートルグラフィックという仕組みを使い、タートルと呼ばれるカーソルに指示を与え、画面に線を引いたりできる。角度や長さを与え、図形を作図し、またそれをプログラムの一部品として扱う事で、複雑な図形をプログラムとして組み立てる事ができる。再起呼び出しも出来るので、フラクタル(自己相似形)な画像も作れたりする。
 処理系は少なかったのだが、子供向けに作られたとあって、地元の図書館なども解説書が多数あった。私もそれを読んで、色々仕組みを理解したりした。
 なお、このLOGOの言語仕様が、実は後述するオブジェクト指向に影響を与え、Smalltalkの始祖的存在にもなった。

 またこれも変わった言語で、Prolog(1972)がある。Programming in Logicの略で、その名の通り論理学的な要請から作られた言語だ。
 この言語では、例えば「AならばB」、「BならばC」というような「命題」を、プログラムとして定義しておく。その上で、「AならばCであるか?」のような疑問を発した時に、プログラムが「然り」という答えを返す、という形になる。これは有名な三段論法である。もちろん三段論法以外にも推論方法はいくつもある。
 このように、他言語のプログラムと大きく違って、推論ベースで処理が進むのが特徴だ。この特徴を活かして、人工知能や、自然言語の解析などに使われている。
 私の感覚では、良くハリウッドの映画などで、主人公がコンピュータに「この事故の結果人類は滅亡するか?」などと質問を入力すると、なんか画面がピコピコとなって、「YES」とか表示されたりするけども、それは処理系としてはPrologのような感じなのかな、と思っている(実際には、言語がどうこう言うより大規模推論エンジンが積まれているのだろうけど、まあ映画の話を真剣に考えても仕方ないか)。

 今まで語ってきた、FORTRANやCOBOLのような純粋なプログラム用途の言語とは別の流れで、スクリプト言語というジャンルがある。当初は貧弱な言語仕様だったが、後にはきちんとしたプログラミング言語としての体裁を備え、特に非スクリプト言語との大きな差異はない。
 スクリプト言語は、元々はバッチファイルやシェルスクリプトと言った、単にシェルのコマンドなどを連続して実行する仕組みから発展している。そして、AWK(1977)において、ややプログラミング言語に近くなった。AWKはUNIXのツールの一つで、テキストファイルの置換や検査などに使われるのだが、細かい置換パターンを実現するために、プログラム的な要素が加わっている。従って、AWKはツールとプログラミング環境の中間のような扱いをされている。
 そのAWKから発展し、プログラミング言語として確立したのが、Perl(1987)だ。これで「パール」と読み、Pearl(真珠)と同じ発音だ。元々Pearlとつけたかったが、すでに同名の環境があったため、一文字抜いたという話だ。
 PerlはC言語の影響を強く受けた、関数型の言語であるが、コンパイラを要するC言語と異なり、インタプリタ言語である。テキストファイルであるPerlスクリプトを読んで、その場で実行していく。
 Perlの特徴は、とにかく「なんでも許容する」である。変数も無宣言で行けるし、数値型でも文字型でも代入できる。処理の多くに様々な記法が許容され、イメージとしては「大体あってれば動く」ようなアバウトな作りになっている。そのアバウトさゆえ、妙な不具合を起こす事もあるが、エラーで止まるケースが少ないので、様々な場面で好まれている。特に、インターネット(WWW)における、サーバ側のクライアント向け処理としては、大変広く普及している。
 Perlと良く似たスクリプト系の言語としては、Perlとは逆に記法を一つに定めて、同様の処理なら大体皆同じコードを書くようになる特徴を持ったPython(1990)や、ウェブブラウザ普及後に、HTML生成用の目的で作られたPHP(1995)、珍しく日本人が作り上げた言語であるRuby(1995)などがある。

 他の有名言語となると、PL/I(1963)があるが、これは大型機用なので、割愛しよう。

 さて、現在主流となるパラダイムとして、オブジェクト指向言語というものがある。
 ALGOLに始まってC言語に続く、構造化という考え方が、従来のプログラムのコード量・作業量の増大によって要求されたように、時代が進んでその構造化言語でもまかないきれない変化によって、オブジェクト指向という考え方が自然と要請されていった。

 何をもってオブジェクト指向と呼ぶかはかなり難しいが、かいつまんで説明してみる。
 プログラムというものは、大きく「手続き」と「データ」に分かれる。何かを計算するプログラムであれば、3だの4だの、具体的な数値が「データ」であり、それを足したり引いたりするのが「手続き」である。
 そして、オブジェクト指向言語以前は、この手続きの方が重要であった。

 例えを書いてみよう。
 学校、というプログラムがあったとする。ここで先生が、生徒一人一人の用紙に、出席番号と名前を書く、という処理を行いたいとする。
 この時、従来の手続き重視型のプログラムの場合、仮に生徒が40人いるとすると、先生が1人目の用紙を取り出して出席番号と名前を書き、2人目の用紙に出席番号と名前を書き…を40人目まで行うわけだ。
 それに対し、オブジェクト指向言語のケースでは、先生はただ単に40人の生徒に対し、「自分の用紙に自分の出席番号と名前を書くように」というメッセージを送るだけである。実際に書き込む処理は、それぞれの生徒に任される。

 上記の二つの手法はそれぞれ長所と短所があり、どちらかが全て優れているというものでもない。また、計算量等は大して変わらない。一般的には、オブジェクト指向言語の方が処理がやや複雑になり、時間がかかる。
 では、オブジェクト指向言語とその他の違いはどこにあるかと言うと、一言で言えば、どこにコードを書くかが異なるのである。そして、オブジェクト指向言語の場合、それが散らばりにくいのが利点なのである。

 例えば、上記の学校プログラムの例で話そう。この生徒のデータに、更に身長と体重という概念を入れなければいけない、という変更があったとしよう。先生が全部やる、手続き型のプログラムの場合、身長体重の概念を組み込むと、その処理は一般にプログラムのあちこちに書かないといけなくなる。先生が何か生徒のデータをいじる時に、身長と体重の処理を組み込まなければいけなくなる。先生の側にコードを書くからそうなるのだ。それに対しオブジェクト指向言語の場合、データを管理しているのは生徒なので、身長体重の管理は生徒の側に書けばいい。身長体重というデータを所有しているのは生徒自身なのだから、生徒の側に処理を書くのは自然な流れである。
 このように、それまで単なる数値や、文字列でしかなかった「データ」に、それを操作する手続きをセットでくっつけてしまったのだ。この、データとそれに付随する手続きのセットを、オブジェクトと呼ぶ。先ほどの例えで言うと、生徒=オブジェクトである。
 従来の手続き型言語では、生徒=名前、出席番号などのデータで、先生=それを扱う手続き全般である。それがオブジェクト指向言語では、生徒は名前、出席番号などのデータと、そのデータを読み書きしたり処理を加えたりする手続きも含むように拡張されているのだ。
 このように、データという概念を拡張して、それを扱う手続きを含めた概念としてのオブジェクトを、プログラム言語の要素として取り入れたのが、オブジェクト指向言語である。もっとも、今の説明ではオブジェクト指向の利点の一つをクローズアップしただけであり、実際の定義ではもう少し色々ある。少しだけ説明すると、「生徒が具体的にどのようにデータをいじるか先生は関与しなくてよい(カプセル化)」「違う種類の生徒を作る時に、雛形を引き継いで生成できる(継承)」「どの種類の生徒に仕事をさせるか、実行時に決められる(多態性)」などである。これらは必ずしもオブジェクト指向特有の仕様ではないが、大体セットになっている。

 もっとも初期のオブジェクト指向言語と言えば、Simula(1967)になる。なんとC言語よりも古い。ALGOLの流れを直接ひいており、クラスや継承等、のちのち使われる概念をすでに実装していた。
 完成されたオブジェクト指向言語としては、Smalltalk(1980)が挙げられる。
 Smalltalkは、「オブジェクト指向」という言葉、概念を作ったアラン・ケイの設計した言語である。アラン・ケイの言うオブジェクト指向とは、上に書いた、処理を持つデータとしての「オブジェクト」と、そのオブジェクトに対する指示・情報である「メッセージ」を組み合わせた、新しいプログラミングスタイルの事である。メッセージの概念はSmalltalkでは強く表現され、オブジェクト指向言語という枠組みの中では、Smalltalkは特別に「メッセージ指向」と名乗っても良いほどである。
 なお、冒頭にも書いたが、SmalltalkはLOGOの影響を受けている。オブジェクトという概念が、グラフィック表示を得意とするLOGOから派生したというのも、面白い。

 そして、現在もっとも普及しているオブジェクト指向言語であり、またC言語の後継言語であるC++(1985)が、それらの流れを受け継いで誕生した。オブジェクト指向という概念自体は、Smalltalkの時に発明されたのだが、C++はそれより古いSimulaに大きく影響を受けている。Simula自体が、ALGOL系にクラスの概念を乗せたものなので、同じくALGOL系のC言語の仕様を受け継いだC++がそちらに似ているのも、道理である。従って、Smalltalk特有のメッセージの概念は、C++にはあまりない。

 C++は、言語仕様としてC言語を全て受け継ぎ、ソースレベルでの上位互換性を保った上で、継承、多態性、オーバーロードなどの概念が導入されている。そしてまた、オブジェクト指向とは少々離れるが、言語仕様の拡張として、例外処理やテンプレートなどが付け加えられている。
 前編の冒頭で書いたが、クラスの概念等は、非常に楽しい物に思えた。再利用性があり、部品を寄せ集めて作るような、おもちゃ感覚があったからだ。しかし、C++の言語仕様は、かなり複雑だ。きつい言い方をすれば、汚い。
 それは、一つは複雑な事、つまりオブジェクト指向の実装を、やれる限りやろうとしている事に起因している。そして更に、C言語の上位互換性を保つために、元々のC言語の文法を出来るだけ崩さないようにしているのも問題だ。そのため、記述の仕方もかなりトリッキーである。
 要は、とびきり小さい言語仕様だった、シンプルなC言語の上にかぶせる形で、かなり大規模な言語仕様であるC++を実装しているので、色々とガタガタになっているのだ。
 それでもまだ、大規模開発では主流の言語として、現在も使われている。

 オブジェクト指向言語として、C++の後継を目指す言語はいくつかある。
 その一つが、Java(1995)だ。地名や紅茶の名前としてのJavaは、日本では「ジャワ」と読むが、言語であるこちらは英語読みで「ジャバ」(あるいはジャヴァ)と発音される。
 Javaは、言語の構文としてはC言語及びC++にそっくりである。いくつかの違いを除けば、ほとんどソースレベルで移植可能なくらいである。
 その中で、一番の大きな違いと言えば、Javaは中間コードを生成するという事だろうか。C及びC++は、コンパイラがターゲットマシンのネイティブな機械語コードを生成する。それに対し、Javaコンパイラは中間コードしか生成しない。これを実行するために、Javaは仮想機械(JavaVM)を必要とする。このJavaVMが、各ターゲットマシンにおける実行を可能にするのだ。
 従って、Javaコンパイラとそれが吐き出す中間コードまでは、どの環境でも互換性がある。コンパイラが環境に依存しないのだ。環境に依存するのは、JavaVMである。そのため、互換性が高い。しかし引き換えに、実行速度そのものはC/C++より落ちる。
 その他の違いとして、C++で採用しているnew/deleteモデルは使用せず、ガベージコレクションによる自動削除を行っている事(これはJavaVMが実行しているから可能とも言える)、明確なポインタ表現を持たない事などが挙げられる。
 全体的に、簡素化したC++という作りになっていて、次世代はJavaだという空気に持っていこうとしている雰囲気が、インターネット界隈にあふれている時期があった。私自身は、その風潮は疑問視している。

 その他には、C++とは別ルートで、オブジェクト指向型C言語として作られたObjective-C(1983)や、Javaと同じく簡素化したC++を目指した、マイクロソフトのC#(2000)、より洗練されたC言語として開発されたD(1999)などがある。

 ああ、プログラミング言語についてはいくら語っても語りきれないけど、楽しいな、色々。
 昔、Cマガジンで、様々な言語について一つずつ紹介する連載があったけど、すごく面白かった。有名な言語から、珍言語まで色々あって。ラムダ式とか、遅延評価戦略とか、その記事で詳しくなったな…。あそこだけ単行本化されてないかな。
 ちょっと予定外に長くなっちゃったけど、大体このへんにしとこうか。まだまだ書き足りないけど、一応満足したし!


前のMCLへ  次のMCLへ

戻る

TOM 2011