抽象化2

http://d.hatena.ne.jp/tkuro/20090321

id:yukichankoにコメント返してて、返した瞬間に疑問点が理解できて、我ながら見当違いの答を書いてしまったことに気がついた。結構大事そうなので別エントリ立ててみた。

yukichanko 2009/10/19 04:50
ベキ集合自体は理解しているのだけど、letの引数とのところに再帰が入ってくると、思考停止しちゃう。

結局のところあそこの

(let ((rest (subsets ...)) 

のところが「何をやっているか?どう制御が進むのか」と考え始めると思考停止というか発散する筈。 そうではなくて、「カッケーオレ様がスッゲー力で将来書ききる(予定)のこのfuncは細々した事は完璧に処理して、必ずオレの求める答を完璧な形で答えてくれるゴールデンfunc!」と思い込んで詳細考えない => 抽象化する、のが関数プログラミングの極意かもしんない、という話。
例えばもっと簡単な例で階乗を計算する

(define (fact n)
  (if (= n 1) 1
      (* n (fact (- n 1)))))

でも (fact (- n 1))のところは「ここで関数適用してそれがこう展開されて」と考えるんじゃなく、 「 n-1までの階乗がこう書ける」と考える筈。その基本に則って、とにかく中は考えずに (rest (subsets ...)) は一個前の全ベキ集合がこう表される、という意味だ、というふうに思い込む。で、詳細を考えないで「関係」を描いて行く、というのが関数プログラミングなのではないか、と思った*1

実際のところ、imperativeに考えてこれを一瞬で考えられる人がいたとしたら、そっちの方が天才的なんでなかろうか。むしろそんなに頭の良くないヘロヘロ人間だからこそ、抽象などの様々な強力な武器に頼って、なんとか天才に並べる→オレスゲーと思い込む→詳細考えない→抽象化(違う)、というのが正解な気がした。

*1:immutable/mutableはその為の方法でしかない