17082007 SICP
SICPの問題2.55で
gosh> (car ''test)
quote
gosh> (cdr ''test)
(test)
と印字する理由がいまいち分からなかったがそれっぽく書いてみたら、こんな感じか、、、
gosh> (cdr (quote 'test))
quote
gosh> (cdr (quote 'test))
(test)
と思ったら、前のページの注釈に書いてあった。
17082007 SICP
SICPの問題2.55で
gosh> (car ''test)
quote
gosh> (cdr ''test)
(test)
と印字する理由がいまいち分からなかったがそれっぽく書いてみたら、こんな感じか、、、
gosh> (cdr (quote 'test))
quote
gosh> (cdr (quote 'test))
(test)
と思ったら、前のページの注釈に書いてあった。
最近朝起きてSICPを読んでる。で、SICPの2章も中盤を越えて、accumulateを使って行列の演算を定義した。
ふむーこれはpythonでやってみたいなと思ってたら、ちょうどタイミングよくpythonでやってる人がいた。
ので、perlで。
sub accumulate{
my ($op, $init, $list) = @_;
@$list == () ? return $init :
return $op->(shift(@$list),accumulate($op,$init,$list));
}
my $test_func = sub {return $_[0]+$_[1];};
my $test_list = [1,2,3,4,5];
print accumulate($test_func, 0, $test_list);
で、SICPみたいに、たたみこむだけじゃなくてリストを戻したい。
my $cons = sub {return [@{$_[1]},$_[0]];};
XXX accumulate($cons, [], [1,2,3,4,5]);
List::Utilでも同じことできるみたいですが。自分で書いてみたかったということで。
13082007 SICP
一週間ぐらい前にchurch数のことがわかったときには
SICPも二章に入って、最初の盛り上がりがやってきたヨ!
なんつって喜んでエントリ書きかけてたんだけど、今となってはどうでもよくなってきた。むしろラムダに傾いたっていうか、TuringとChurchの狭間での髭剃りのほうが気になる。
関数型言語に目覚めた30代におくるラムダッシュ!bluetoothで剃った髭の数を最寄りのフィボナッチ数でお知らせ!みたいなITシェーバーだったらコンテンツマッチ広告といえるじゃろが、444じゃなぁ、、、世界が驚いてもナナロク世代は驚かん(しかもナナロク世代じゃないし)
haskellでchurch数を後でちゃんと読む。
章ってのは読了になるのだろうか?
それにしてもやっとって感じ。
Meadowでgaucheを使うために
ただし、Meadow+gauche(win)の場合には
(setq scheme-program-name "gosh.exe -i")
としないとプロンプトがでない。gaucheだとelispよりもデータ、手続きを区別しないで取り扱っている感があってなかなかおもしろい。
昨日弱音を吐いたけど、小鼓呑んで頭がまわってないだけだった。(どうしても日本酒が飲みたくてローソンで買った。ゴールデンウィークは実家に帰って会津とか那須のほうの酒を物色予定)
SICPのp.32はこんな感じで
(defun inc (n) (+ n 1)) (defun cube (x) (* x x x)) (defun sum (term a next b) (if (> a b) 0 (+ (funcall term a) (sum term (funcall next a) next b)))) (sum 'cube 1 'inc 10) 3025
関数はクォートして評価されないようにしといて、高階関数のほうでfuncallで評価する。こんな感じになってくるとなんかperlのリファレンス操作してるみたいだ。
とか思ったのでperlでも書いてみた。
my $inc = sub {$_[0] + 1}; my $cube = sub {$_[0] ** 3}; sub sum { my ($term,$a,$next,$b) = @_; return 0 if $a > $b; $term->($a) + sum($term,$next->($a),$next,$b); } print sum($cube,1,$inc,80);
Emacs辞典の4章がelispの基礎でわかりやすい。
あと
(sum 'cube 1 'inc 51)
で
(error "Lisp nesting exceeds max-lisp-eval-depth")
っていうエラーがでた(Meadow)
こんな感じで
(defun pscl (x y) (cond ((< y 3) 1) ((= x 1) 1) ((= y x) 1) (t (+ (pscl (- x 1) (- y 1)) (pscl x (- y 1)))) ))
schemeだとelseのところがelispだとtになる。どの条件にも当てはまらないとnilだから、elseはtで表現するらしい。
(defun A (x y) (cond ((= y 0) 0) ((= x 0) (* 2 y)) ((= y 1) 2) (t (A (- x 1) (A x (- y 1))))))
Ackerman関数ってのが良く分からなかったので調べたら爆発的に計算量が増える関数らしい。しかも末尾再帰的にならないらしい
SICPのp.19に再帰的プロセスと再帰的手続きを混同しないようにとかいてあるのだけれど、
perl - to goto or not to goto, that's the continuation
と、そこから張られた一連のリンクを読んでいてなんとなく掴みかけてきた感じがした。
あとはコメントの、continuationってgotoの意味論研究の過程で生み出された抽象概念ですよ。っていうあたりとか。
なんでも再帰も僕の理解にお役立ち。
末尾再帰がループと同等に実行されるのは、コンパイラによるオプショナルな最適化ではない。 Schemeは、末尾呼び出しでスタックを消費しないことを言語規格上要求している。
SICPおもろい。
相変わらずSICPをelispで
(defun goodenough (guess x)(< (abs (- (* guess guess) x)) 0.001)) (defun improve (guess x) (average guess (/ x guess))) (defun average (x y) (/ (+ x y) 2)) (defun sqlt_it (guess x) (if (goodenough guess x) guess (sqlt_it (improve guess x) x))) (sqlt_it 1.0 5) 2.2360688956433634