読書会メモ 第6回 (第一章終了)


●消化内

計算機プログラムの構造と解釈
【第6回】第1章 第3節(p41〜p44)


●メモ
ようやく第一章が終了。この会を始めてから3週間で第一章を読み終えたことになる。全ての問題を解きながら進んでいることともあるが、題材として随所にでてくる数学の復習に一番時間を取られているかな。でも、それはそれでよい勉強をさせてもらっている。高校数学でほぼ理解できる内容であることがせめてもの救いだ。

手続きによる抽象

「手続きによる抽象」をテーマにした第一章のハイライトである問題1.46を残しておく。この章では平方根不動点などの数値計算を様々なアプローチで解いてきた。これが章最後の問題で反復的改良法(予測値を改良しながら解へ近似させていく戦略)として抽象化される。あとで振り返れば至極当然に見える抽象化であっても、左右が見えないまま一歩ずつ階段を昇っていった結果それが現れる瞬間というのはちょっと感動する。

問題1.46
;反復的改良法
(define (iterative-improve good-enough? improve)
  (lambda (guess) 
    (define (itr result)
      (if (good-enough? result)
          result
          (itr (improve result))))
    (itr guess))
  )

;反復的改良法を用いた平方根算出手続き
(define (sqrt x)
 (let ((good-enough? (lambda (guess)
                       (< (abs (- (square guess) x)) 0.00001)))
      (improve (lambda (guess)
                 (average guess (/ x guess)))))
  ((iterative-improve good-enough? improve ) 1.0))
)

;反復的改良法を用いた不動点算出手続き
(define (fixed-point f first-guess)
  (let ((close-enough? (lambda (guess)
                         (< (abs (- guess (f guess)) 0.00001)))))
  ((iterative-improve close-enough? f) first-guess)))


洗練された抽象化は非常に美しいと思う。本質を見抜き、抽出し、適切な名前をつける。そのようなコードであれば一見してロジックの大筋をつかむことができる。

われわれはプログラマとして、プログラムの根底にある抽象を見つけ、より強力な抽象化ができるよう、その上に構成し、一般化するようつとめなければならない。これはプログラムを可能な限り抽象的に書くべしというのではない;経験を積んだプログラマは、自分の仕事に適した抽象のレベルを選ぶことを知っている。しかし抽象を使って考えることができるのは、新しい状況になったときに、すぐ応用できるため、大切である。

『計算機プログラムの構造と解釈』p.43

第一章まとめ


本章のテーマは「手続きによる抽象」だったわけだが、そこに至るまでの過程で実に様々な要素を学んできたことがわかる。

[scheme]scheme文法、再帰手続き、lambda
[解釈系基礎]:置換えモデル、作用的順序と正規順序
[アルゴリズム/数学]再帰プロセスと反復プロセス、アルゴリズムの効率、離散数学微積三角関数…、不動点
[ソフトウェア工学一般]ブラックボックス抽象、高階手続きによる抽象


講師の先輩によれば、これらバラバラに見える要素が第4章「超言語的抽象」ですべて一つにつながるのだという。この本は全体的(かつ再帰的)にそのような構成をとっているのがわかってきた。つまり、当初はそれと知らされずに出てくる材料が最後にどかんとつながる。それがまた一個上のレベルでつながるというような。著者はかなり意図的にそのような構成にしたのだろう。4章に進むのが楽しみだ。