start by drawing it:
The bindings Y=6 and Z=3 are added to the global frame G.
The third DEFINE has an implicit lambda, which makes the procedure
P1: params (x),
body (set! .
and adds the binding FOO=P1 to G.
The fourth DEFINE similarly makes
P2: params (z),
body (foo 10),
and adds the binding BAR=P2 to G.
So far, everything has happened in the global environment, because we
called any procedures.
Now we have to start being careful about scope.
To evaluate (bar (foo y)) we first evaluate the subexpressions (with
The value of BAR is P2.
(FOO 7) is a procedure call,
we evaluate in the same way:
FOO (in G) is P1; 7 is self-evaluating.
Now we call P1 with argument 7.
To do that, we make a frame in which the formal parameter [X] is bound to
the actual argument value .
Which frame does it extend?
scope, it extends the environment in which it was created, namely G.
dynamic scope, it extends the current environment, which is also G.
this procedure call it doesn't matter which rule we're following.
Now, with E1 as current environment, we evaluate the body of P1, which
The first is (SET! Y (+ X Y Z)).
We start by
the procedure call (+ X Y Z).
We find these bindings:
+ = addition primitive, in G
X = 7, in E1
Y = 6, in G
Z = 3, in G
So the result of the addition primitive is 7+6+3 = 16.
Now we do the
which modifies the binding of Y, in G, to 16.