SICP
SICP 3.2.3 Solutions
November 5, 2017 11:23
Ex. 3.10
To complete a definition, we must determine the value to assign to our variable, which in this case is named W1
. To get that value, a call to make-withdraw
is made. This creates a new frame for that procedure call. In the course of make-withdraw
, the let
statement creates a lambda and calls it, which means another environment is created inside the one created for make-withdraw
. This image depicts what’s going on:
The procedure make-withdraw
returns the lambda statement inside the let, and that will be the value assigned to W1
. Once it is defined, the environment diagram will look like this:
When W1
is next called, with the argument 50
, an execution frame is created. It will be made within the environment that W1
refers to for procedure execution (E11). Let’s call this the ‘reference environment’ of W1
, to make it easier to describe. This results in the following situation when the second line is executed:
The result is a change to the value of balance
in the reference environment of W1
. After the call, the picture looks like this:
For the next step a new withdraw procedure is created, and a completely separate environment chain is produced. It is similar to the first but with distinct variables. Note that the code for the actual procedure body is shared between the procedures (this represents the actual storage in memory of the code). But any calls using W2
will be executed in its reference environment E21, and only affect the variables there.
When we compare this to the text’s version of make-withdraw
, we see that the alternate version involves the creation of an additional environment. In both versions, a new frame is created when make-withdraw
is called. In the second, however, the let
statement causes the creation of another frame, since it executes a lambda within the environment that make-withdraw
uses for evaluation. The lambda
that is returned and assigned to the account is created within that second environment (E11 or E21 above). Although it never again makes use of the first frame (in which initial-value
is defined), that frame still remains in the chain that is the environment.
Both procedures thus work identically, as they only modify the balance
value in the course of their operation. All the let
statement effectively did was rename initial-value
to balance
. The procedures do not rely on anything further back in the chain of frames.
To prove that the two procedures actually do produce identical output, we can run them both through the interpreter. This is the only thing that is checked in the solutions file.