命令型プログラミング
命令型プログラミング(めいれいがたプログラミング、imperative programming)は、プログラムの状態 (計算機科学)を変化させるステートメントを基本文に用いる総称的なプログラミングパラダイムである。ステートメントではコマンド(命令文)が多用される。宣言型プログラミングと対をなしてのプログラミング言語の分類用語としても扱われている。宣言型の数学的性質に対して、命令型はノイマン型コンピュータ向けの計算機科学特有の性質である。このパラダイムは、手続き型、構造化、モジュラープログラミング、オブジェクト指向などを包括している。
ステートメント上のコマンドで状態は変化され、変化した状態の参照でステートメントの動作も変化することは副作用と呼ばれる。コマンドと副作用の存在によって命令型プログラミングは、各オペレータを状態の遷移と照らし合わせて解釈することになる。このことから命令型はhow a program operates(どう処理するか)と形容される。
宣言型プログラミングの基本文の式の方針は、コマンドと副作用を持たないことなので、そこでの参照透過な各オペレータは、その定義のままに把握できる。このことから宣言型はwhat a program accomplishes(なにを果たすか)と形容される。
宣言型・命令型・手続き型の違いを、商品代金計算に例えると以下のようになる。ここでは + がオペレータ(演算子・関数・手続き・ルーチン)である。特典ポイント5%と消費税10%のルールは計算式外部の状態(state)に記憶されている。
宣言型は、100円+200円の問いに、300円の答えを出す。状態は見ない。
命令型は、100円+200円の問いに、300円の答えを出して5%特典による15ポイントを状態に記憶させる。
手続き型は、100円+200円の問いに、状態からの消費税10%を加算して場合によっては以前の15ポイントを割り引いた315円の答えを出す。
宣言型は、+をただ数を足す計算にしており、当たり前に聞こえるがこれが数学的と言われる。declarative(宣言的)とは計算の平叙性を意味しており、オペレータの計算をその定義のままに把握できる。
命令型は、100+200の答えの、5%特典を計算式外部の状態に記憶させている。この計算式枠外の状態を変化させるという計算は、従来の数学には無いものなのでこれがimperative(命令的)と言われた。状態変化のコマンドを用いるだけの計算式も書ける。
手続き型は、100+200の答えを、状態内の消費税と照らし合わせて解釈して330にする。計算式枠外の状態を吟味しつつオペレータの計算を進めるのがprocedural(手続き的)と言われる。更にそれがその時の状態内のポイントの多さで315や305にもなる。 手続き型がしばしば、命令文を順次実行していくや記憶領域に代入して状態を変化させていくなどと説明されるのはこのためである。副作用の活用は、より小さなメモリ容量でのより効率的なプロセス拡充をもたらせたので、命令型パラダイムはノイマン型コンピュータプログラムの基本になった。
なお、プログラミング視点での手続き型は、命令型プログラムに手続きの定義と呼び出しの機能を加えて、構造性とモジュール性を備えさせたパラダイムを意味している。高水準言語の普及後はこの意味の方が一般的になった。
命令型に対する宣言型というプログラミング理論構図が重視され始めたのは1970年代からであり、副作用によるオペレータのブラックボックス化偏重への見直しがその動機になっている。副作用を前提にした命令型に対して、参照透過性を前提にしてオペレータのホワイトボックス化を重視しているのが宣言型である。
なお、冒頭の状態を見ないという宣言型の説明ではまともなプログラムも作れないように思えるが、宣言型では問いと答えに状態も含めてしまうという方法で、命令型と同等の表現を可能にしている。そこで用いられるのが部分構造論理由来の部分構造型システムや圏論由来のモナドであり、詳細は割愛するが参照透過性もそれで維持される。従って補正するとこうなる。
宣言型は、(100円&状態)+200円の問いに、引数状態からの消費税10%を加算して、返り値状態に特典15ポイントを収めた、(330円&状態)の答えを出す。
ほとんど全てのコンピュータのハードウェア実装は命令型である。ほぼ全てのコンピュータハードウェアは機械語を実行するよう設計されており、機械語は命令から構成される。このような低レベルから見た場合、プログラムの状態はメモリの内容によって定義され、文としては機械語の命令が相当する。高級な命令型言語は変数や他の複雑な構文を使用可能となっているが、基本的に同じパラダイムである。レシピやチェックリストはプログラムではないが、命令型プログラミングのスタイルに似たコンセプトである。それらのステップが命令であり、実世界が状態を保持している。命令型プログラミングの基本的考え方はハードウェアの実装に近く、概念的にもなじみ深いため、多くのコンピュータ言語が命令型のスタイルである。
代入文は一般にメモリ上のある位置に存在する情報への操作であり、結果を後で使用するためにメモリ上に格納する。高級命令型言語ではさらに複雑な式の評価が可能となっており、算術操作や関数評価の組み合わせによる式が可能で、その計算結果をメモリに格納する。ループ文は文の並びを繰り返し実行させる。ループは、事前に決められた回数だけ繰り返す場合と、指定された条件が変化するまで繰り返す場合がある。条件分岐文は、何らかの条件が成り立ったときだけ指定された文の並び(ブロック)を実行する。条件が成り立たない場合、そのブロックはスキップされ、その次の文から処理が続行される。無条件分岐文は制御をプログラム内の別の箇所に転送する。無条件分岐には、多くの言語にあるGoto文、サブプログラム、プロシージャ呼び出しなどがある。
最初の命令型言語はコンピュータ本来の機械語であった。1949年に機械コードをニーモニックに置き換えた低水準言語のアセンブラが登場した。機械語とアセンブラの命令は非常に単純であり、ハードウェアの実装は容易になっていたが、複雑なプログラムの作成は困難だった。1954年からIBMのジョン・バッカスが、初の高水準言語「FORTRAN」を開発した。FORTRANは機械語やアセンブラでの複雑なプログラム作成の困難さを克服するための言語であった。FORTRANはコンパイル式の手続き型言語であり、名前付きの変数、ニーモニックよりずっと複雑な式、サブプログラムといった命令型言語に共通の各種機能が利用可能であった。1958年から1960年代にかけて数学的アルゴリズムをより表現し易くする目的で手続き型言語「ALGOL」が開発された。手続きと制御フロー構文の導入で洗練されたALGOLは、バロースB5000などのコンピュータ用OS制作にも使われた。1959年から開発された事務処理用の「COBOL」と、1964年に制作された教育用の「BASIC」はどちらもソースコードを人間の可読性に合わせたテキスト寄りにした。1970年にはニクラウス・ヴィルトが開発した構造化言語「Pascal」が公開された。1972年にベル研究所のデニス・リッチーが開発した「C言語」が登場した。ヴィルトは1975年から80年代にかけてモジュラー言語「Modula」「Oberon」を設計している。1978年からアメリカ国防総省の要求でハネウェルのチームが新言語の策定を開始し、マルチパラダイム手続き型言語「Ada」が1983年に満を持して初回公開された。
1980年代になるとオブジェクト指向が急成長を遂げた。オブジェクト指向言語の多くは命令型のスタイルであるが、オブジェクトを扱う機能が追加されている。1967年から開発されていた初のオブジェクト指向言語「Simula」や、Simulaを参考にしてビャーネ・ストロヴストルップが1979年からC言語を拡張設計した「C++」がある。C++の登場は1983年で最初の実装は1985年である。1980年代後半から1990年代にかけてはオブジェクト指向のコンセプトを導入した命令型言語が次々と登場した。