car ''testの謎

SICPの問題2.55で

gosh> (car ''test)
quote
gosh> (cdr ''test)
(test)

と印字する理由がいまいち分からなかったがそれっぽく書いてみたら、こんな感じか、、、

gosh> (cdr (quote 'test))
quote
gosh> (cdr (quote 'test))
(test)

と思ったら、前のページの注釈に書いてあった。

perlでaccumulate

最近朝起きて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でも同じことできるみたいですが。自分で書いてみたかったということで。

church数のこと

一週間ぐらい前にchurch数のことがわかったときには

SICPも二章に入って、最初の盛り上がりがやってきたヨ!

なんつって喜んでエントリ書きかけてたんだけど、今となってはどうでもよくなってきた。むしろラムダに傾いたっていうか、TuringとChurchの狭間での髭剃りのほうが気になる。

lamdash

関数型言語に目覚めた30代におくるラムダッシュ!bluetoothで剃った髭の数を最寄りのフィボナッチ数でお知らせ!みたいなITシェーバーだったらコンテンツマッチ広告といえるじゃろが、444じゃなぁ、、、世界が驚いてもナナロク世代は驚かん(しかもナナロク世代じゃないし)

haskellでchurch数を後でちゃんと読む。

SICP一章読了

章ってのは読了になるのだろうか?

ProductName 計算機プログラムの構造と解釈
ジェラルド・ジェイ サスマン,ジュリー サスマン,ハロルド エイブルソン
ピアソンエデュケーション / ¥ 4,830 (2000-02)
通常24時間以内に発送

それにしてもやっとって感じ。

Meadowでgosh

Meadowでgaucheを使うために

ただし、Meadow+gauche(win)の場合には

(setq scheme-program-name "gosh.exe -i")

としないとプロンプトがでない。gaucheだとelispよりもデータ、手続きを区別しないで取り扱っている感があってなかなかおもしろい。

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の基礎でわかりやすい。

ProductName Emacs 辞典 (DESKTOP REFERENCE)
佐藤 竜一
翔泳社 / 3129円 ( 2006-05-11 )


あと

(sum 'cube 1 'inc 51)

(error "Lisp nesting exceeds max-lisp-eval-depth")

っていうエラーがでた(Meadow)

elispでパスカル三角形

こんな感じで

(defun pscl (x y) 
  (cond ((< y 3) 1)
        ((= x 1) 1)
        ((= y x) 1)
        (t (+ (pscl (- x 1) (- y 1)) (pscl x (- y 1))))
        ))

elispでackerman関数

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は、末尾呼び出しでスタックを消費しないことを言語規格上要求している。

ProductName 計算機プログラムの構造と解釈
ジェラルド・ジェイ サスマン
ピアソンエデュケーション / 4830円 ( 2000-02 )


SICPおもろい。

elispで平方根

相変わらずSICPをelispで

ProductName 計算機プログラムの構造と解釈
ジェラルド・ジェイ サスマン
ピアソンエデュケーション / 4830円 ( 2000-02 )


(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