I am working my way through SICP. I am on Section 3.1.1 and looking at local state. I am evaluating these exercises in GNU Guile v2.0.11.
I did find a similar question about this section, but it seems not to address the point I am struggling with, or I am overly obtuse.
The two examples I am looking at are these:
(define new-withdraw
(let ((balance 100))
(lambda (amount)
(if (>= balance amount)
(begin (set! balance (- balance amount))
balance)
"Insufficient funds"))))
(define (make-withdraw balance)
(lambda (amount)
(if (>= balance amount)
(begin (set! balance (- balance amount))
balance)
"Insufficient funds")))
When I assign the first to a variable with:
(define a new-withdraw)
(define b new-withdraw)
I get two pointers to the same procedure object and the state is shared between them:
scheme@(guile-user)> a
$1 = #<procedure 1165880 at /path/to/file (amount)>
scheme@(guile-user)> b
$2 = #<procedure 1165880 at /path/to/file (amount)>
scheme@(guile-user)> (a 50)
$3 = 50
scheme@(guile-user)> (b 10)
$4 = 40
When I implement the second procedure, though, I get pointers to two distinct procedure objects with distinct state:
scheme@(guile-user)> (define c (make-withdraw 100))
scheme@(guile-user)> (define d (make-withdraw 100))
scheme@(guile-user)> c
$5 = #<procedure 14fdac0 at /path/to/file (amount)>
scheme@(guile-user)> d
$6 = #<procedure 1508360 at /path/to/file (amount)>
scheme@(guile-user)> (c 50)
$7 = 50
scheme@(guile-user)> (d 10)
$8 = 90
I've read through the section and there is no clear explanation of this, and I'm having trouble finding anything when I search for this section. I understand what is happening in terms of state in general, but I don't get what the difference between these procedures is that allows one to have a single universal state, and the other to maintain local state.
Why is the first definition, 'new-withdraw', unable to maintain local state across multiple assignments? It seems that the lambda should be capturing the assignment of balance to 100 every time we make a different assignment (define new-withdraw).