Chapter 3
3.1 Exercise 3.1
3.2 Exercise 3.2
3.3 Exercise 3.3
3.4 Exercise 3.4
3.5 Exercise 3.5
3.6 Exercise 3.6
3.7 Exercise 3.7
3.8 Exercise 3.8
3.9 Exercise 3.9
3.10 Exercise 3.10
3.11 Exercise 3.11
3.12 Exercise 3.12
3.13 Exercise 3.13
3.14 Exercise 3.14
3.15 Exercise 3.15
3.16 Exercise 3.16
3.17 Exercise 3.17
3.18 Exercise 3.18
3.19 Exercise 3.19
3.20 Exercise 3.20
3.21 Exercise 3.21
3.22 Exercise 3.22
3.23 Exercise 3.23
3.24 Exercise 3.24
3.25 Exercise 3.25
3.26 Exercise 3.26
3.27 Exercise 3.27
3.28 Exercise 3.28
3.29 Exercise 3.29
3.30 Exercise 3.30
3.31 Exercise 3.31
3.32 Exercise 3.32
3.33 Exercise 3.33
3.34 Exercise 3.34
3.35 Exercise 3.35
3.36 Exercise 3.36
3.37 Exercise 3.37
3.38 Exercise 3.38
3.39 Exercise 3.39
3.40 Exercise 3.40
3.41 Exercise 3.41
3.42 Exercise 3.42
3.43 Exercise 3.43
3.44 Exercise 3.44
3.45 Exercise 3.45
3.46 Exercise 3.46
3.47 Exercise 3.47
3.48 Exercise 3.48
3.49 Exercise 3.49
3.50 Exercise 3.50
3.51 Exercise 3.51
3.52 Exercise 3.52
3.53 Exercise 3.53
3.54 Exercise 3.54
3.55 Exercise 3.55
3.56 Exercise 3.56
3.57 Exercise 3.57
3.58 Exercise 3.58
3.59 Exercise 3.59
3.60 Exercise 3.60
3.61 Exercise 3.61
3.62 Exercise 3.62
3.63 Exercise 3.63
3.64 Exercise 3.64
3.65 Exercise 3.65
3.66 Exercise 3.66
3.67 Exercise 3.67
3.68 Exercise 3.68
3.69 Exercise 3.69
3.70 Exercise 3.70
3.71 Exercise 3.71
3.72 Exercise 3.72
3.73 Exercise 3.73
3.74 Exercise 3.74
3.75 Exercise 3.75
3.76 Exercise 3.76
3.77 Exercise 3.77
3.78 Exercise 3.78
3.79 Exercise 3.79
3.80 Exercise 3.80
3.81 Exercise 3.81
3.82 Exercise 3.82

3.10 Exercise 3.10

The new make-withdraw is subtly different from the earlier examples in that the body is not merely a lambda expression, but an immediately- invoked lambda.

(This is somewhat difficult to explain without diagrams, but I’ve put the skeleton of my answer here anyway. It’s probably wrong.)

The first thing we should do before trying to apply the environment model is to fully expand on all syntactic sugar around lambda expressions. When we do this, the definition for make-withdraw is as follows:

(define make-withdraw
  (lambda (initial-amount)
    ((lambda (balance)
       (lambda (amount)
         (if (>= balance amount)
             (begin
               (set! balance (- balance amount))
               balance)
             "Insufficient funds")))
     initial-amount)))

Here, make-withdraw will be a name in the global environment referring to the procedure inside.

When we evaluate the expression (define W1 (make-withdraw 100)), we create a name W1 in the global environment that refers to the result of (make-withdraw 100). When this is evaluated, a new environment, which we’ll call E1, is constructed with the global environment as its parent. It has initial-amount bound to 100. The procedure we are evaluating in this environment has the body

((lambda (balance)
   (lambda (amount)
     (if (>= balance amount)
         (begin
           (set! balance (- balance amount))
           balance)
         "Insufficient funds")))
 initial-amount)

This body is a procedure application, so it creates a new environment, E2, whose parent is the environment in which this procedure was defined – that is, E1. However, the procedure which is being applied is also defined here. So we create a procedure object that takes one parameter, whose defining environment is E2, and with the body

(lambda (amount)
  (if (>= balance amount)
      (begin
        (set! balance (- balance amount))
        balance)
      "Insufficient funds"))

#<procedure>

This procedure object is returned and given the name W1.

Then we evaluate (W1 50). This creates a new environment, E3, whose parent frame is E2, the environment in which the procedure that has the name W1 was defined. We then evaluate the procedure, which updates the balance value stored in E2 from 100, the value initially given from initial-amount in E1, to 50.

Evaluating (define W2 (make-withdraw 100)) makes a parallel procedure and set of environments like W1, with its own private balance.

TODO: Pretty pictures