Quirksand

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:

make-withdraw frames

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:

W1 defined

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:

W1 called with '50'

The result is a change to the value of balance in the reference environment of W1. After the call, the picture looks like this:

after withdrawal of 50

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.

procedure W2 created

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.

Solutions 3.2.3