# How to use dynamic scope?

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 sub1 and 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?