Exercise 3.11. In section 3.2.3 we saw how the environment model described the behavior of procedures with local state. Now we have seen how internal definitions work. A typical message-passing procedure contains both of these aspects. Consider the bank account procedure of section 3.1.1:
(define (make-account balance) (define (withdraw amount) (if (>= balance amount) (begin (set! balance (- balance amount)) balance) "Insufficient funds")) (define (deposit amount) (set! balance (+ balance amount)) balance) (define (dispatch m) (cond ((eq? m 'withdraw) withdraw) ((eq? m 'deposit) deposit) (else (error "Unknown request -- MAKE-ACCOUNT" m)))) dispatch)Show the environment structure generated by the sequence of interactions
(define acc (make-account 50)) ((acc 'deposit) 40) 90 ((acc 'withdraw) 60) 30Where is the local state for
acc
kept? Suppose we define another account(define acc2 (make-account 100))How are the local states for the two accounts kept distinct? Which parts of the environment structure are shared between
acc
andacc2
?
Initial state:
-------------------------
| |
global -->| make-account:--. |
env | | |
-----------------|-------
| ^
| |
@=@--'
|
v
parameters: balance
body: (define ...)
Evaluation of (define acc (make-account 50))
:
-------------------------
| make-account: ... |
global -->| |
env | acc:--. |
--------|----------------
^ |
| `------------.
--------------- |
E1-->| balance: 50 | |
| |<--@ |
| dispatch:------>|<-'
| | @--> parameters: m
| | body: (cond ...)
| |<--@
| withdraw:------>|
| | @--> parameters: amount
| | body: (if (>= ...) ...)
| |<--@
| deposit:------->|
| | @--> parameters: amount
| | body: (set! ...)
---------------
Evaluation of ((acc 'deposit) 40)
:
-------------------------
| make-account: ... |
global -->| |
env | acc:--. |
--------|----------------
^ |
| `--------------.
----------------- |
E1-->| balance: 50 |<--@ | Here is the balance that will be changed
| dispatch:-------->|<-' by the set! in deposit.
| withdraw: ... | @--> ...
| deposit: ... |
-----------------
^ ^
| |
| `-----------------------.
| |
--------------- --------------
E2-------->| m: deposit | E3--->| amount: 40 |
(acc 'deposit) --------------- (... 40) --------------
Evaluation of ((acc 'withdraw) 60)
:
-------------------------
| make-account: ... |
global -->| |
env | acc:--. |
--------|----------------
^ |
| `--------------.
----------------- |
E1-->| balance: 90 |<--@ | Here is the balance that will be changed
| dispatch:-------->|<-' by the set! in withdraw.
| withdraw: ... | @--> ...
| deposit: ... |
-----------------
^ ^
| |
| `-----------------------.
| |
--------------- --------------
E4-------->| m: withdraw | E5--->| amount: 60 |
(acc 'withdraw) --------------- (... 60) --------------
Show the environment structure generated by the sequence of interactions
-------------------------
| make-account: ... |
global -->| |
env | acc:--. |
--------|----------------
^ |
| `--------------.
----------------- |
E1-->| balance: 30 |<--@ |
| dispatch:-------->|<-'
| withdraw: ... | @--> ...
| deposit: ... |
-----------------
Where is the local state for
acc
kept?
E1.
How are the local states for the two accounts kept distinct? Which parts of the environment structure are shared between
acc
andacc2
?
After evaluating (define acc2 (make-account 100))
, the environment will be as follows:
---------------------------
| make-account: ... |
global -->| |
env | acc2:--------------------------------------------------.
| | |
| acc:-----------------. | |
-----------------------|--- |
^ ^ | |
| | | |
| `-------------------+-----------. |
| | | |
----------------- | ----------------- |
E1-->| balance: 30 |<--@ | E6-->| balance: 100 |<--@ |
| dispatch:-------->|<-' | dispatch:-------->|<-'
| withdraw: ... | @--> ... | withdraw: ... | @--> ...
| deposit: ... | | deposit: ... |
----------------- -----------------
Each local state is a frame which is created to apply make-account
.
In our model, internal definitions of make-account
are evaluated each time,
so that only the global environment is shared.
But resulting internal definitions of acc
and acc2
are mostly same. Only
the parent frames are differ. So that code parts of procedures objects may be
shared.