一人読書会 「計算機プログラムの構造と解釈」 (1)

「計算機プログラムの構造と解釈」 を購入。しっかりと読み込みたいので、1年くらいかけて一人読書会としゃれ込もうと思う。

・・・電車で読むだけではもったいない。

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

まず、全編を通して、プログラムの説明には、C や Java や Python ではなく、Lisp の方言である、Scheme (スキーム) を使用する。

そもそも、Scheme の設計者である、ジェラルド・ジェイ・サスマン が、本書の著者。

amazon のレビューをみると、訳に対する苦情が多いようだが、自分も最初のページで違和感を感じた。デバッグのことを「虫とり」とか。

ただ、訳者が、1931年生まれの先生ということを知ると、訳の雰囲気の違和感も哲学書のような雰囲気を醸し出してきた。自分はこういう訳も嫌いではない。

で、本書では、 cheme がわからないと話にならないので、最初の章は、文法および考え方の説明に費やされている。

こちらに簡単にまとめた。さらにまとめると、

確認用の処理系には、DrScheme を使用することとする。

手続きの作用を表現。括弧で囲んで、組合せと呼ぶ。

> (+ 1 2)
3

この例だと、加算(+) が、手続きを表す演算子(オペレーター)、1、2 が作用される被演算子(オペランド)

演算子を左端に書く記法を、前置記法という。利点として、任意個数の引数をとることができる、組合せを入れ子にできる。

特殊形式(special forms)

引数に作用しない場合、組合せとは呼ばず、特殊形式という。たとえば、define

> (define x 2)

これで、変数 x に 2 をセットする。

合成手続き

define をつかって、演算に名前をつけることができる。自乗を行う演算に名前をつけてみる。

> (define (square x) (* x x))
> (square 2)
4

条件式と述語

cond ・・・ 場合分け

if ・・・ 場合が2つの場合

論理演算子

and、or、not

用例は、こちら を参照。

問題

問題1.1

入力して確認。

問題1.2

これでよいと思うけど・・・

> (/ (+ 5 4 (- 2 (- 3 (+ 6 (/ 4 5))))) 
     (* 3 (- 6 2) (- 2 7)))
-37/150

問題1.3

いままで経験した言語との考え方の違いを思い知る。

今の知識、思考方法では、こんな感じにしかかけない・・・

変数や配列を使わずに、2番目に大きい値を取得するって困難。

> (define (smaller x y) (if (< x y) x y))
> (define (last x y z) (smaller x (smaller y z)))
> (define (square x) (* x x))
> (define (q1_3 x y z) (+ 
                        (square (if (> x (last x y z)) x (last x y z)))
                        (square (if (> y (last x y z)) y (last x y z)))))
> (q1_3 4 3 2)
25

問題1.4

引数 b が 負の値の場合、符号を反転し絶対値を取得し、a と加算する

おーなんと、被演算子に演算子を置くと、その演算子が作用するのか!

> (define (a-plus-abs-b a b)
    ((if (> b 0) + -) a b))
> (a-plus-abs-b 2 -3)
5

おー結構しんどいなー。今日はここまで。

ゆっくりでもいいから何とか続けていきたい。。。

Follow me!

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です