Page:Scheme - An interpreter for extended lambda calculus.djvu/22



Section 4: Some Implementation Issues
The key problem is efficiency. Although it is easy to build an inefficient interpreter which straightforwardly performs expression substitutions; such an interpreter performs much unnecessary copying of intermediate expressions. The standard solution to this problem is to use an auxiliary structure, called the environment, which represents a set of virtual substitutions. Thus, when evaluating an expression of the form

instead of reducing it by performing

we reduce it to

where   creates a new environment  in which the   are logically paired with (i.e. "bound to") the corresponding   (the precise meaning of   will be explained presently), and in which any variables not in   are bound as they were in.

When using environments, it is necessary to keep them straight. For example, the following expression should manage to evaluate to 7:

A substitution interpreter would cause the free occurrence of  in the inner lambda expression to be replaced by   before applying that lambda expression to. An interpreter which uses environments must arrange for the expression  to be evaluated in an environment such that   is bound to   and   is bound to. This implies that when the inner lambda expression is applied to, there must be associated with it an environment in which   is bound to. In order to solve this problem we introduce the notion of a closure [McCarthy] [Moses] which is a data structure containing a lambda expression, and an environment to be used when that lambda expression is applied to arguments. We will notate a closure using the beta construct (our own notation, but isomorphic to the LISP funarg construct) as follows:

When a lambda expression is to be evaluated, because it was passed as an argument, it evaluates to a closure of that lambda expression in the environment it is evaluated in (i.e., the environment it was passed from):