(define (make-frame var val)
(cons var val))
(define (frame-variables frame) (car frame))
(define (frame-values frame) (cdr frame))
(define (add-binding-to-frame! var val frame)
(set-car! frame (cons var (car frame)))
(set-cdr! frame (cons val (cdr frame))))
(define (empty-env? env)
(null? env))
(define (env-variables env)
(define (merge x)
(if (null? x)
'()
(append (car x) (merge (cdr x)))))
(merge (map frame-variables env)))
(define (env-values env)
(define (merge x)
(if (null? x)
'()
(append (car x) (merge (cdr x)))))
(merge (map frame-values env)))
(define (enclosing-environment env) (cdr env))
(define (first-frame env) (car env))
(define the-empty-environment '())
(define (lookup-variable-value var env)
(define (lookup variables values)
(if (null? variables)
(error "Unbound variable" var)
(if (eq? var (car variables))
(car values)
(lookup (cdr variables) (cdr values)))))
(lookup (env-variables env) (env-values env)))
(define (set-variable-value! var val env)
(define (lookup-set! variables vals)
(if (null? variables)
(error "Sorry Unbound variable -- SET!" var)
(if (eq? var (car variables))
(set-car! vals val)
(lookup-set! (cdr variables) (cdr vals)))))
(lookup-set! (env-variables env) (env-values env))
'ok)
(define test-env
(list (cons (list 'x 'y 'z) (list 1 2 3))
(cons (list 'a 'b 'c) (list 4 5 6))
(cons (list 'm 'n 'q) (list 7 8 9))))
lookup
程序效果很好,但set
程序无法改变var.So的val值。
Scheme是按值调用,因此我怀疑merge
的返回值与env
不共享对象。但我不明白它为什么不分享。
append
股,map
股,cons
股,(我的意思是(define y (cons x x))
,然后(set-car! x ...)
y
也会发生变化,但是为什么没有定义功能共享?
所以我只想获得env
的所有变量和值(我的意思是剥离帧),然后搜索或设置它们。但我卡在这里。
(define x '(a b c))
(define (y z) (set-car! z 'change))
(y x) => (change b c)
这是有效的,这意味着z
被指向x
的指针取代,或merge
的返回值是" old"的副本,相同但独立?
当merge
(或其他)的形式参数被列表替换时,它是否是指向列表的指针?
按值调用如何在这里工作?
我如何实现自己的想法?
答案 0 :(得分:0)
您可以使用env-values
和env-variables
将这些帧有效地附加到一个列表中。 通过将每个元素复制到新列表来实现此目的。您的set-car!
会更改新列表中的缺点,但不会更改原始env
。
您应该使查找迭代原始帧和变量,并且可能返回保存该值的对。如果没有找到,则抛出类似(error "Unbound variable" var)
的错误。
那样lookup-variable-value
会变成
(define (lookup-variable-value var env)
(car (lookup var env)))
set-variable-value!
将成为:
(define (set-variable-value! var val env)
(set-car! (lookup var env) val))