Educators, generals, dieticians, psychologists, and parents program.
Armies, students, and some societies are programmed. An assault on
large problems employs a succession of programs, most of which spring
into existence en route. These programs are rife with issues that
appear to be particular to the problem at hand. To appreciate
programming as an intellectual activity in its own right you must turn
to computer programming; you must read and write computer
programs—many of them. It doesn't matter much what the programs are
about or what applications they serve. What does matter is how well
they perform and how smoothly they fit with other programs in the
creation of still greater programs. The programmer must seek both
perfection of part and adequacy of collection. In this book the use
of program
is focused on the creation, execution, and study of
programs written in a dialect of Lisp for execution on a digital
computer. Using Lisp we restrict or limit not what we may program,
but only the notation for our program descriptions.
教育者、将軍、栄養士、心理学者、そして親は、プログラムします。軍隊、学生、そしていくつかの社会は、プログラムされます。大きな問題への挑戦には一連のプログラムが使われ、その大半は取り組みの途中で生まれてきます。これらのプログラムには、目の前の問題に特有と思われる論点がつきものです。プログラミングをそれ自体として知的活動と認識するには、コンピュータプログラミングに向き合わなければなりません。コンピュータプログラムを読み、書かなければなりません—それも数多く。プログラムが何についてのものか、どんな応用に使われるかは、たいして重要ではありません。重要なのは、プログラムがいかにうまく動作するか、そしてさらに大きなプログラムを作り上げるために他のプログラムといかに滑らかに組み合わさるかです。プログラマは、部分の完全さと全体の適切さの両方を追求しなければなりません。本書におけるプログラム
という言葉の用法は、Lisp の方言で書かれたプログラムをデジタルコンピュータ上で作成、実行、研究することに焦点を当てています。Lisp を使うことで、私たちが何をプログラムできるかを制限するのではなく、プログラムの記述に使う表記法だけを限定しているのです。
Our traffic with the subject matter of this book involves us with
three foci of phenomena: the human mind, collections of computer
programs, and the computer. Every computer program is a model,
hatched in the mind, of a real or mental process. These processes,
arising from human experience and thought, are huge in number,
intricate in detail, and at any time only partially understood. They
are modeled to our permanent satisfaction rarely by our computer
programs. Thus even though our programs are carefully handcrafted
discrete collections of symbols, mosaics of interlocking functions,
they continually evolve: we change them as our perception of the model
deepens, enlarges, generalizes until the model ultimately attains a
metastable place within still another model with which we struggle.
The source of the exhilaration associated with computer programming is
the continual unfolding within the mind and on the computer of
mechanisms expressed as programs and the explosion of perception they
generate. If art interprets our dreams, the computer executes them in
the guise of programs!
本書の主題に関わるとき、私たちは三つの現象の焦点と向き合います。人間の心、コンピュータプログラムの集合体、そしてコンピュータです。あらゆるコンピュータプログラムは、現実の、あるいは精神的なプロセスについて、心の中で孵化したモデルです。これらのプロセスは人間の経験と思考から生じ、数は膨大で、細部は複雑で、いつの時点でも部分的にしか理解されていません。コンピュータプログラムによって永続的に満足のいくモデル化がなされることは、めったにありません。したがって、私たちのプログラムは注意深く手作りされたシンボルの離散的な集まり、すなわち互いに噛み合う関数のモザイクであるにもかかわらず、絶えず進化し続けます。モデルについての認識が深まり、広がり、一般化されるにつれてプログラムを変更し、やがてそのモデルは、私たちが格闘する別のモデルの中で準安定な位置に到達するのです。コンピュータプログラミングに伴う高揚感の源泉は、プログラムとして表現されたメカニズムが心の中とコンピュータ上で絶え間なく展開されること、そしてそれが生み出す認識の爆発にあります。芸術が私たちの夢を解釈するなら、コンピュータはプログラムという姿でそれを実行するのです!
For all its power, the computer is a harsh taskmaster. Its programs
must be correct, and what we wish to say must be said accurately in
every detail. As in every other symbolic activity, we become
convinced of program truth through argument. Lisp itself can be
assigned a semantics (another model, by the way), and if a program's
function can be specified, say, in the predicate calculus, the proof
methods of logic can be used to make an acceptable correctness
argument. Unfortunately, as programs get large and complicated, as
they almost always do, the adequacy, consistency, and correctness of
the specifications themselves become open to doubt, so that complete
formal arguments of correctness seldom accompany large programs.
Since large programs grow from small ones, it is crucial that we
develop an arsenal of standard program structures of whose correctness
we have become sure—we call them idioms—and learn to combine them
into larger structures using organizational techniques of proven
value. These techniques are treated at length in this book, and
understanding them is essential to participation in the Promethean
enterprise called programming. More than anything else, the
uncovering and mastery of powerful organizational techniques
accelerates our ability to create large, significant programs.
Conversely, since writing large programs is very taxing, we are
stimulated to invent new methods of reducing the mass of function and
detail to be fitted into large programs.
その力にもかかわらず、コンピュータは厳しい監督者です。プログラムは正しくなければならず、私たちが言いたいことはあらゆる細部において正確に述べられなければなりません。他のあらゆる記号的活動と同様に、私たちは論証を通じてプログラムの正しさを確信するようになります。Lisp 自体に意味論を与えることができ(ちなみにこれも別のモデルです)、プログラムの機能が、たとえば述語論理で仕様化できるなら、論理の証明手法を用いて受け入れ可能な正当性の論証を行うことができます。しかし残念ながら、プログラムが大きく複雑になると—ほぼ常にそうなるのですが—仕様自体の十分さ、一貫性、正しさが疑わしくなり、完全で形式的な正当性の論証が大規模プログラムに伴うことはめったにありません。大きなプログラムは小さなものから成長するので、正しさを確信できる標準的なプログラム構造のレパートリーを発展させること—それをイディオムと呼びます—そして実績のある組織化技法を使ってそれらをより大きな構造に組み合わせる方法を学ぶことが極めて重要です。これらの技法は本書で詳しく扱われており、それを理解することはプログラミングというプロメテウス的事業に参加するために不可欠です。何よりも、強力な組織化技法の発見と習得が、大規模で重要なプログラムを作り出す能力を加速させます。逆に、大きなプログラムを書くことは非常に骨が折れるので、大規模プログラムに組み込むべき機能と詳細の量を減らす新しい方法を発明する動機が生まれるのです。
Unlike programs, computers must obey the laws of physics. If they
wish to perform rapidly—a few nanoseconds per state change—they
must transmit electrons only small distances (at most
$1\frac{1}{2}$
feet). The heat generated by the huge number of devices so
concentrated in space has to be removed. An exquisite engineering art
has been developed balancing between multiplicity of function and
density of devices. In any event, hardware always operates at a level
more primitive than that at which we care to program. The processes
that transform our Lisp programs to machine
programs are
themselves abstract models which we program. Their study and creation
give a great deal of insight into the organizational programs
associated with programming arbitrary models. Of course the computer
itself can be so modeled. Think of it: the behavior of the smallest
physical switching element is modeled by quantum mechanics described
by differential equations whose detailed behavior is captured by
numerical approximations represented in computer programs executing on
computers composed of …!
プログラムとは違い、コンピュータは物理法則に従わなければなりません。高速に動作しようとすれば—状態変化あたり数ナノ秒で—電子はわずかな距離(最大で$1\frac{1}{2}$フィート)しか伝送できません。空間にこれほど集中した膨大な数のデバイスが生み出す熱を除去しなければなりません。機能の多様性とデバイスの密度のバランスをとる精緻なエンジニアリングの技が発展してきました。いずれにせよ、ハードウェアは常に、私たちがプログラムしたいと思うレベルよりも原始的なレベルで動作します。Lisp プログラムを機械
プログラムに変換するプロセス自体が、私たちがプログラムする抽象モデルです。それらの研究と作成は、任意のモデルをプログラムすることに伴う組織化の方法について、多くの知見を与えてくれます。もちろんコンピュータ自体もそのようにモデル化できます。考えてみてください。最小の物理的スイッチング素子の振る舞いは、量子力学によってモデル化され、それは微分方程式で記述され、その詳細な振る舞いは数値近似によって捕捉され、それはコンピュータプログラムとして表現され、そのプログラムは…で構成されたコンピュータ上で実行されるのです!
It is not merely a matter of tactical convenience to separately
identify the three foci. Even though, as they say, it's all in the
head, this logical separation induces an acceleration of symbolic
traffic between these foci whose richness, vitality, and potential is
exceeded in human experience only by the evolution of life itself. At
best, relationships between the foci are metastable. The computers
are never large enough or fast enough. Each breakthrough in hardware
technology leads to more massive programming enterprises, new
organizational principles, and an enrichment of abstract models.
Every reader should ask himself periodically Toward what end, toward
what end?
—but do not ask it too often lest you pass up the fun of
programming for the constipation of bittersweet philosophy.
三つの焦点を個別に識別することは、単なる戦術的な便宜の問題ではありません。よく言われるように「すべては頭の中にある」としても、この論理的な分離は焦点間の記号的な交流を加速させ、その豊かさ、活力、可能性は、人間の経験において生命の進化そのものによってのみ凌駕されるものです。焦点間の関係は、うまくいっても準安定にすぎません。コンピュータは十分に大きくもなく、十分に速くもありません。ハードウェア技術のブレークスルーのたびに、より大規模なプログラミング事業、新しい組織化の原理、そして抽象モデルの充実がもたらされます。すべての読者は折に触れて何のために、何のために?
と自問すべきです—しかし、あまり頻繁に問いかけてはいけません。プログラミングの楽しさを、ほろ苦い哲学の便秘と引き換えにしてしまいますから。
Among the programs we write, some (but never enough) perform a precise
mathematical function such as sorting or finding the maximum of a
sequence of numbers, determining primality, or finding the square
root. We call such programs algorithms, and a great deal is known of
their optimal behavior, particularly with respect to the two important
parameters of execution time and data storage requirements. A
programmer should acquire good algorithms and idioms. Even though
some programs resist precise specifications, it is the responsibility
of the programmer to estimate, and always to attempt to improve, their
performance.
私たちが書くプログラムの中で、正確な数学的機能を果たすものがあります(しかし決して十分ではありません)。たとえば、ソートや数列の最大値の探索、素数判定、平方根の計算などです。このようなプログラムをアルゴリズムと呼び、その最適な振る舞いについて、特に実行時間とデータ記憶容量という二つの重要なパラメータに関して、多くのことが知られています。プログラマはよいアルゴリズムとイディオムを身につけるべきです。正確な仕様化が難しいプログラムもありますが、その性能を見積もり、常に改善を試みることはプログラマの責任です。
Lisp is a survivor, having been in use for about a quarter of a
century. Among the active programming languages only Fortran has had
a longer life. Both languages have supported the programming needs of
important areas of application, Fortran for scientific and engineering
computation and Lisp for artificial intelligence. These two areas
continue to be important, and their programmers are so devoted to
these two languages that Lisp and Fortran may well continue in active
use for at least another quarter-century.
Lisp は生き残りです。約四半世紀にわたって使われてきました。現役のプログラミング言語の中で、より長い歴史を持つのは Fortran だけです。どちらの言語も重要な応用分野のプログラミングニーズを支えてきました。Fortran は科学・工学計算に、Lisp は人工知能に。これら二つの分野は引き続き重要であり、プログラマたちはこれら二つの言語にとても愛着を持っているため、Lisp と Fortran は少なくともあと四半世紀は現役で使われ続けるかもしれません。
Lisp changes. The Scheme dialect used in this text has evolved from
the original Lisp and differs from the latter in several important
ways, including static scoping for variable binding and permitting
functions to yield functions as values. In its semantic structure
Scheme is as closely akin to Algol 60 as to early Lisps. Algol 60,
never to be an active language again, lives on in the genes of Scheme
and Pascal. It would be difficult to find two languages that are the
communicating coin of two more different cultures than those gathered
around these two languages. Pascal is for building
pyramids—imposing, breathtaking, static structures built by armies
pushing heavy blocks into place. Lisp is for building
organisms—imposing, breathtaking, dynamic structures built by squads
fitting fluctuating myriads of simpler organisms into place. The
organizing principles used are the same in both cases, except for one
extraordinarily important difference: The discretionary exportable
functionality entrusted to the individual Lisp programmer is more than
an order of magnitude greater than that to be found within Pascal
enterprises. Lisp programs inflate libraries with functions whose
utility transcends the application that produced them. The list,
Lisp's native data structure, is largely responsible for such growth
of utility. The simple structure and natural applicability of lists
are reflected in functions that are amazingly nonidiosyncratic. In
Pascal the plethora of declarable data structures induces a
specialization within functions that inhibits and penalizes casual
cooperation. It is better to have 100 functions operate on one data
structure than to have 10 functions operate on 10 data structures. As
a result the pyramid must stand unchanged for a millennium; the
organism must evolve or perish.
Lisp は変化します。本書で使われている Scheme という方言は、オリジナルの Lisp から進化したもので、変数束縛における静的スコープや関数が関数を値として返せることなど、いくつかの重要な点で元の Lisp と異なります。意味論的な構造において、Scheme は初期の Lisp と同じくらい Algol 60 に近い存在です。Algol 60 は二度と現役の言語にはなりませんが、Scheme と Pascal の遺伝子の中に生き続けています。これら二つの言語をめぐるコミュニティほど異なる文化の共通通貨となっている二つの言語を見つけるのは難しいでしょう。Pascal はピラミッドを建てるためのものです—軍隊が重い石を押して所定の位置に据える、壮大で息をのむような静的構造物。Lisp は生物を作るためのものです—小隊が揺れ動く無数のより単純な生物を組み合わせていく、壮大で息をのむような動的構造物。使われる組織化の原理は両者で同じですが、一つだけ極めて重要な違いがあります。個々の Lisp プログラマに委ねられる裁量的でエクスポート可能な機能は、Pascal の事業の中で見出されるものよりも桁違いに大きいのです。Lisp プログラムは、それを生み出したアプリケーションを超越する実用性を持つ関数でライブラリを膨らませます。Lisp のネイティブなデータ構造であるリストが、このような実用性の成長の大きな原因です。リストの単純な構造と自然な適用可能性は、驚くほど特異性のない関数に反映されています。Pascal では宣言可能なデータ構造が過剰にあるため、関数内に専門化が生じ、気軽な協調を阻害し不利にします。10 個のデータ構造に対して 10 個の関数を持つよりも、1 つのデータ構造に対して 100 個の関数を持つ方がよいのです。その結果、ピラミッドは千年間不変でなければならず、生物は進化するか滅びるかしかないのです。
To illustrate this difference, compare the treatment of material and
exercises within this book with that in any first-course text using
Pascal. Do not labor under the illusion that this is a text
digestible at MIT only, peculiar to the breed found there. It is
precisely what a serious book on programming Lisp must be, no matter
who the student is or where it is used.
この違いを例証するために、本書における題材と演習の扱い方を、Pascal を使った入門テキストのそれと比べてみてください。本書が MIT だけで消化可能な、あそこにいる特殊な人種だけのためのテキストだという幻想にとらわれないでください。学生が誰であれ、どこで使われるのであれ、Lisp プログラミングに関する真剣な書物とは、まさにこのようなものでなければならないのです。
Note that this is a text about programming, unlike most Lisp books,
which are used as a preparation for work in artificial intelligence.
After all, the critical programming concerns of software engineering
and artificial intelligence tend to coalesce as the systems under
investigation become larger. This explains why there is such growing
interest in Lisp outside of artificial intelligence.
本書はプログラミングについてのテキストであり、人工知能の仕事の準備として使われる大半の Lisp の本とは異なることに注意してください。結局のところ、ソフトウェア工学と人工知能の重要なプログラミング上の関心事は、調査対象のシステムが大きくなるにつれて融合する傾向があります。このことが、人工知能の外部で Lisp への関心が高まっている理由を説明しています。
As one would expect from its goals, artificial intelligence research
generates many significant programming problems. In other
programming cultures this spate of problems spawns new languages.
Indeed, in any very large programming task a useful organizing
principle is to control and isolate traffic within the task modules
via the invention of language. These languages tend to become less
primitive as one approaches the boundaries of the system where we
humans interact most often. As a result, such systems contain complex
language-processing functions replicated many times. Lisp has such a
simple syntax and semantics that parsing can be treated as an
elementary task. Thus parsing technology plays almost no role in Lisp
programs, and the construction of language processors is rarely an
impediment to the rate of growth and change of large Lisp systems.
Finally, it is this very simplicity of syntax and semantics that is
responsible for the burden and freedom borne by all Lisp programmers.
No Lisp program of any size beyond a few lines can be written without
being saturated with discretionary functions. Invent and fit; have
fits and reinvent! We toast the Lisp programmer who pens his thoughts
within nests of parentheses.
その目標から予想されるように、人工知能の研究は多くの重要なプログラミングの問題を生み出します。他のプログラミング文化では、このような問題の洪水が新しい言語を生み出します。確かに、非常に大規模なプログラミングタスクでは、言語の発明を通じてタスクモジュール内の交流を制御し分離することが、有用な組織化の原理です。これらの言語は、人間が最も頻繁にやり取りするシステムの境界に近づくにつれて、より原始的でなくなる傾向があります。その結果、そのようなシステムは何度も複製された複雑な言語処理関数を含むことになります。Lisp の構文と意味論は非常に単純なので、構文解析は初歩的な作業として扱えます。したがって、構文解析技術は Lisp プログラムにおいてほとんど役割を果たさず、言語処理系の構築が大規模な Lisp システムの成長と変化の速度を妨げることはめったにありません。最後に、まさにこの構文と意味論の単純さこそが、すべての Lisp プログラマが負う重荷と自由の原因なのです。数行を超えるいかなる規模の Lisp プログラムも、裁量的な関数で満たされずには書けません。発明して組み合わせよ、そしてまた発作的に再発明せよ! 括弧の入れ子の中に思考を綴る Lisp プログラマに乾杯。
Alan J. PerlisNew Haven, Connecticut