SICP 読み (177) 4.1.7 構文解析を実行から分離する

問題 4.24 がボリューム大きスギ。その前にスルーしている問題 4.22 を検討。とりあえず、以前の問題でヒネリ出した書き換えな手続きが以下。

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

試験で確認してみる。

  ("4.22"
   ("let->combination (to lambda)"
    (let ((l '(let ((a 1) (b 2)) (+ a b)))
	  (r '((lambda (a b) (+ a b)) 1 2)))
      (assert-equal r (let->combination l))
      )
    )

   ("let->combination (to define)"
    (let ((l '(let f ((a '()) (b '(1 2 3 4)))
		(if (null? b)
		    a
		    (f (cons (car b) a) (cdr b)))))
	  (r '(begin (define f (lambda (a b)
				 (if (null? b)
				     a
				     (f (cons (car b) a) (cdr b)))))
		     (f '() '(1 2 3 4)))))
      (assert-equal r (let->combination l))
      )
    )
   )

この導出された式を analyze すれば良いはずなんですが ...
という事で、analyze に以下を追加。

	((let? exp) (analyze (let->combination exp)))

以下の試験に一応パス。

   ("eval (1)"
    (let ((env (extend-environment '(tmp) '(0) the-global-environment)))
      (let ((l '(let f ((a '()) (b '(1 2 3 4)))
		  (if (null? b)
		      a
		      (f (cons (car b) a) (cdr b))))))
	(assert-equal '(4 3 2 1) (eval l env))
	)
      )
    )

   ("eval (2)"
    (let ((env (extend-environment '(tmp) '(0) the-global-environment)))
      (let ((l '(let ((a 1) (b 2)) (+ a b))))
	(assert-equal 3 (eval l env))
	)
      )
    )

一応ヨシと見て良いのだろうか。てーか、今ごろ気がついたんですが、analyze ってコンパイルなのか。(違

問題 4.24 は time とかでは微妙なのかなぁ。