如果一个过程内有表示状态的变量,这个变量的作用范围只在这个过程内,而在过程外部是无法访问这个变量的。那么显然,定义这个过程对象之后,需要维持一个环境,在该环境中保存了上述提到的变量的值,并且这个值是可以变化的。其实,过程的形式参数也是只能在过程内访问的,所这个过程也必须维持形参的值。当前过程作用的环境对它的外围环境具有屏蔽作用,也就是,当这个环境包含的变量的值,会被首先访问,如果过程执行中包含的变量不在当前环境中,那么会到当前环境指向的外围环境中去寻找,直到找打为止,否则报错“Undefined identifier”。
求值规则表明:首先要求各子表达式的值;然后将运算符作用于运算对象。各子表达式可能是基本过程如+、-、*、/,也可能是定义的lambda表达式,每个求值过程都要指定环境,在这个环境层次中,所有的子表达式必须有意义。基本的过程如上如的加减乘除系统默认的是全局环境,也就是它没有外围环境了,其他自定义的过程,都是在这个全局环境之下。
define表达式,不同于一般的基本过程,它比较特殊。求值define表达式,将在define所在的环境中建立一个过程对象,这个过程对象有一个序对组成,分为代码部分和环境部分。代码部分是所定义的lambda表达式的过程体;环境部分是一个指向某一个环境的指针。这个环境可能是全局,也可能是局部,由define的位置决定。scheme语言允许嵌套定义,被嵌套的过程对象所指向的环境,就是包围它的过程的环境。
(define (sqrt x)
(define (good-enough? guess)
(< (abs (- (square guess) x)) 0.001))
(define (improve guess)
(average guess (/ x guess)))
(define (sqrt-iter guess)
(if (good-enough? guess)
guess
(sqrt-iter (improve guess))))
(sqrt-iter 1.0))
上面定义的sqrt过程中,嵌套定义了三个内部过程。sqrt在全局环境下,也就是它的过程对象的环境部分的指针指向全局环境,而内部的三个过程good-enough?、improve和sqrt-iter,他们和sqrt的形成x处于同一个环境中,就是当应用sqrt这个过程时,解释器为创建的临时环境,应用结束后环境销毁。