Reputation: 2551
I am trying to fully understand Objects and local states of their variables
This code seems to produce different results for the same procedure called multiple times, meaning the local variable changes:
(define new-withdraw
(let ((balance 100))
(lambda (amount)
(if (>= balance amount)
(begin (set! balance (- balance amount))
balance)
"Insufficient funds"))))
For this other code, it produces the same result, which means it creates a new local variable for every procedure call:
(define (make-account)
(let ((balance 100))
(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))
My questions are:
Why do they behave differently despite creating a local variable using let?
Is there a way one can make the second code work as the first one without passing balance
as a parameter of make-account
?
Thank you
Upvotes: 1
Views: 462
Reputation: 18917
Testing code 1:
> (new-withdraw 0)
100
> (new-withdraw 50)
50
> (new-withdraw 10)
40
Testing code 2:
> (define ac (make-account))
> ((ac 'withdraw) 0)
100
> ((ac 'withdraw) 50)
50
> ((ac 'withdraw) 10)
40
So both codes keep their local state. The difference between code 1 and code 2 is that code 1 works for one account only, whereas code 2 "creates a new account" on each call - the call to the procedure returns the dispatching procedure that you need to bind to a variable, and then use as shown above.
Therefore you get the impression that the local state is lost; it's not, you were probably creating a new account every time.
Upvotes: 2