SICP 読み (147) 4.1.2 式の表現
業者連絡待ちの間に (以下略
しかし保守契約を結ばないとファームのアプデイトもできんとは、一体どーゆー事なんでしょうかねぇ。セキュリティパッチとは異なるソレなんでしょうか。
問題 4.8
名前付き let を導出、との事。以下の手続きはどう変換されるべきなのか。
(define (fib n) (let fib-iter ((a 1) (b 0) (count n)) (if (= count 0) b (fib-iter (+ a b) a (- count 1)))))
4.6 では let が lambda に変換された、という事で同じ形にするのかな。どうなるべき、なんだろうか。
(define (fib n) (define fib-iter (lambda (a b count) (if (= count 0) b (fib-iter (+ a b) a (- count 1))))) (fib-iter 1 0 n))
手続きな部分はそのまんまなので、やってデキない訳ではなさげ。
gosh> (define l '(let fib-iter ((a 1) (b 0) (count n)) (if (= count 0) b (fib-iter (+ a b) a (- count 1)))) ) l gosh> (cadr l) fib-iter gosh> (caddr l) ((a 1) (b 0) (count n)) gosh> (cadddr l) (if (= count 0) b (fib-iter (+ a b) a (- count 1))) gosh> (list 'lambda (map car (caddr l)) (cdddr l)) (lambda (a b count) ((if (= count 0) b (fib-iter (+ a b) a (- count 1))))) gosh>
lambda 式を作る手順は同じですが、取り出す位置が違うな。とりあえず手続きをベタに書いてみよう。元は以下。
(define (let->combination exp) (append (list (make-lambda (map car (cadr exp)) (cddr exp))) (map cadr (cadr exp))))
えーと、どうやって切り分ければ良いのかな。cadr が symbol? って聞けば良いと見よう。
(define (let->combination exp) (if (symbol? (cadr exp)) (list 'define (cadr exp) (list 'lambda (map car (caddr exp)) (cdddr exp)) (list (cadr exp) (map cadr (caddr exp)))) (append (list (make-lambda (map car (cadr exp)) (cddr exp))) (map cadr (cadr exp)))))
うわ、微妙。then ブロックなソレは動作確認してません。やってみよ。
gosh> (list 'define (cadr l) (list 'lambda (map car (caddr l)) (cdddr l)) (list (cadr l) (map cadr (caddr l)))) (define fib-iter (lambda (a b count) ((if (= count 0) b (fib-iter (+ a b) a (- count 1))))) (fib-iter (1 0 n))) gosh>
最早、合ってるのかどうかさえ不明 (何
えーと、何が何だかワケワカらんぞ。if の前に括弧が二つあるな。これは make-lambda を使ってないからかな??あ、その前の list も不要。
もう一つ。define なリストが終わってから手続き呼び出しだな。あら??なんじゃそれは。二つもリストは戻せないと思うんだけど。最初に戻らないと駄目ぽ。まぢ??
つづき
元に戻りかけたんですが、begin を使う、という解を見いだす。微妙??
(define (let->combination exp) (if (symbol? (cadr exp)) (list 'begin (list 'define (cadr exp) (make-lambda (map car (caddr exp)) (cdddr exp))) (list (cadr exp) (map cadr (caddr exp)))) (append (list (make-lambda (map car (cadr exp)) (cddr exp))) (map cadr (cadr exp)))))
この then ブロックなソレを gosh に吸わせてみる。
gosh> (list 'begin (list 'define (cadr l) (make-lambda (map car (caddr l)) (cdddr l))) (list (cadr l) (map cadr (caddr l)))) (begin (define fib-iter (lambda (a b count) (if (= count 0) b (fib-iter (+ a b) a (- count 1))))) (fib-iter (1 0 n))) gosh> l (let fib-iter ((a 1) (b 0) (count n)) (if (= count 0) b (fib-iter (+ a b) a (- count 1)))) gosh>
出力はどうか。
(begin (define fib-iter (lambda (a b count) (if (= count 0) b (fib-iter (+ a b) a (- count 1))))) (fib-iter (1 0 n)))
ええ感じ、なのかなぁ。まずはこれで試験を作ってみよう。