|Sussman and Steele||December 22, 1975||22||Some Implementation Issues|
(BETA (LAMBDA <vars> <body>) E) in environment E
When a closure is to be applied to some arguments:
((BETA (LAMBDA <vars> <body>) E1) <args>) in environment E2
this is performed by reducing the application expression to
<body> in environment Pairlis[<vars> <args in E2> E1]
That is, any free variables in the closed lambda expression refer to the environment as of the time of closure (
E1), not as of the time of application (
E2), whereas the arguments are evaluated in the application environment as expected.
This notion of closure has gone by many other names in other contexts. In LISP, for example, such a closure has been traditionally known as a funarg. ALGOL has several related ideas. Every ALGOL procedure is, at the time of its invocation, essentially a "downward funarg". In addition, expressions which are passed by name instead of by value are closed through the use of mechanisms called thunks [Ingerman]. It turns out that an actor (other than a cell or a serializer) is also a closure. Hewitt [Smith and Hewitt] describes an actor as consisting of a script, which is code to be executed, and a set of acquaintances, which are other actors which it knows about. We contend that the script is in fact identical to the lambda expression in a closure, and that the set of acquaintances is in effect an environment. As an example, consider the following code for cons; taken from [Smith and Hewitt] (cf. [Fischer]):
[CONS ≡ (≡> [=A =B] (CASES (≡> FIRST? A) (≡> REST? B) (≡> LIST? YES)))]
When the form
(cons x y) is evaluated, the result is an (evaluated)
cases statement, which is a receiver ready to accept a message such as "
first?" or "
rest?". This resulting receiver evidently knows about the actors
y as being bound to the variables
b; it is evidently a closure of the
cases script plus a set of acquaintances which includes
y (as well as "
first?" and "
rest?" and "
yes", for example; PLASMA considers such "constant acquaintances" to be part of the set, whereas in SCHEME we might prefer to consider them part of the script). Once we realize that it is a closure and nothing more, we can see easily how to express the same semantics in SCHEME: