手続きによる抽象の構築(1)

今日から本格始動です。

1.手続きによる抽象の構築

計算プロセス(computational process)を勉強していこうと思う。計算プロセスは計算機の中に住む抽象的な存在である。プロセスは進行しながらもう一つの抽象的な存在(data)を操作する。プロセスの進行は規則パターン、プログラム(program)の指示に従う。われわれはプロセスに指示しようとしてプログラムを作る。いわばわれわれの呪文で計算機の霊に魔法をかけるのだ。

最初は自分なりの言葉でまとめ直そうと思ったのだけど、これ以上、いじりようがない一文に思えます。原書では以下のようになっています。

We are about to study the idea of computational process. Computational processes are abstract beings that inhabit computers. As they evolve, processes manipulate other abstract things called data. The evolution of a process in directed by a pattern of rules called a program. People create programs to direct processes. In effect, we conjure the spirits of the computer with our spells.

この後はプログラムと魔法(を使うには修行せねばならず、わずかなミスも許されない)や工業製品(は巧みに設計された場合、モジュラになっており、部品ごとに作ることができ、交換でき、個々にバグ取り出来る)との比較が続きます。

Lispによるプログラム

Lispは1950年代に論理表現についての推論の形式化として発明された。数学的形式化のために発明されたにも拘わらず、Lispは実用的プログラム言語である。

Lispの解釈系(interpreter)はLisp言語で記述したプロセスを実行する機械である。最初のLisp解釈系は、MITが実装した。

Lispは公式定義を広めようとする行為に抵抗し、数々の方言を生んでいる。本書で使用するLisp方言はSchemeという。

Lispは計算に用いるには非効率であるが、効率が重視されない場面(シェル・エディタの拡張言語)には好んで使われる。

以下「なぜ本書でLispを使うのか」の理由を引用。

Lispが主流の言語でないなら、なぜわれわれはそれをプログラムの議論の土台として使うのだろうか。それはLispが主要なプログラムの構成やデータの構造を学び、それを言語の基礎となる言語学的機能に関係づけるのに優れた媒体とする独特の特徴を持っているからである。

If Lisp is not a mainstream language, why are we using it as the framework for our discussion of programming? Because the language processes unique features that make it an excellent medium for studying important programming constructs and data structures and for relating them to the linguistic features that support them.

特徴のもっとも著しいのはプロセスの手続き(procedures)というLispによる記述自体がLispデータとして表現、処理できることである。

The most significant of these features is the fact that Lisp descriptions of processes, called procedures, can themselves be represented and manipulated as Lisp data.

たびたび「プログラムとデータが等価」というLispの特徴です。自分はそのパワーを真に体験したことはないです。

「受動的」なデータと「能動的」なプロセスを区別する伝統をぼやかす点に依存した強力なプログラム設計技法が使えるからだ。やがて分かるように、手続きをデータとして扱うLispの柔軟さはこの技法を探求するための、実在する言語で一番便利なものとしている。

The importance of this is that there are powerful program-design techniques the rely on the ability to blur the traditional distinction between “passive” data and “active” processes. As we shall discover, Lisp’s flexibility in handling procedures as data makes it one of the most convenient language in existence for exploring these techniques.

「なんでLisp?」→「Lispは強力な技法が使えます」「データとプロセスの区別をぼやかす設計技法です」「この技法を学ぶのに一番便利なのはLispです」

この技法以外を学ぶのにLispはどうなんだろう?という疑問が浮かびました。「この技法以外も問題なく学べます」なのか、「他を差し置いてでもまずはこの技法を学びましょう」なのか。

1.1. プログラムの要素

強力なプログラム言語には、計算機に仕事のやり方を指示するだけではなく、プロセスに関する考えをまとめるためにも役立つ。そのために単純な概念を統合し複雑な概念を構築する手段を用意している。これを達成するため、強力なプログラム言語には3つの仕掛けが用意されている。

(原文を自分なりに再構築しようとして、大して変わらなかったうえに、わかりにくくなっているような気がする・・・)

  • 基本式(primitive expressions) 言語が関わる最も単純なものを表す(which represent the simplest entities the language is concerned with)
  • 組み合わせ法(means of combination) より単純なものから合成物を作る(by which compound elements are built from simpler ones)
  • 抽象化法(means of abstraction) 合成物に名をつけ、単一のものとして扱う(by which compound elements can be named and manipulated as units)

基本「式」に対して、組み合わせ「法」・抽象化「法」なのが重要なのではないかと思いました。

プログラムする時、二つの要素:手続きとデータを扱う。(それらが実はそれほど違わないことはやがて分かる)早く言えばデータは処理したい「もの」であり、手続きはデータの処理法の記述である。

1.1.1. 式

実際にScheme解釈系(自分はgaucheを利用)を立ち上げて、簡単な四則演算の応答を見る。

式の並びをかっこで囲んで手続きの作用を表現する上のような式を組み合わせ(combinations)という。並びの左端の要素を演算子(operator)、他の要素を被演算子(operands)という。組み合わせの値は演算子が指定する手続きを、被演算子の値である引数(arguments)に作用させて得る。

「被演算子に作用させて」ではなく、「被演算子の値である引数に作用させて」というのが引っかかったので、原文に戻る。

Expressions such as these, formed by delimiting a list of expressions within parentheses in order to denote procedure application, are called combinations. The leftmost element in the list is called operator, and the other elements are called operands. The value of a combination is obtained by applying the procedure specified by the operator to arguments that are the value of operands.

原書でも「that are value of operands」が太文字になっている!!重要な箇所を見落とさなかったので、とてもうれしい。英語にしてみるとわかりやすい。 演算子(operator)が作用(apply)されるのは、被演算子の値(value of operands)であり、被演算子(operands)ではないということだと思う。C言語風に言うと値渡し(pass by value)であり、参照渡し(pass by reference)ではないということではないだろうか。作用されるのはコピーであり、オリジナルには何の変更も及ぼさないことを言っているのではないかと思う。

前置演算子と括弧による曖昧さの排除の利点の解説。清書系は英語で「pretty print」というらしい。勉強になった。

どのような複雑な式に対しても解釈系は常に同じ基本動作を繰り返す:端末から式を読み込み、その式を評価し、結果を印字する。このような動作のことを、解釈系は読み込み・評価・印字ループ(read-eval-print loop)を回ると言うことがある。

REPLキター!最近、moshにも実装されましたね。 コメント欄で「REPL欲しいです」「ですよねー」というやりとりを見て「REPLってなんじゃい?」と思ったちょっと前の俺とは違うぜ。

というところで、1日目を終わります。1時間40分かけて、まだ3ページしか進んでないという・・・。密度の濃さは満足しているので、今後もこの密度で続けたいデス。

シェアする

  • このエントリーをはてなブックマークに追加

フォローする