2004年度前期 IT教育基礎論特論B
コンピュータプログラムのためのプログラミング言語の概要を知るとともに、 プログラミング言語の種別について学習する。
コンピュータは、数値計算やデータ解析など、様々な処理が可能である。 そのために、コンピュータで処理する内容は予め決められておらず、 目的に応じて自由に定義することができる。 反面、コンピュータを利用して何をするかを定義しなければ、 何もすることができない。
コンピュータを利用し、何らかの処理を行う場合、 その処理に必要な内容を具体的に定義する必要がある。 コンピュータは、この定義に基づき実際の処理を行う。 コンピュータによる処理内容を定義したものを コンピュータプログラム(もしくは単にプログラム)と呼ぶ。 また、このプログラムを定義することをプログラミングと呼び、 プログラムを定義し、記述する人のことをプログラマと呼ぶ。
プログラミング言語は、 コンピュータプログラムを定義するための言葉、 すなわち、コンピュータで処理したい内容を コンピュータに伝えるための道具として定義された、人工言語のひとつである。
プログラミング言語では、 コンピュータへのデータの入力方法、 入力されたデータによる計算や比較方法、得られた結果の出力方法などや、 これらをどのような条件でどの順番で行うか、 また必要であれば、これに伴うハードウェアの制御方法などを定義する。
またプログラミング言語は、 自然言語が思考の道具であると同様、 単に人がコンピュータに処理内容を伝えるためだけの道具ではなく、 なんらかの処理をどのように行うか、 なんらかの問題を具体的にどのように解くかを考える、 いわば思考のための道具でもある。
計算やデータ解析など、コンピュータを利用して何らかの処理を行うためには、 コンピュータ上で提供される単純な計算や制御機能を矛盾性、あいまい性なく、 正確に組み合わせ、目的の処理を実現する必要がある。 言い換えれば、解決しようとする物事を分解し、 基本的な意味の論理的な関係を定義できなければならない。 その枠組みを与えるのがプログラミング言語である。 コンピュータプログラムを記述するためには、 プログラミング言語で物事を考えられるようになるべき!?
プログラミング言語には様々な種類があり、その目的や機能が大きく異なる。 ここでは、その抽象度、実行形式、記述形式のそれぞれに着目し、 プログラミング言語を分類する。
プログラミング言語は、その抽象度により、 低級言語と高級言語に分類することができる。 ここでいう抽象度とは、 対象とするコンピュータシステムのハードウェアに依存し、 個々のシステムのアーキテクチャに併せたプログラムを記述しなければならないか、 それとも、基本的な機能を抽象化し、 システムに依存しないプログラムの記述が可能であるかどうかを示す。 低級言語と高級言語の例を表1に示す。
アセンブリ言語 |
|
FORTRAN, BASIC, COBOL, Pascal, C言語, PL/I, LISP, Scheme, ML, Prolog, C++, Smalltalk, Java, C#, PHP, Perl, Tcl, ... |
一般に、低級言語には機械語とアセンブリ言語の2種類がある。
機械語とは、コンピュータシステムのCPUが持つ基本機能と1対1に対応し、 CPUが直接実行可能な2進数で表現された(2進数を16進数で表現していることが多い) プログラミング言語であり、CPUの種類だけ機械語の種類がある。 CPUが持つ基本機能とは、レジスタへのメモリ上の値の取得、 レジスタからメモリへの値の書き出し、レジスタに対する演算の実行、 メモリ上の実行位置の変更などである。 CPUが直接実行することができるため、高速なプログラムの実行ができる反面、 人がこれを見ても、何が書かれているかほとんど理解できない (極まれに、理解できる変な人もいる)。
アセンブリ言語は、機械語を人が見てある程度理解できるよう、 簡単なアルファベットの語句に置き換えたものであり、 機械語とほぼ1対1に対応する。 アセンブリ言語によっては、記述性、可読性を高めるために、 簡単なマクロ等を利用できるものもある。 アセンブリ言語は、アセンブラと呼ばれるソフトウェアにより 機械語に変換することができ、 低級言語によりプログラムを書く必要がある場合は、 通常、アセンブリ言語が利用される。 アセンブリ言語で記述されたプログラムは、 プログラムを実行する前にコンピュータが実行可能な機械語に変換する必要があり、 この変換のことをアセンブルと呼ぶ。 また、この変換を行うためのソフトウェアをアセンブラと呼ぶ。
機械語やアセンブリ言語などの低級言語は、 その高速な実効やハードウェアの直接操作が可能であり、 ゲームプログラムなど高速性を要求されるようなプログラムの一部や、 ハードウェア制御のためのドライバの一部の記述などに利用される。 ただし、現在は、コンピュータそのものの性能の向上や、 後述するコンパイラの性能の向上により、 特殊な場合を除いて一般のプログラマが利用することはほとんどない。
低級言語が、コンピュータが直接実行可能なコード、 もしくはこれとほぼ1対1に対応しているのに対し、 高級言語は、高いレベルでの抽象化を行うことにより プログラム全体像の把握によるトップダウン的なプログラムの開発や、 プログラムのモジュール化による再利用性の向上を行い、 より、人の思考に近い形での効率的なプログラミングを可能とする プログラミング言語である。
すなわち、低級言語が、 CPU提供する最も基本的な機能を扱わなければならないのに対し、 高級言語では、それなりに意味のある形でプログラムを記述することができ、 記述されたプログラムの内容も比較的理解しやすい形となる。 また、抽象化を行うための枠組みを与えることにより、 単にコンピュータの制御を行うだけでなく、 人が物事を考えるための道具としても利用される。
ただし、高級言語には、実行形式やプログラミングパラダイムの異なる、 多様なプログラミング言語があり、それぞれ特色がある。 また、高級言語の場合、一口に高級言語と言っても、その抽象度は大きく異なる。
高級言語の場合、 人が理解しやすい形でプログラムが記述されるため、 これをコンピュータが直接実行することはできない。 高級言語で記述されたプログラムをコンピュータで実行するためには、 そのプログラムをコンピュータが理解できる形、 すなわち機械語に翻訳する必要がある。 このとき、その翻訳をいつ行うかによって、 大きくわけて2種類の実行形式がある。
記述されたプログラムを実行する前に、 予め翻訳しておく実行形式のプログラミング言語を コンパイル型言語と呼ぶ。 コンパイル型言語では、 コンパイラと呼ばれるソフトウェアで、 記述されたプログラムを特定のコンピュータ用の 機械語に翻訳したもの(オブジェクトコード)を作成し (これをコンパイルと呼ぶ)、 実行可能ファイルとして保存しておき、 プログラムを実行する際には、この実行可能ファイルを実行する。
コンパイラ型言語では、プログラムに変更を加えるたびに、 毎回コンパイルをし直す必要があるが、 コンパイルされた結果である、 実行可能ファイルに記録されたオブジェクトコードは、 コンピュータが直接実行することが可能である。
これに対し、プログラムを実行する際に、 逐次翻訳を行いながら実行する形式のプログラミング言語を インタプリタ型言語と呼ぶ。 インタプリタ型言語では、 インタプリタと呼ばれるソフトウェアが 記述されたプログラムを1命令づつ読み込み、 対応する機能に翻訳し、実行する。
インタプリタ型言語は、 記述されたプログラムの翻訳を行いながら実行する必要があるが、 コンパイルという作業が必要なく、 そのプログラムは特定のコンピュータに依存せず、 また、プログラムを対話的に実行することができる。
なお、図1に示すように、 コンパイル型言語とインタプリタ型言語の中間に位置するものとして、 機械語への翻訳の際に時間のかかる字句解析を 予め行っておくバイトコンパイル型言語や、 コンパイルにより特定のコンピュータアーキテクチャに依存しない 仮想的なコンピュータシステム用のオブジェクトコードを生成し、 これを具体的なコンピュータシステム用に変換しながら実行する バーチャルマシン型言語などもある。
計算モデルとは、コンピュータの中でプログラムがどのように 計算(実行)されるか、その実行方法のモデルであり、 またプログラミングパラダイムとは、 どのようにプログラムを記述するか、その記述方法を定めた枠組みである。
コンピュータが直接実行できる機械語は、 ハードウェアにより提供される基本的な機能と1対1に対応しており、 そのままでは人にとって理解が困難である。 これに対し高級言語は、人が見て理解し易く、 また一度記述したプログラムの再利用性を上げることにより、 プログラムの生産性を向上することを目的としている。 このような高級言語を実現するためには、 プログラムをどのように記述するか、その記述のための枠組みを定義し、 また、記述されたプログラムをどのように実行するかを定義する必要がある。 この実行方法を形式化したものを計算モデルと呼び、 また、なんらかの計算モデルに基づき、 プログラムをどのように記述するか、 その記述方法の枠組みをプログラミングパラダイムと呼ぶ。
計算モデルは、コンピュータの中でプログラムがどのように解釈、実行され、 これによりどのようにデータを処理し、 その結果として、どのような出力を行うかを体系化したモデルであり、 一般に、コンピュータによるプログラムの実行のことを計算と呼ぶため、 その実行方法のモデルを計算モデルとよぶ。 通常、コンピュータによる計算方法は多様な視点から捉えることができ、 関数モデル、論理モデル、書き換えモデルなど、 さまざまな計算モデルが提案されている。 現在提案されている主な計算モデルを表2に示す。
モデル | 概要 |
---|---|
機械モデル |
チューリングマシーン等の仮想的なコンピュータシステムにおける 状態遷移をモデル化したもの。 |
関数モデル |
コンピュータによる計算を簡単な関数の組み合わせとして捉える。 λ式とその簡約により定義できる。 |
論理モデル | 論理式を定義し、その真偽や証明を求める。 |
関数モデルや論理モデルで与えられた表現を変形し、 意味の自明な表現を導く。 |
|
代数モデル |
処理対象となるデータを集合として捉え、
集合に定義された演算により、 新たな集合の生成や要素の特定を行う。 |
これに対しプログラミングパラダイムは、 何らかの計算モデルに基づき、 どのようにプログラムを記述するか、その記述方法の概念をいう。 プログラミングパラダイムにの詳細に関しては後述する。
プログラミングパラダイムとは、 1つないし複数の何らかの計算モデルに基づき、 どのようにプログラムを記述するかを定めたものである。 コンピュータにより何らかの処理を行うためにプログラムを記述する場合、 コンピュータで提供される基本的な機能を組み合わせ、 具体的な処理内容を定義する。 このとき、そのプログラムの記述方法は以下の要素からなる。
すなわち、プログラミングパラダイムとは、 プログラミング言語により提供される基本式、組み合わせ法、抽象化法の3つが、 どのような形式になるかを定義するものである。
プログラミングパラダイムは、 様々な計算モデルに基づき定義され、 また、基本式、組み合わせ法、抽象化法も多様な種類があり、 これに基づくプログラミング言語も多様である。 以下、その主なものを述べる。
関数型プログラミング言語における基本式は、 そのプログラミング言語において予め定義されている関数であり、 この関数を組み合わせることによって、複雑な計算を行う。 また、関数を組み合わせたものに名前をつけることによって、 新たな関数を定義し、利用することができる。
論理型プログラミング言語の基本式は、 事実および規則を定義する述語である。 この規則を組み合わせることにより、 問い合わせられた内容の真偽を求めることができる。 このとき、関係する2つの規則が定義されれば、 自動的に、あらたな規則が生成されることとなる。 例えば、「AならばB」、「BならばC」という規則が定義されれば、 結果的に「AならばC」という新たな規則が定義される。
手続き型プログラミング言語では、 そのプログラミング言語で提供される基本的な手続きを順番に並べて プログラムを記述する。 すなわち、手続き型プログラミング言語の基本式は手続きであり、 その組み合わせ法は、手続きの列となる。 また、この手続きの列に名前をつけて、 新たな手続きとして定義することができる。
オブジェクト指向プログラミング言語の基本式はオブジェクトである、 オブジェクト間の相互作用を定義することにより、プログラムを記述する。 オブジェクトとは、手続き(メソッド)とデータ(属性)を カプセル化したものであり、 このオブジェクトに対しメッセージを送ると、 対応するメソッドを実行する。 あるオブジェクトのメソッド中に 他のオブジェクトへのメッセージ送信を記述することで、 オブジェクト間の相互作用を定義することができる。 すなわち、オブジェクト指向プログラミング言語における組み合わせ法は、 オブジェクト間のメッセージ交換により実現される。 このとき、既存オブジェクトのメソッドや属性の一部を変更した 新しいオブジェクトを定義することや、 新たなメソッドと属性を持つ新規のオブジェクトを定義することができる。
エージェント指向プログラミング言語は、現在研究が進められている 新しいプログラミングパラダイムに基づくプログラミング言語であり、 プログラミングパラダイムのその具体的な厳密な定義はまだないが、 その基本式がエージェントである。 エージェントとは、一般的には「自律的なオブジェクト」であると言われる。 すなわち、オブジェクトが他のオブジェクトからメッセージを受け取って 初めてそのメソッドを実行するのに対し、 エージェントは、他のオブジェクトの状態や周りの環境の変化に応じて、 自発的にメソッドを実行する点が異なる。
スクリプト型プログラミング言語は、特定の用途のために、 簡単な命令を組み合わせてプログラムを記述することのできる プログラミング言語である。 スクリプト型プログラミングパラダイムというものがあるわけではなく、 多くは手続き型のプログラミングパラダイムに基づいているが、 オブジェクト指向プログラミングパラダイムに基づく プログラムの記述ができるものも多い。
また現在、これらのプログラミングパラダイムに基づき、 多様な高級言語が開発されている。 各プログラミングパラダイムおよびプログラミング言語の例を表3に示す。 ただし、1つのプログラミング言語が、 1つのプログラミングパラダイムのみの基づいていないことも多く、 単純に、あるプログラミング言語のプログラミングパラダイムが どれであるとは言い切れない場合もある。
パラダイム |
基本式 | 組み合わせ法 | 抽象化法 | プログラミング言語 |
---|---|---|---|---|
関数型 | 関数 | 関数の入れ子 | 新規関数の定義 | ML |
論理型 | 述語 (事実および規則) |
規則の組み合わせ | 新規規則の生成 | Prolog |
手続き型 | 手続き | 手続きの列 | 手続き列への名前定義 |
FORTRAN, BASIC, COBOL, LISP, Pascal, C言語, PL/I |
オブジェクト | オブジェクト間 メッセージ交換 |
新規クラスの生成 | Smalltalk, C++, Java, C# |
|
エージェント | エージェント間 メッセージ交換 |
新規クラスの生成 | - | |
命令 | 命令の列 | 命令列への名前定義等 | Perl, Tcl, PHP |
インタプリタ型言語では、コンパイルという作業が不必要である代わりに、 そのプログラムを実行するためには、インタプリタを使用し、 逐次、翻訳を行いながら実行する必要があり、 また、コンパイラ型言語では、コンパイルが必要である代わりに、 コンパイルの結果生成されたオブジェクトコードを コンピュータが直接実行することができる。
これら、インタプリタ型言語およびコンパイラ型言語の特徴に基づき、 両者の利点、欠点、用途を述べよ。
これまでのプログラミングは、 手続き型プログラミングパラダイムに基づくプログラミング言語を 利用することが多かった。 これに対し近年は、オブジェクト指向プログラミングパラダイムに基づく、 オブジェクト指向プログラミング言語によるプログラミングも 多く利用されるようになってきている。
手続き型プログラミングパラダイムおよび オブジェクト指向プログラミングパラダイムのそれぞれを調べ、 その特徴、利点、欠点、用途をまとめよ。