Would the OCaml expression let x = 5 in (let x = 6 in x)
evaluate differently for dynamic vs lexical (static) scoping?
when would an expression evaluate differently for dynamic vs lexical scoping besides in function application/function closure?
Would the OCaml expression let x = 5 in (let x = 6 in x)
evaluate differently for dynamic vs lexical (static) scoping?
when would an expression evaluate differently for dynamic vs lexical scoping besides in function application/function closure?
In your example, static and dynamic scope coincide, so it would behave the same under both interpretations. Functions, or other constructs that have the ability to delay computations (e.g., lazy thunks), would be the only way to make them diverge.
For example, with functions:
let x = 1 in
let f () = x in
let x = 2 in
f () -- 1 under static scoping, 2 under dynamic scoping
Or similarly, with laziness:
let x = 1 in
let y = lazy x in
let x = 2 in
force y -- 1 under static scoping, 2 under dynamic scoping
(Of course, a lazy thunk is a function under the hood. And combining laziness with dynamic scoping is an even worse idea than dynamic scoping already is.)
Let's reformat your example slightly:
This is an expression in OCaml and the
let x = 6 in x
local binding shadows the first, so this is effectively:Or just:
None of this involves function application, and OCaml implements lexical scoping rather than dynamic scoping.
Let's say it did involve functions.
The function
print_x
does create a closure over the portion of the program wherex
is bound to the value6
. Introducing a newx
binding subsequently will not alter its behavior.Now of course, if we were to use explicit mutable state, we could alter it.
Now we can subsequently update
x
and change the behavior ofprint_x
as long as the namex
is not shadowed by a later binding.In order to avoid that possibility you might want to use a module which encapsulates this part of the program.