(wat-aro)

無職から有職者にランクアップしました

SICP 問題 4.08

let->combinationの変更ですんでいるのでevalは変更しなくていい.

(define (named-let? exp) (symbol? (cadr exp)))
(define (named-let-func-name exp) (cadr exp))
(define (named-let-parameters exp) (caddr exp))
(define (named-let-variables exp) (map car (named-let-parameters exp)))
(define (named-let-expressions exp) (map cadr (named-let-parameters exp)))
(define (named-let-bodys exp) (cdddr exp))

(define (make-definition variable value)
  (list 'define variable value))

(define (named-let->define func-name variables expressions bodys)
  (make-begin (list (make-definition func-name (make-lambda variables bodys))
                    (cons func-name expressions))))

(define (let->combination exp)
  (if (symbol? (cadr exp)) ;; 2番目の要素がシンボルならnamed-let
      (named-let->define (named-let-func-name exp)
                         (named-let-variables exp)
                         (named-let-expressions exp)
                         (named-let-bodys exp))
      (cons (make-lambda (let-variables exp)
                     (let-bodys exp))
        (let-expressions exp))))
gosh> (let->combination '(let fib-iter ((a 1)
                                        (b 0)
                                        (count n))
                           (= 1 1)
                           (if (= count 0)
                               b
                               (fib-iter (+ a b) a (- count 1)))))
      ((define fib-iter
         (lambda (a b count)
           (= 1 1)
           (if (= count 0)
               b
               (fib-iter (+ a b) a (- count 1)))))
       (fib-iter 1 0 n))