Reputation: 2787
Consider the following Ocaml code:
let app f y = let x = 4 in (f y)+1 ;;
let proc x = let change z = z-x in app change (x+3) ;;
(proc 2)
From what I understand, static scoping uses the structure of the code to determine the value of the variables, so in this case, x
is replaced with 2
both in change
and in (x+3)
. However, what I don't understand is why dynamic scoping only replaces the x
in change
with 4
but not the x
in (x+3)
with 4
.
This is a bit confusing, I'm wondering if there's any trick to how to think through these problems.
Upvotes: 1
Views: 1429
Reputation: 66808
A free variable is a variable that's used in a function but isn't defined in the function. In your example code, the only free variable is the variable x
of the function change
:
let change z = z - x
The function change
uses x
but doesn't define it.
The essence of scoping is to determine what variable definition a free variable is referring to, what its referent is. In your example code, it comes down to determining the referent of the free variable x
in the change
function.
For static scoping, there is a single static referent for every free variable. The referent is determined by looking outward in the text of the program through statically containing blocks of code until a binding (a definition) is found. In OCaml, variable bindings are introduced by function definitions and by let
. So you're looking for the nearest enclosing block of change
that binds x
. The nearest binding of x
is the function parameter x
in let proc x =
. For the example call, it has the value 2.
For dynamic scoping, the referent is determined by looking up through the nested function calls that are active at the time the value is required. In other words, you want to find the innermost function in the call chain that defines a variable named x
. If you pretend that OCaml has dynamic scoping (which it most definitely does not), the call chain looks like this:
proc => app => change
The function just outside change
in the call chain is app
, and it defines a variable named x
. So for the example code, the free variable x
of change
refers to the variable x
defined by app
. In the example, it has the value 4
.
The x
in x + 3
is not a free variable. It's defined by proc
and is used in proc
. For the example call it has the value 2 no matter what scoping is used.
For what it's worth I don't think it's particularly useful to think of replacing variables with values. It's better to think of them as being bound to values.
I'd also like to say (though I probably shouldn't) that dynamic scoping is insane. The extra flexibility is definitely not worth the extra complexity in figuring out what's going on. It shouldn't be necessary to trace through chains of function calls to determine the binding of a variable. (In my opinion.)
Upvotes: 2