乐正

Actions speak louder than words.

Sicp-ex4-11

问题

我们完全可以不把框架表示为表的序对,而是表示为约束的表,其中的每个约束是一个名字-值序对。请重写有关的环境过程,采用这种新的表示方式。

解答

练习4.11 (ex4-11.scm) download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
(define (enclosing-envrionment env) (cdr env))

(define (first-frame env) (car env))

(define the-empty-environment '())

(define (make-frame . variable-value-pairs)
  variable-value-pairs)

(define (frame-variables frame)
  (if (null? frame)
      '()
      (cons (car (car frame))
            (frame-variables (cdr frame)))))

(define (frame-values frame)
  (if (null? frame)
      '()
      (cons (cdr (car frame))
            (frame-values (cdr frame)))))

(define (add-binding-to-frame! var val frame)
  (cons (cons var val) frame))

(define (extend-environment var-val-pairs base-env)
  (cons (apply make-frame var-val-pairs) base-env))

(define (lookup-variable-value var env)
  (define (env-loop env)
    (define (scan frame)
      (cond ((null? frame)
             (env-loop (enclosing-envrionment env)))
            ((eq? var (car (car frame)))
             (cadr (car frame)))
            (else (scan (cdr frame)))))
    (if (eq? env the-empty-environment)
        (error "Unbound variable" var)
        (scan (first-frame env))))
  (env-loop env))

(define (set-variable-value! var val env)
  (define (env-loop env)
    (define (scan frame)
      (cond ((null? frame)
             (env-loop (enclosing-envrionment env)))
            ((eq? var (car (car frame)))
             (set-cdr! (car frame) val))
            (else (scan (cdr frame)))))
    (if (eq? env the-empty-environment)
        (error "Unbound variable - SET!" var)
        (scan (first-frame env))))
  (env-loop env))

(define (define-variable! var val env)
  (define (scan frame)
    (cond ((null? frame)
           (add-binding-to-frame! var val frame))
          ((eq? (car (car frame)))
           (set-cdr! (car frame) val))
          (else (scan (cdr frame)))))
  (scan (first-frame env)))

测试

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
(define foo (make-frame (cons 'hello 3) (cons 'world 4)))
;Value: foo

foo
;Value 40: ((hello . 3) (world . 4))

(frame-variables foo)
;Value 41: (hello world)

(frame-values foo)
;Value 42: (3 4)

(define bar (extend-environment (list (cons 'nidaye 6)) foo))
;Value: bar

bar
;Value 48: (((nidaye . 6)) (nihao . 5) (hello . 3) (world . 4))

draft

« sicp-ex4-10 sicp-ex4-12 »

Comments