Ex. 4.11
環境変数のフォーマット(p.225)は、例えばこんな感じ
(((x y z) (1 2 3)))
これを、こんな感じに変える
(((x 1)(y 2)(z 3)))
実装、、、無理。省略(^^ゞ
Ex. 4.12
親環境、子環境がある場合の環境変数のフォーマットは、こんな感じ
( ((a b)(10 20)) ((x y z)(1 2 3)) )
向かって右側が親環境であり、左側が子環境である。
従って、環境変数の検索は、まず子環境、親環境と各環境をスキャンする必要がある。
さらに、子環境で、変数 a,b を、親環境で変数 x, y, z と各変数をスキャンする必要がある。
2重スキャンである。この2重スキャンの部分を関数化しろというのが、ここの設問である。
(define (search-env var env)
(define (env-loop env) ;;環境のループ
(define (scan vars vals) ;; 変数のループ
(cond ((null? vars)
(env-loop (enclosing-environment env)))
((eq? var (car vars))
vals)
(else (scan (cdr vars)(cdr vals)))))
(if (eq? env the-empty-environment)
'()
(let (frame (first-frame env))
(scan (frame-variables frame)
(frame-values frame)))))
(env-loop env))
これを使って、lookup-variable-value を定義する
(define (lookup-variable-value var env)
(let ((vals (search-env var)))
(if (null? vals)
(error "Unbound variable" var)
(car vals))))
Ex. 4.13
省略。
ところで、unbind! は、特殊形式でないとダメなんだろうか。
(unbind! 'x env)
という感じで、関数でもいいような気が、、、