SICP:'set' 和 'define' 在元循环评估器中
SICP:'set' and 'define' in The Metacircular Evaluator
在计算和调用'set-variable-value!'和'define-variable-value!'时,程序会将'env'传递给函数,而在这两个函数中,'set!'只能修改'env' 在函数内部;修改后的 'env' 也不会返回。
那么,'env'怎么改?
请记住,在本书的 3.3 节中,Modeling with Mutable Data 介绍了可变运算符,通过使用在函数名称后缀 !
的约定,如 set-car!
,修改了cons单元的汽车。
函数set-variable-value!
和define-variable-value!
只是修改传递的环境,因此不需要return它。例如,set-variable-value!
是通过使用 set-car!
:
定义的
(define (set-variable-value! var val env)
(define (env-loop env)
(define (scan vars vals)
(cond ((null? vars)
(env-loop (enclosing-environment env)))
((eq? var (car vars))
(set-car! vals val))
(else (scan (cdr vars) (cdr vals)))))
(if (eq? env the-empty-environment)
(error "Unbound variable -- SET!" var)
(let ((frame (first-frame env)))
(scan (frame-variables frame)
(frame-values frame)))))
(env-loop env))
请注意,作者在 Chapter 4 的开头说:
The language implemented by our evaluator will be a subset of the Scheme dialect of Lisp that we use in this book.
由于引入的方言有副作用,实现它的最简单解决方案是在其解释器中也使用副作用。
在计算和调用'set-variable-value!'和'define-variable-value!'时,程序会将'env'传递给函数,而在这两个函数中,'set!'只能修改'env' 在函数内部;修改后的 'env' 也不会返回。
那么,'env'怎么改?
请记住,在本书的 3.3 节中,Modeling with Mutable Data 介绍了可变运算符,通过使用在函数名称后缀 !
的约定,如 set-car!
,修改了cons单元的汽车。
函数set-variable-value!
和define-variable-value!
只是修改传递的环境,因此不需要return它。例如,set-variable-value!
是通过使用 set-car!
:
(define (set-variable-value! var val env)
(define (env-loop env)
(define (scan vars vals)
(cond ((null? vars)
(env-loop (enclosing-environment env)))
((eq? var (car vars))
(set-car! vals val))
(else (scan (cdr vars) (cdr vals)))))
(if (eq? env the-empty-environment)
(error "Unbound variable -- SET!" var)
(let ((frame (first-frame env)))
(scan (frame-variables frame)
(frame-values frame)))))
(env-loop env))
请注意,作者在 Chapter 4 的开头说:
The language implemented by our evaluator will be a subset of the Scheme dialect of Lisp that we use in this book.
由于引入的方言有副作用,实现它的最简单解决方案是在其解释器中也使用副作用。