Local State ----------- Sometimes functions return different values, even when called with same arguments. If (barney 23) doesn't always return the same value, then we say that "barney has state". Can change values of bindings with set!. Three examples involving automatic teller machines (ATMs) ;global state (define balance 0) (define atm-1 (lambda (amt) (set! balance (+ balance amt)) balance)) ;no state (define atm-2 (lambda (amt) (let ((balance 0)) (set! balance (+ balance amt)) balance))) ;local state (define atm-3 (let ((balance 0)) (lambda (amt) (set! balance (+ balance amt)) balance))) (atm-1 10) ==> ????? depends on what the value of balance is! if balance ==> 10 then (atm-1 10) ==> 20 as long as no intervening computation! e.g., balance ==> 10 (call-any-procedure-at-all) (atm-1 10) ==> ??? because computation might have changed balance (atm-2 10) ==> 10 always! the local variable balance is created with value 0 on each call to atm-2, rebound to 10, and then returned. (atm-3 10) ==> ??? depends on the value of the local state variable balance if (atm-3 0) ==> 10 then (atm-3 10) ==> 20 even if intermediate computation, as long as the intermediate thing does not call atm-3. atm-3 is the ONLY procedure that can change the local state variable balance. -------------------------------------------------------------------------- (define make-account (lambda (balance) (lambda (amt) (set! balance (+ balance amt)) balance))) (define betty-acct (make-account 10)) (define barney-acct (make-account 10)) What is the type of betty-acct? (barney-acct 20) ==> 30 (betty-acct 100) ==> 110 Barney and Betty now have separate accounts, with different balances! ---------------------------------------------------------------------- LOCAL STATE: * Packaging up state variables and their associated computation. * Another abstraction mechanism. In general we use local state variables rather than global ones because code is "safer", in the sense that only certain procedures can have access to these local variables. Think of "data objects with local state". One way of organizing a system that has objects with local state is the message passing style that we saw earlier in the semester. Now each object not only knows how to process certain messages, it also has local state variables that are particular to each INSTANCE or version of the object of a given TYPE.