有很多方法可以做到这一点。这个
classical way
使用列表:
(define (variable name value env)
(cons (cons name value) env))
(define (get-value name env)
(let ((val (assq name env)))
(if val
(cdr val)
(error "Unbound variable" name)))) ; for r6rs use raise
;; the empty environment
(define the-empty-environment '())
Al Petrofsky制造
eiod
(在一个定义中求值)它是这样做的:
;; actually called extend
(define (variable name value env)
(lambda (i) (if (eq? name i) value (env i)))
;; just a wrapper, no need for it since you can just call env with the name
(define (get-value name env)
(env name))
;; the empty environment
(define (the-empty-environment i)
(error "Unbound variable" i))
在里面
SICP
您有带绑定的框架:
;; actually called extend-environment
(define (variables vars vals env)
(if (= (length vars) (length vals))
(cons (make-frame vars vals) env)
(if (< (length vars) (length vals))
(error "Too many arguments supplied" vars vals)
(error "Too few arguments supplied" vars vals))))
;; actualy called lookup-variable-value
(define (get-value var env)
(define (env-loop env)
(define (scan vars vals)
(cond ((null? vars)
(env-loop (enclosing-environment env)))
((eq? var (car vars))
(car vals))
(else (scan (cdr vars) (cdr vals)))))
(if (eq? env the-empty-environment)
(error "Unbound variable" var)
(let ((frame (first-frame env)))
(scan (frame-variables frame)
(frame-values frame)))))
(env-loop env))
;; the empty environment
(define the-empty-environment '())
;; referenced
(define (enclosing-environment env) (cdr env))
(define (first-frame env) (car env))
(define (make-frame variables values)
(cons variables values))
(define (frame-variables frame) (car frame))
(define (frame-values frame) (cdr frame))
请注意,与其他添加一个的方法不同,这会添加一个完整的集合。例如绑定
x
到
5
和
y
到
7
您可以:
(variables '(x y) '(5 7) env)
我将补充我自己的观点:
(define (variable var val env)
(hash-set env var val))
(define (get-value name env)
(hash-ref env name (lambda () (error "Unbound variable" name))))
;; the empty environment
(define the-empty-environment '#hasheq())
这个答案的要点是,如果您可以选择
get-value
,
variable
和
the-empty-environment
. 只要您能够实现这些,如何实现其实并不重要。您可以用一个替换另一个,解释器仍然可以工作。这是除了SICP之外的一个要求你一次做一帧的操作。