Lexical Scoping and sharing objects
Consider the make-account procedure in SICP.
(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)
And the example:
(define peter-acc (make-account 100)) (define paul-acc peter-acc)
And the footnote:
The phenomenon of a single computational object being accessed by more than one name is known as aliasing. The joint bank account situation illustrates a very simple example of an alias.
Bugs can occur in our programs if we forget that a change to an object may also, as a “side effect,” change a “different” object because the two “different” objects are actually a single object appearing under different aliases. These so-called side-effect bugs are so difficult to locate and to analyze that some people have proposed that programming languages be designed in such a way as to not allow side effects or aliasing
In normal situations, I would here people say: "paul-acc refers to peter-acc".
As I understand it, peter-acc and paul-acc are really names that point to one computational object. So they are the same.
I am confused as to how it would be modeled in the environment model of evaluation. For example:
(define (f bank-account) ((bank-account 'deposit) 69)) (define peter-acc (make-account 100)) (define paul-acc peter-acc) (f paul-acc)
I cannot do environment diagrams because my eyes are destroyed. Here's what I think the interaction should be:
- make-account and f have pointers to the global environment.
- (define peter-acc (make-account 100)) is evaluated. make-account creates a new environment e1. Enclosing environment is global. The internal procedures withdraw, deposit and dispatch are created and have pointers to e1. Dispatch is returned and is bound to the name peter-acc in the global environment.
- (define paul-acc peter-acc) is evaluated. The name peter-acc is found in the global frame. paul-acc is bound to the dispatch procedure object in e1 because that is where peter-acc is pointing to. Therefore, Dispatch in e1 is bound to the names peter-acc and paul-acc in the global environment.
- (f paul-acc) is evaluated. A new environment e2 is created by f. Enclosing environment is global. paul-acc is found in global. In e2, banck-account is bound to the dispatch procedure object in e1 because that is where paul-acc is pointing to. Therefore, peter-acc with respect to the global environment, paul-acc with respect to the global environment, and bank-acount with respect to e2 all point to the dispatch procedure in e1.
- The body gets executed.
Is this all correct?
The thing that confuses me is when I encounter things like this in SICP exercises, when constructing environment diagrams, I read people on the web saying things like "bank-account refers to paul-acc. Paul-acc refers to peter-acc." Why exactly is the word "refers" used here? Does bank-account with respect to e2 actually point to the name paul-acc and not it's value?