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

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

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

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

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

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

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

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

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

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

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

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

  1. > (+ 1 2)
  2. 3

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

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

特殊形式(special forms)

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

  1. > (define x 2)

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

合成手続き

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

  1. > (define (square x) (* x x))
  2. > (square 2)
  3. 4

条件式と述語

cond ・・・ 場合分け

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

論理演算子

and、or、not

用例は、こちら を参照。

問題

問題1.1

入力して確認。

問題1.2

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

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

問題1.3

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

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

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

  1. > (define (smaller x y) (if (< x y) x y))
  2. > (define (last x y z) (smaller x (smaller y z)))
  3. > (define (square x) (* x x))
  4. > (define (q1_3 x y z) (+
  5. (square (if (> x (last x y z)) x (last x y z)))
  6. (square (if (> y (last x y z)) y (last x y z)))))
  7. > (q1_3 4 3 2)
  8. 25

問題1.4

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

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

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

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

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

Follow me!

コメントを残す

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