宣言的プログラミングの「宣言的」って?

疑問

関数型言語を取り扱う書籍や記事を読んでいると、しばしば「宣言的」なる単語が飛び出してくる。どうやら、関数型言語で大事にされる概念らしい。
ところが意味を調べるとよく分からない。例えばWikipedia曰く、宣言的には2つの意味があるらしいのだが……

純粋関数型言語/論理プログラミング言語/制約プログラミング言語で書かれたプログラムを「宣言型」と称する。この立場では、「宣言型プログラミング」とはそのようなプログラミング言語のグループ全体の総称であり、命令型言語と対立する概念である。
宣言型プログラミング - Wikipedia

ある出力を得るにあたってそれを作成する方法ではなく、出力の性質を記述することを「宣言型」と称する。例えば、HTMLは、ページがどう見えるかを記述するものであるため、宣言的である。HTML はタイトルやフォントやテキストや画像を指定するが、具体的にコンピュータの画面にどう出力するかは記述しない。この手法は、FORTRANC言語Javaなどといった命令型プログラミング言語とは全く異なる。
宣言型プログラミング - Wikipedia

前者はまあいいとして、後者は何がなんだか……。分かるような、分からないような。単に抽象度を高めたってだけではないの?

解決?

そんなわけで頭の中のモヤモヤが残ったままだったのだが、最近読んだ『コンピュータプログラミングの概念・技法・モデル』に、ようやく納得できる解説を発見した。ちょっと長いのだが、関連する部分を全文転載したいと思う。

状態なしプログラミングと状態ありプログラミングはそれぞれ、宣言的プログラミングと命令的プログラミングといわれることが多い。後者は正しい用語とはいえないが、伝統的に使われている。宣言的プログラミングを文字通りに取れば、宣言するだけのプログラミングである。すなわち、何が必要かをいって、それをどのように達成するかはシステムに任せることである。命令的プログラミングを文字通りに取れば、コマンドを与えることである。すなわち、あることをするのに、どのようにするかを伝えることである。

本当の問題は、「宣言的」が絶対的性質ではなく、程度を表していることである。1950年代末期に開発されたFortran言語は、数式を数学的記法に似た構文で書くことを許した最初の主流言語であった。アセンブリ言語に比べれば断然宣言的である! コンピュータにI+Jが必要であることを告げればよく、IとJがメモリのどこに格納されているか、また、それらを取り出して加えるのにどういうマシン命令が必要か、ということを記述する必要が無い。この相対的な意味において、言語は年とともに宣言性の度合いを増している。

※それぞれの引用囲みは、上のWikiepdiaの引用に対応する。

上で「抽象度を高めた記法のこと?」と推測していたのは、そう間違いでもなかったらしい。

プログラミングの歴史をながめると、まず機械語を直接取り扱わずに済むようにニーモニックが生まれたそうな。それからアセンブリ命令がifなどの基本的な命令になり、gotoの大部分は条件付きループに書き換えられた。ループをさらに抽象化してイテレータが生まれた。
制御構文まわりの一部分だけを見ても、なるほど確かにより細部が隠されている。

この進化の流れが行き着くのはどこなのだろう? というテーマはPaul Grahamの有名なエッセイThe Hundred-Year Languageなどで扱われている。

プログラミング言語の未来に思いを馳せるのも、なかなか面白い。

まとめ

  • 「宣言的である」とは、具体的な手順、すなわち実装の細部やアルゴリズムを隠すこと
  • 宣言性に絶対的な尺度や定義は無い。あくまで相対的な意味で使われる(e.g.アセンブリ言語に比べればFortranは宣言的である)