SICP 読書会 #12008年05月17日 02時45分

書くのが遅くなりましたが、先日開かれた snow-bell さん主催の SICP 勉強会 (計算機プログラムの構造と解釈の読書及び演習) に参加しました。SICP 勉強会は午後からだったのですが、同じ会場で午前中に Gauche 勉強会 (私は不参加) も開かれており、チャットログも合同となっています。他の参加者の記事はSICP勉強会のまとめと異業種交流会 - snow-bellの日記からどうぞ。

組み合わせと合成手続き

Scheme の式 (expression) には組み合わせ (combination) と合成手続き (compound procedure) がある。式を評価したとき、組み合わせならば部分式 (リストの各項) が再帰的に評価されるが、合成手続きでは部分式が組合せとして評価されるとは限らない。

たとえば、手続き定義 (関数定義) (define (square x) (* x x)) は合成手続きであり、この式中の (square x) は組み合わせとして評価されるわけではない (ここでは関数 square に値 x を適用しているわけではない)。

作用的順序と正規順序

引数をすべて評価してから関数にそれらを適用するのが作用的順序の評価 (applicative-order evaluation)。関数の内容を先に展開し、引数が必要になった時点でその引数を評価するのが正規順序の評価 (normal-order evaluation)。

評価順 言語例 SICP 別称
引数が先 Scheme、C 作用的順序の評価 正格評価 (strict evaluation)、先行評価 (eager evaluation)、値呼び出し (call-by-value)
関数が先 Haskell 正規順序の評価 非正格評価 (non-strict evaluation)、遅延評価 (lazy evaluation)、名前呼び出し (call-by-name)

それにしても normalregularcanonicalstrict にそれぞれ正規、正則、正準、正格と別個の訳語を割り当てていった人たちはすごいと思う。

1.1.6問題1.3

演習問題三つの数を引数としてとり,大きい二つの数の二乗の和を返す手続きを定義せよ.、私の解答は以下。

(define (f1.3 x y z)
  (cond ((and (>= x z) (>= y z)) (+ (* x x) (* y y)))
        ((and (>= y x) (>= z x)) (+ (* y y) (* z z)))
        ((and (>= z y) (>= x y)) (+ (* z z) (* x x)))
        (else -1))) ; must not come here

基本的な考え方としては一番小さな数を見つけ、それ以外の二つの数の二乗の和を返すというもの。比較に等号を入れているのは同じ数が複数含まれているときのため。しかし二乗の和を求める部分をまとめてないなど無駄が多い。

雑感

ちょうど書籍を買って積んでいたところだったので、一から読む勉強会はいいタイミングでした。各人の演習問題の解答を見ると、こんな風に書けたのかと思うところが多々あり勉強になります。

第 2 回は 5 月 31 日に Vim 勉強会、Kansai.pm と合同で行われるそうです。また、5 月 24 日には Kanasan.JS JavaScript 第 5 版読書会 #4 も開かれるので、関西の方は是非 (もちろん関西以外からでも) 参加してみてはいかがでしょうか。