I have this example code, which is an undefined language. We want to know what will be printed if we use static versus dynamic scope.
def fun1(a): var z = 1 def sub1(c,e): def sub2(d): print(z) sub2(z) print(z) def sub3(b): var z = 2 var s = 1 sub1(z,2) sub3(z) var z = 0 fun1(3) print(z)
The solution says that under static scoping it will print
1 1 0 and under dynamic scoping it will print
2 2 0.
However, I thought in static scoping the variable bindings are always determined by the most global definition first. Since
z is bound to
0 in the global environment, I would think this always overrides any local bindings, and it should print
0 0 0.
If we use dynamic scoping my understanding is that there are two versions of dynamic scope: deep and shallow binding. Deep binding refers to the binding at definition of the function, and shallow refers to the definition that exists at the call of the function.
If we use deep binding, then I would think: We first call
fun1(3) and here
z=1 for both
sub3. We call
sub3 and that calls
sub1, and that defines
sub2, then calls
sub2(z). At this point
z should be bound to
1 so it prints
1, then prints
z which is still bound to
1. At the end of the program we print
z which in the more global scope is bound to
0 so we get
1 1 0.
If we use shallow binding then since
sub2 is called in
sub1 we use the binding for
z there. Since that binding is defined in the call environment for
sub1, and that was
sub3's environment, then we find that
z=2. This is the binding both inside of
sub1 and inside of
sub2 so we get
2 printed twice. Then in the global environment,
0. All together, we get
2 2 0.
It seems to me like the person who wrote these solutions is confusing static scope with deep binding dynamic scope, and confusing dynamic scope with shallow binding dynamic scope. Or am I the one misunderstanding terms?