bli00
bli00

Reputation: 2787

Static Scoping vs Dynamic Scoping

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

Answers (1)

Jeffrey Scofield
Jeffrey Scofield

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

Related Questions