1 手続きを用いた抽象化の構築

心が単純な考えについてその力を発揮する活動は、主に次の3つです。1. 単純な考えをひとつの合成物に組み合わせること。すべての複雑な考えはこれによってできています。2. 二番目は、単純なものでも複雑なものでも、二つの考えをひとつの場所に並べて置き、それらをひとつに結合することなしに同時に眺めることです。これによって、心は関係性についての考えを得ることができます。3. 三番目は、その考えの実在に伴うほかのすべての考えから、その考えを切り離すことです。これは抽象化と呼ばれ、これによってすべての一般概念というものはできています。

---John Locke, An Essay Concerning Human Understanding (1690)

私たちは、計算プロセス(computational process)について学ぼうとしています。計算プロセスというのは抽象的な存在で、コンピュータの中に生息しています。それらが進化するにつれ、プロセスはデータ(data)と呼ばれるまた別の抽象物を操作します。プロセスの進化は、プログラム(program)と呼ばれる規則のパターンによって指揮されています。プログラムを作るのは、プロセスを指揮するためです。事実上、私たちは呪文を使ってコンピュータの精霊に魔法をかけているのです。

計算プロセスは、魔法使いの言葉で言うと、精霊のようなものです。それは、見たり触れたりすることはできません。そもそも、物質によって作られていないのです。それでも、それはとてもリアルな存在です。計算プロセスは、知的な作業を行うことができます。質問に答えることができます。銀行のお金を支出したり、工場でロボットの腕を操作したりすることで、世界に影響を与えることもできます。私たちがプロセスに魔法をかけるのに使うプログラムとは、魔法使いの呪文のようなものです。それは難解で深遠なプログラミング言語(programming language)による記号的表現によって慎重に組み立てられ、プロセスに実行させたいタスクを指示します。

計算プロセスは、正しく動くコンピュータでは、プログラムを正確かつ精密に実行します。そのため、魔法使いの見習いのように、初心者プログラマは魔法のもたらす結果を理解し、予測することを学ばなければいけません。プログラムのほんの小さな間違い(普通、バグ(bug)やグリッチ(glitch)と呼ばれます)も、複雑な予期しない結果を引き起こすことがあるのです。

運のいいことに、プログラムを学ぶことは魔法を学ぶことに比べるとずっと安全です。私たちが扱う精霊は、都合のいいことに安全な方法で封じ込まれているからです。しかし、現実世界のプログラミングでは、注意力や専門知識や知恵が必要となります。例えば、CAD(コンピュータによる設計支援)プログラムの小さなバグが、飛行機やダムの破滅的な崩壊を引き起こしたり、産業ロボットの自己破壊を起こしたりするのです。

達人ソフトウェアエンジニアは、プログラムを構築する能力があり、結果となるプロセスが意図するタスクを実行してくれることにある程度自信を持つことができます。彼らは、システムの動作を前もって思い描くことができます。プログラムを構造化して、予期しない問題が破滅的な結果を引き起こさないようにする方法を知っています。そして、問題が起こってしまったときには、プログラムをデバッグ(debug)できます。うまく設計されたコンピュータシステムは、うまく設計された自動車や原子炉のように、モジュール化して設計されていて、部品が別々に作成、置き換え、デバッグできるようになっています。

Lispプログラミング

プロセスを記述するのには、適切な言語が必要です。この目的のために、私たちはプログラミング言語Lispを使うことにします。私たちの日々の考えが普通自然言語(英語やフランス語や日本語など)によって表現されるように、そして定量的な現象の記述が数学的記法によって表現されるように、私たちの手続き的な思考はLispによって表現されます。Lispは1950年代の後半に、再帰方程式(recursion equation)と呼ばれるある種の論理表現についての推論を定式化するものとして発明されたものです。この言語はJohn McCarthyにより考え出され、彼の論文“記号式の再帰方程式とそれらの機械による演算”(McCarthy 1960)に基づいています。

数学的な定式化としての生まれにもかかわらず、Lispは実用的なプログラミング言語です。Lispインタプリタ(interpreter)はLisp言語によって記述されたプロセスを実行する機械です。最初のLispインタプリタは、MIT研究所の人工知能部門の同僚、学生に手伝ってもらいながら、McCarthyが実装したものです。1Lispという名前はLISt Processing(リスト処理)の頭文字で、この言語は記号微分や代数式の積分のようなプログラミング上の問題に取り組むための記号操作能力を提供するために設計されたものです。この目的のために、アトムとリストとして知られる新しいデータオブジェクトを導入しています。この特徴が、Lispがその時代のほかの言語から際立ったものとなっている最大の特徴です。

Lispは、一致協力した設計の努力によってできたものではありません。ユーザーの必要とすることや実用的な実装の検討事項に応えるものとして、実験的なやり方で非公式に進化してきたものです。Lispの非公式な進化は何年も続き、Lispユーザーのコミュニティは伝統的に、この言語の“公式な”定義を公布しようとすることに抵抗してきました。この進化が言語の柔軟性と元々のエレガントさと組み合わさって、広く使われている言語としては二番目に古い(これより古いのはFortranだけです)言語であるLispはずっと適応を続け、プログラム設計についての最新の考え方を含むようになっています。そのため、今ではLispは方言の集まりで、元々の特徴の多くを共通して持ちながらも、それぞれ大きく違うこともあるものとなっています。この本で使う方言はSchemeと呼ばれるものです。2

実験的な性質を持ち、また記号操作に重点を置いているため、初期のLispは数値計算については、非常に非効率的なものでした。少なくとも、Fortranと比べるとそうでした。しかし、年を経るにつれ、プログラムを機械語に変換して、十分効率的に数値計算を実行できるようにするLispコンパイラが開発されるようになりました。それに、特別な応用に対しては、Lispは非常に有効に使われています。3今でもLispは、絶望的に非効率的だという昔からの評判を乗り越えられていませんが、今ではLispは効率が最優先事項ではない数多くの応用に使われています。例えば、LispはOSのシェル言語や、エディタやCADシステムの拡張言語として選ばれるものになっています。

Lispがメインストリームの言語でないとしたら、なぜそれをプログラミングの考察のための枠組みとして使うのでしょうか。それは、この言語が独特な特徴を持っているため、プログラミングの重要な構成とデータ構造について学び、それらを支える言語的特性と結びつけるのにとても便利な媒体だからです。これらの特性の中でも最も意義深いものは、プロセスのLispによる記述(これは手続き(procedure)と呼ばれます)が、それ自身Lispのデータとして表され、操作できるということです。これが重要なのは、“受動的な”データと“能動的な”プロセスという伝統的な区別を曖昧にする能力を使った強力なプログラム設計のテクニックが存在するからです。これから見ていくように、Lispは手続きをデータとして扱う柔軟性のおかげで、これらのテクニックを探求するのに最も便利な言語のひとつになっています。手続きをデータとして表現する能力は、コンピュータ言語を支えるインタプリタやコンパイラのような、ほかのプログラムをデータとして操作しなければならないプログラムを書くのにも、Lispをとても優れたものにしています。それに、こういったことを考えに入れなくても、Lispでのプログラミングは本当に楽しいのです。


1. Lisp 1 Programmer's Manualは1960年に登場し、Lisp 1.5 Programmer's Manual (McCarthy et al. 1965)は1962年に出版されました。Lispの初期の歴史は、McCarthy 1978で説明されています。
2. 1970年代に主要なLispプログラムの大部分に用いられた2つの方言は、MITのプロジェクトMACで開発されたMacLisp (Moon 1978; Pitman 1983)と、Bolt Beranek and Newman Inc.とXerox Palo Alto研究センターで開発されたInterlisp (Teitelman 1974)でした。Portable Standard Lisp (Hearn 1969;Griss 1981)、異なるマシンの間で簡単に移植できるように設計されたLisp方言です。MacLispは、カリフォルニア大学バークレー校で開発されたFranz Lispや、MIT人工知能研究所がLispをとても効率よく実行できるよう設計した特定目的プロセッサ(処理器)に基づくZetalisp (Moon and Weinreb 1981)といった、いくつかの下位方言を生みました。この本で使用するLisp方言はSheme(Steele and Sussman 1975)と呼ばれ、1975年にMIT人工知能研究所のGuy Lewis Steele Jr.とGerald Jay Sussmanにより開発され、のちにMITで教育目的で再実装されたものです。Common Lisp方言(Steele 1982, Steele 1990)は、初期のLisp方言の機能を組み合わせ、Lispの業界標準を作るためにLispコミュニティにより開発されました。Common Lispは1994年にANSI標準(ANSI 1994)になりました。
3. そのような特別な応用のひとつは、自然科学的に重要な計算のブレークスルー---太陽系の運動についての積分の精度を二桁近く上げ、太陽系の力学はカオス的であることを示した---でした。この計算は、新しい積分アルゴリズム、専用コンパイラ、そして専用コンピュータによるものですが、これらはすべてLispによって書かれたソフトウェアツールの助けによって実装されたものです。(Abelson et al. 1992; Sussman and Wisdom 1992)

results matching ""

    No results matching ""