I am self-learning Michael L. Scott’s Programming Language Pragmatics. The following quote explains how deep binding and shallow binding are different in the presence of static scoping:
program binding_example(input, output); procedure A(I : integer; procedure P); procedure B; begin writeln(I); end; begin (* A *) if I > 1 then P else A(2, B); end; procedure C; begin end; begin (* main *) A(1, C); end.
Figure 3.15 contains a Pascal program that illustrates the impact of
deep binding rules in the presence of static scoping. When B is called via formal parameter P, two instances of I exist. Because
the closure for P was created in the initial invocation of A, B uses
that invocation’s instance of I in its writeln statement, and the
output is a 1.With shallow binding it would print a 2.
-
Firstly I am new to Pascal. Is it correct that in the program, there
are four separate parts:-
the definition of procedure
A
, which only defines procedureB
-
a block named
A
-
the definition of procedure
C
-
a block named
main
?
When executing the program,
-
is the block
main
first executed and then the blockA
? -
Why does it say that “When B is called via formal parameter P, two instances of I exist”?
-
-
Now to understand the difference between deep and shallow bindings
in the presence of static scoping-
Why in the presence of static scoping and deep binding, does the program print
1
? -
Why in the presence of static scoping and shallow binding, does the program print
2
?
-
Thanks.
2
Firstly I am new to Pascal. Is it correct that in the program, there are four separate parts…
The general construct is that of an entity with (a) nested definitions, and, (b) one body.
So, A
& C
are nested within (program) binding_example
, and, B
is nested within (procedure) A
.
When executing the program,
is the block main first executed and then the block A?
Sort of, but not exactly. Flow of control is initially transferred to the first line of the program body. Since that line of code invokes A
, the program body is suspended, a copy of A
is activated with the relevant parameters from the program body statement, and flow of control is transferred to the first line of A
s body and with that new activation.
Why does it say that “When B is called via formal parameter P, two instances of I exist”?
Because A
is a recursive function. It invokes itself as you can see in A
‘s body. Thus, if you follow the logic and flow of control, there will be two copies of A
activated at one point in the execution of the program. Since A
defines I
, if there are two A
s, then there are two I
s.
First, the bindings only work one way here. The mention of shallow bindings, in this example, are only hypothetical.
Which is to say that the author is making the point that if the language worked differently, well, it would work differently…
(Personally, I’m not a big fan of hypothetical alternatives as tutorial material — I find them often poorly thought through.)
As the author is not fully explaining how this hypothetical and different language would work, we are best just taking author’s point that deep bindings end up choosing the first activation of A
, since that is the environment that conjures the actual parameter B
.
Why in the presence of static scoping and deep binding, does the program print 1?
Because when A
is first activated, that in some sense, creates a B
that can now be referenced (without an A
we don’t have a B
to use). Now, A
chooses to reference its B
, and, that B
knows about its A
, and hence about A
‘s I
, which holds, 1
, after all. Now A
is recursively invoked, which creates a second activation of A
, having its own I
, whose value is 2
. Now that second A
invokes P
, which is the first A
s B
, so 1
is printed.
Why in the presence of static scoping and shallow binding, does the program print 2?
As I mentioned, this is just a hypothetical case, and I don’t consider it fully baked because the text of the procedures would not make sense as such and would also have to change to satisfy this hypothetical pascal that had instead shallow bindings.
9