The overall specification of how the interpreter evaluates a combination
remains the same as when we first introduced it in 1.1.3:
To evaluate a combination:
解释器对组合式 (combinations) 求值的总体规范与我们在 1.1.3 节首次介绍时保持一致:对组合式求值:
Evaluate the subexpressions of the combination.
对组合式的各子表达式求值。
Apply the value of the operator subexpression to the values of the operand
subexpressions.
将运算符子表达式的值作用于各运算对象子表达式的值。
The environment model of evaluation replaces the substitution model in
specifying what it means to apply a compound procedure to arguments.
在说明将复合过程 (compound procedure) 应用于实参意味着什么这一问题上,环境模型取代了代换模型。
In the environment model of evaluation, a procedure is always a pair consisting
of some code and a pointer to an environment. Procedures are created in one
way only: by evaluating a λ-expression. This produces a procedure
whose code is obtained from the text of the λ-expression and whose
environment is the environment in which the λ-expression was
evaluated to produce the procedure. For example, consider the procedure
definition
在求值的环境模型中,一个过程始终是由某段代码和指向某个环境的指针所构成的序对。过程的创建方式只有一种:对 λ 表达式求值。这将产生一个过程对象,其代码来自 λ 表达式的文本,其环境则是对 λ 表达式求值以产生该过程时所处的环境。例如,考虑如下过程定义:
evaluated in the global environment. The procedure definition syntax is just
syntactic sugar for an underlying implicit λ-expression. It would
have been equivalent to have used
在全局环境中求值。过程定义语法不过是底层隐式 λ 表达式的语法糖 (syntactic sugar),与使用下面这种写法等价:
which evaluates (lambda (x) (* x x)) and binds square to the
resulting value, all in the global environment.
它对 `(lambda (x) (* x x))` 求值,并在全局环境中将 `square` 绑定到所得的值。
Figure 3.2 shows the result of evaluating this define expression.
The procedure object is a pair whose code specifies that the procedure has one
formal parameter, namely x, and a procedure body (* x x). The
environment part of the procedure is a pointer to the global environment, since
that is the environment in which the λ-expression was evaluated to
produce the procedure. A new binding, which associates the procedure object
with the symbol square, has been added to the global frame. In general,
define creates definitions by adding bindings to frames.
图 3.2 展示了对这个 `define` 表达式求值的结果。该过程对象是一个序对,其代码部分说明此过程有一个形参,即 `x`,以及过程体 `(* x x)`;其环境部分是指向全局环境的指针,因为正是在全局环境中对 λ 表达式求值才产生了该过程。一个将过程对象与符号 `square` 关联起来的新绑定已被添加到全局框架中。一般而言,`define` 通过向框架中添加绑定来创建定义。
Figure 3.2: Environment structure produced by evaluating (define (square x) (* x x)) in the global environment.
图 3.2:在全局环境中对 `(define (square x) (* x x))` 求值所产生的环境结构。
Now that we have seen how procedures are created, we can describe how
procedures are applied. The environment model specifies: To apply a procedure
to arguments, create a new environment containing a frame that binds the
parameters to the values of the arguments. The enclosing environment of this
frame is the environment specified by the procedure. Now, within this new
environment, evaluate the procedure body.
既然已经了解了过程的创建方式,就可以描述过程的应用方式了。环境模型规定:将过程应用于实参时,创建一个新环境,其中包含一个将各形参绑定到对应实参值的框架;该框架的外围环境就是该过程所指定的环境。然后在这个新环境中对过程体求值。
To show how this rule is followed, Figure 3.3 illustrates the environment
structure created by evaluating the expression (square 5) in the global
environment, where square is the procedure generated in Figure 3.2.
Applying the procedure results in the creation of a new environment,
labeled E1 in the figure, that begins with a frame in which x, the
formal parameter for the procedure, is bound to the argument 5. The pointer
leading upward from this frame shows that the frame’s enclosing environment is
the global environment. The global environment is chosen here, because this is
the environment that is indicated as part of the square procedure
object. Within E1, we evaluate the body of the procedure, (* x x).
Since the value of x in E1 is 5, the result is (* 5 5), or 25.
图 3.3 通过示例说明了上述规则的遵循过程,展示了在全局环境中对表达式 `(square 5)` 求值时所创建的环境结构,其中 `square` 是图 3.2 中生成的过程。应用该过程将创建一个新环境,图中标记为 E1,它以一个框架开始,该框架中过程的形参 `x` 被绑定到实参 `5`。从这个框架向上的指针表明,该框架的外围环境是全局环境——之所以选择全局环境,是因为 `square` 过程对象所指定的就是这个环境。在 E1 内,我们对过程体 `(* x x)` 求值。由于 `x` 在 E1 中的值为 5,结果为 `(* 5 5)`,即 25。
Figure 3.3: Environment created by evaluating (square 5) in the global environment.
The environment model of procedure application can be summarized by two rules:
图 3.3:在全局环境中对 `(square 5)` 求值所创建的环境。
过程应用的环境模型可以用两条规则来概括:
A procedure object is applied to a set of arguments by constructing a frame,
binding the formal parameters of the procedure to the arguments of the call,
and then evaluating the body of the procedure in the context of the new
environment constructed. The new frame has as its enclosing environment the
environment part of the procedure object being applied.
将一个过程对象应用于一组实参时,需构造一个框架,将该过程的各形参绑定到调用时提供的各实参,然后在这个新构造的环境的上下文中对过程体求值。新框架的外围环境就是被应用的过程对象的环境部分。
A procedure is created by evaluating a λ-expression relative to a
given environment. The resulting procedure object is a pair consisting of the
text of the λ-expression and a pointer to the environment in which
the procedure was created.
过程是通过在给定环境中对 λ 表达式求值而创建的。所得到的过程对象是一个序对,由 λ 表达式的文本和指向创建该过程时所在环境的指针组成。
We also specify that defining a symbol using define creates a binding in
the current environment frame and assigns to the symbol the indicated
value. Finally, we
specify the behavior of set!, the operation that forced us to introduce
the environment model in the first place. Evaluating the expression
(set! ⟨variable⟩ ⟨value⟩) in some environment locates the
binding of the variable in the environment and changes that binding to indicate
the new value. That is, one finds the first frame in the environment that
contains a binding for the variable and modifies that frame. If the variable
is unbound in the environment, then set! signals an error.
我们还规定,使用 `define` 定义一个符号会在当前环境框架中创建一个绑定,并将指定的值赋给该符号。最后,我们规定 `set!` 的行为——正是这个操作迫使我们引入了环境模型。在某个环境中对表达式 `(set! ⟨variable⟩ ⟨value⟩)` 求值时,将在该环境中找到该变量的绑定,并将其修改为指示新的值。也就是说,找到环境中第一个包含该变量绑定的框架并对其进行修改。若该变量在当前环境中未被绑定,则 `set!` 将发出一个错误信号。
These evaluation rules, though considerably more complex than the substitution
model, are still reasonably straightforward. Moreover, the evaluation model,
though abstract, provides a correct description of how the interpreter
evaluates expressions. In Chapter 4 we shall see how this model can
serve as a blueprint for implementing a working interpreter. The following
sections elaborate the details of the model by analyzing some illustrative
programs.
这些求值规则虽然比代换模型复杂得多,但仍然相当直观。此外,这个环境模型虽然是抽象的,却对解释器如何对表达式求值给出了正确的描述。在第 4 章中,我们将看到如何以这一模型为蓝图来实现一个能正常运行的解释器。以下各节将通过分析若干示例程序来阐述该模型的细节。
(define (square x)
(* x x)) (define square
(lambda (x) (* x x)))