SICP 読み (148) 4.1.2 式の表現

直前エントリ、駄目ぢゃん。

(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> (define n 5)
n
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)))
*** ERROR: invalid application: (1 0 5)
Stack Trace:
_______________________________________
  0  n

gosh> 

やれやれ。どうしたものやら。現時点の手続きは以下。

(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)))))

上の修正は

(list 'fib-iter '(1 0 n))

根がソレなんで

(append (list 'fib-iter) '(1 0 n))

なやり方しか思いつかん。なんかないかなぁ。cons したら良いとか??

gosh> (cons 'fib-iter '(1 0 n))
(fib-iter 1 0 n)
gosh> 

がーん。て事はこれでええんか。

(define (let->combination exp)
  (if (symbol? (cadr exp))
      (list 'begin
	    (list 'define 
		  (cadr exp)
		  (make-lambda (map car (caddr exp)) (cdddr exp)))
	    (cons (cadr exp) (map cadr (caddr exp))))
      (append (list (make-lambda (map car (cadr exp)) (cddr exp)))
	      (map cadr (cadr exp)))))

一応以下の試験にはパス。

  ("let->combination"
   ("first"
    (let ((l '(let ((a 1) (b 2)) (+ a b)))
	  (result '((lambda (a b) (+ a b)) 1 2)))
      (assert-equal result (let->combination l))
      )
    )

   ("second"
    (let ((l '(let ((a 1) (b 2) (c 3)) (+ a b) (+ b c)))
	  (result '((lambda (a b c) (+ a b) (+ b c)) 1 2 3)))
      (assert-equal result (let->combination l))
      )
    )

   ("third"
    (let ((l '(let fib-iter ((a 1) (b 0) (count n)) (if (= count 0) b (fib-iter (+ a b) a (- count 1)))))
	  (result '(begin (define fib-iter (lambda (a b count) (if (= count 0) b (fib-iter (+ a b) a (- count 1))))) (fib-iter 1 0 n))))
      (assert-equal result (let->combination l))
      )
    )

   ("forth"
    (let ((l '(let f ((result set1) (set2 set2))
		(if (null? set2)
		    result
		    (f (adjoin-set (car set2) result) (cdr set2)))))
	  (result '(begin (define f (lambda (result set2)
				      (if (null? set2)
					  result
					  (f (adjoin-set (car set2) result)
					     (cdr set2)))))
			  (f set1 set2))))
      (assert-equal result (let->combination l))
      )
    )
   )

うーん。面白いんですが、問題 4.10 の意味が分からん。(何