Quirksand

SICP

SICP 3.2.4 Solutions

November 19, 2017 11:27

Section 3.2 finishes off with one more single exercise. It’s another one that relies on working by hand and thinking through the environment structure. There are no files to test, but there will be a bunch of diagrams to look at.

Exercise 3.11.

We’re going to go through this one line at a time, and show the diagrams that result after each statement.

(define acc (make-account 50))

In order to define acc, the make-account procedure is run. This will be executed in an environment (E1 below) created within the global environment, because the global environment is the reference environment for make-account. Once the internal defines are executed, three procedures will exist in this new environment. Then, one of them is returned and that procedure is bound to acc in the global environment.

Here’s the picture after the definition of acc:

"Environments with acc defined"

Next, we make a deposit.

((acc 'deposit) 40)

The first thing that happens is that acc is called. Since acc has E1 as its reference environment, the execution frame for it is created there. That leads to this:

"Starting dispatch for deposit"

The call to acc will return the deposit procedure defined in E1. That procedure is then called with the argument 40. This is executed in a new frame made in E1, which is the reference environment for deposit. I labeled this as E11a, to emphasize that it’s not actually the same as the one in which acc was executed. The picture looks similar, however:

"Execution of deposit procedure"

When the whole statement is finished, we end up with this situation. The balance, as defined in E1, is now 90.

"Completion of deposit"

Now, the withdrawal.

((acc 'withdraw) 60)

This line works almost identically to the previous. The procedure acc is called with m bound to the symbol 'withdraw:

"Starting dispatch for withdrawal"

The result of that is a call to withdraw (not shown, but identical to the earlier call to deposit) with its argument set to 60. The withdraw procedure changes balance in E1, and thus we have this situation once the line is finished:

"Completion of withdrawal"

The exercise goes on to ask where the local state for acc is kept, and how it is kept distinct if we make another account. This can be explained with a diagram showing the full environment structure after the creation of the second account:

"Environments for two accounts"

Each call to make-account creates new procedure objects for deposit, withdraw, and dispatch. They are all defined internally in the execution frame that is created for make-account. This environment is preserved since the account variable in the global environment (acc or acc2) makes reference to it. This is, then, where the local state is kept – the balance variable is held there, and the ‘internal’ procedures will operate on it.

The only thing actually shared between the accounts is the code for the internal procedures. This is distinct from the procedure objects themselves (depicted in the environment diagram as two circles), which share one enclosing environment per account.

There’s no need to check any results, so there is no solution file for this section.