SICP 4.1.3 Ex. 4.11 Ex. 4.12 Ex. 4.13

  • 投稿日:
  • カテゴリ:

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)

という感じで、関数でもいいような気が、、、