2013年9月4日水曜日

開発環境

計算機プログラムの構造と解釈(Gerald Jay Sussman(原著)、Julie Sussman(原著)、Harold Abelson(原著)、和田 英一(翻訳)、ピアソンエデュケーション、原書: Structure and Interpretation of Computer Programs (MIT Electrical Engineering and Computer Science)(SICP))の4(超言語的抽象)、4.1(超循環評価器)、4.1.3(評価器のデータ構造)、述語のテスト、手続きの表現、環境に対する操作、問題 4.12を解いてみる。

その他参考書籍

問題 4.12

コード(BBEdit)

sample.scm

(define (env-loop var proc-1 proc-2 err-msg env)
  (define (scan vars vals)
    (cond ((null? vars)
           (proc-1 env))
          ((eq? var (car vars))
           (proc-2 vals))
          (else
           (scan (cdr vars) (cdr vals)))))
  (if (eq? env the-empty-environment)
      (error err-msg var)
      (let ((frame (first-frame env)))
        (scan (frame-variables frame)
              (frame-values frame)))))

;; 上記の抽象を使って三つの手続きを再定義
(define (lookup-variable-value var env)
  (env-loop var
            (lambda (env)
              (lookup-variable-value var 
                                     (enclosing-environment env)))
            (lambda (vals)
              (car vals))
            "Unbound variable"
            env))

(define (set-variable-value! var val env)
  (env-loop var
            (lambda (env)
              (set-variable-value! var
                                   val
                                   (enclosing-environment env)))
            (lambda (vals)
              (set-car! vals val))
            "Unbound variable -- SET!"
            env))

(define (define-variable! var val env)
  (env-loop var
            (lambda (env)
              (add-binding-to-frame! var 
                                     val 
                                     (first-frame env)))
            (lambda (vals)
              (set-car! vals val))
            '()
            env))

(define f-1 (make-frame '(a b) (list 1 2)))

(define f-2 (make-frame '(c d) (list 3 4)))

(define e (list f-1 f-2))

最初はset-variable-value!、define-variable!で、set-car!が思うように動かなかった。

理由はフレームを問題4.11の方法で表現してたからで、本書の表現(変数のリストと対応づけられている値のリストの対)を使うと上手くいった。

入出力結果(Terminal, REPL(Read, Eval, Print, Loop))

1 ]=> e

;Value 2: (((a b) 1 2) ((c d) 3 4))

1 ]=> (lookup-variable-value 'a e)

;Value: 1

1 ]=> (lookup-variable-value 'b e) 

;Value: 2

1 ]=> (lookup-variable-value 'c e)

;Value: 3

1 ]=> (lookup-variable-value 'd e)

;Value: 4

1 ]=> (set-variable-value! 'a 10 e)

;Unspecified return value

1 ]=> e

;Value 2: (((a b) 10 2) ((c d) 3 4))

1 ]=> (set-variable-value! 'b 20 e)

;Unspecified return value

1 ]=> e

;Value 2: (((a b) 10 20) ((c d) 3 4))

1 ]=> (set-variable-value! 'c 30 e)

;Unspecified return value

1 ]=> e

;Value 2: (((a b) 10 20) ((c d) 30 4))

1 ]=> (set-variable-value! 'd 40 e)

;Unspecified return value

1 ]=> e

;Value 2: (((a b) 10 20) ((c d) 30 40))

1 ]=> (define-variable! 'e 5 e)

;Unspecified return value

1 ]=> e

;Value 2: (((e a b) 5 10 20) ((c d) 30 40))

1 ]=> (define-variable! 'a 100 e)

;Unspecified return value

1 ]=> e

;Value 2: (((e a b) 5 100 20) ((c d) 30 40))

1 ]=> (define-variable! 'd 400 e)

;Unspecified return value

1 ]=> e

;Value 2: (((d e a b) 400 5 100 20) ((c d) 30 40))

0 コメント:

コメントを投稿