SICP演習問題4.8
なかなか苦戦した.
どうやってlambdaに変換したらよいか.
変換は以下のようにする.
(let loop ((a 5)) (if (< a 0) 0 (+ a (loop (- a 1))))) ;=> 15 ((lambda () (define (loop a) (if (< a 0) 0 (+ a (loop (- a 1))))) (loop 5))) ;=> 15
プログラム読みにくい...一週間後このプログラムがすらすら読めるだろうか.
letを使えば少しすっきりするんだけど,letの定義でletを使うのはやっぱりいやなので,
defineを連呼.
追記(090625)
tagがうまく評価されず,普通の(名前なし)letがうまくできないことが発覚.
とりあえず暫定処置を施す.
if分の中のtagはfalseなのに,bindings, bodyの引数のときは#
わからん......
tagは結局(symbol? cadr exp)なので,それの評価結果をそのまま引数にする.
;;exercise4.8 (define (let-clauses exp) (cdr exp)) (define (let-bindings-with-tag exp tag) (if tag (cadr (let-clauses exp)) (car (let-clauses exp)))) (define (let-body-with-tag exp tag) (if tag (cddr (let-clauses exp)) (cdr (let-clauses exp)))) (define (let-tag exp) (if (symbol? (car (let-clauses exp))) (car (let-clauses exp)) #f)) (define (let->combination exp) (define tag (let-tag exp)) (define bindings (let-bindings-with-tag exp (symbol? (cadr exp)))) (define body (let-body-with-tag exp (symbol? (cadr exp)))) (if (null? bindings) '() (if tag (list (make-lambda '() (list (cons 'define (cons (cons tag (map car bindings)) body)) (cons tag (map cadr bindings))))) (cons (make-lambda (map car bindings) body) (map cadr bindings)))))