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:
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?
Your points 2 to 5 are correct. In your point 1, f
and make-account
do not "have" pointers to global environment - they do not need to, by themselves. They are both entries, bindings, in the global environment. Both "refer to", or "point at" simple values, functions in both cases.
bank-account
with respect to e2
actually points to the value to which paul-acc
points (which is the same value to which peter-acc
points, or refers). In Scheme, (define n1 n2)
means "set up new binding in the current environment, named n1
, and pointing at the value of the expression n2
". If n2
happens to be a variable, its value is just what that variable's value is. That's why we're talking about Scheme's evaluation semantics.
A function call (fun arg)
is evaluated by finding the value of arg
expression, binding the function's parameter to this value, and then evaluating the function's body in the resulting environment:
( (lambda (param) body) arg )
=
(let ( (param arg) )
body)