第159回 素人くさいSICP読書会(at 月島某所)

  • 会場提供&お菓子ありがとうございました
  • おみやげはいつものように杏仁豆腐。ご家族には「杏仁豆腐のお兄ちゃんたち」という評価が定着しているもよう
  • かっくんが買ったばかりのMacBook Proを持ってきてた。そこからMacの話題。Quicksilverのメモリ消費量がひどい、とか
  • 佐野さんのノキア端末は圏外になるとリセットがかかるらしい。ひどい話
  • 結局、この日は問題5.3に終始
  • 問題5.3
  • 書く必要があるのは図が二つとコード(制御器の定義)が二つ
  • hisaさんから「コードから書いた方がやりやすい」と聞いたので、問題とは逆にコードから書く
  • good-enough?とimproveを基本演算としてまず書き、それらの中身をちまちまバラしていく。面倒だけど機械的な作業なので難しくはない。人力コンパイラ
  • 元のSchemeのコードの内部defineではxは引数として取っていないが、xを捕捉して中で利用しているので、good-enough?とimproveはxを取るように記述した
  • hisaさんと答合わせしたらほぼ同じだった
  • 杉本さんに「全体のループを忘れている」と指摘された。たしかにループがないと使い捨てで二度と使えなくなってしまう
  • で、こんな感じ

good-enough?とimproveが基本演算の場合

(controller
 sqrt-loop
   (assign x (op read))
   (assign guess (const 1.0))
 good-enough-test
   (test (op good-enough?) (reg x) (reg guess))
   (branch (label sqrt-done))
   (assign guess (op improve) (reg x) (reg guess))
   (goto (label good-enough-test))
 sqrt-done
   (perform (op print) (reg guess))
   (goto (label sqrt-loop)))

算術演算のみに展開

(controller
 sqrt-loop
   (assign x (op read))
   (assign guess (const 1.0))
 good-enough-test
   (assign t (op *) (reg guess) (reg guess))
   (assign t (op -) (reg t) (reg x))
   (test (op >) (reg t) (const 0))
   (branch (label abs-done))
   (assign t (op *) (reg t) (const -1))
 abs-done
   (test (op <) (reg t) (const 0.001))
   (branch (label sqr-done))
   (assign t (op /) (reg x) (reg guess))
   (assign t (op +) (reg t) (reg guess))
   (assign guess (op /) (reg t) (const 2))
   (goto (label good-enough-test))
 sqrt-done
   (perform (op print) (reg guess))
   (goto (label sqrt-loop)))

手持ちの紙に殴り書きした図(汚いなー)

  • この図をhisaさんがOmniGraffleで書こうとして悪戦苦闘してた
  • 複雑な方の図は面倒なのでパス。一時変数を1個所にまとめると線がぐしゃぐしゃになるはずなので「エイリアスにすればいんじゃね」と提案。「回路図のGNDみたいな感じ」(佐野さん)
  • 次回は問題5.3の答をプロジェクタで確認して、次の本文に入る予定