;; Exercise 4.13
我认为make-unbound!应该只删除第一个frame里面的约束。我的原因有一下几点:
1,make-unbound!和define对应,前者是删除约束,而后者是添加约束(有时是改变已有的约束)。define是在第一个frame中定义约束,所以make-unbound!也应该是从第一个框架中删除约束。
2,根据封装的原则,不应该在当前environment中删除第一个frame之外的约束。
下面假设我们的eval是data-driven的方式实现的(参加exercise 4.3)。
;; Exercise 4.13
(define (unbound-var-in-frame! var frame)
(let ((new-vars '())
(new-vals '()))
(define (scan vars vals)
(cond ((null? vars) 'done)
((eq? var (car vars))
(scan (cdr vars) (cdr vals)))
(else
(begin
(set! new-vars (cons (car vars) new-vars))
(set! new-vals (cons (car vals) new-vals))
(scan (cdr vars) (cdr vals))))))
(scan (frame-variables frame)
(frame-values frame))
(set-car! frame new-vars)
(set-cdr! frame new-vals)
'ok))
(define (eval-make-unbound! exp env)
(unbound-var-in-frame! (cadr exp) (first-frame env)))
(put 'make-unbound! eval-make-unbound!)
下面是测试结果:
;;; M-Eval input:
(define a 1)
;;; M-Eval value:
ok
;;; M-Eval input:
(define b 2)
;;; M-Eval value:
ok
;;; M-Eval input:
(make-unbound! b)
;;; M-Eval value:
ok
;;; M-Eval input:
a
;;; M-Eval value:
1
;;; M-Eval input:
b
. . data_structure.rkt:55:8: Unbound variable b