Lexical vs Dynamic Scope Makes No Difference in Functional Programing

By Xah Lee. Date: . Last updated: .

Lexical vs Dynamic Scope Makes No Difference in Functional Programing

is this true. If you write your code in a pure functional programing style, Lexical vs Dynamic Scope makes no difference.

ai answer

No, this is not true. Even in a pure functional programming style (no side effects, no mutation, referential transparency), lexical scoping vs. dynamic scoping still makes a significant difference.

Why the difference persists

In pure FP, functions are first-class and often return other functions (higher-order functions). The key issue is how free variables (variables used inside a function but defined outside it) are resolved — especially in closures.

This affects behavior even without any mutation or I/O.

Counterexample (in pseudocode)

# Lexical version (like Python, Haskell, Scheme, ML, etc.)
def make_adder(n):          # n is captured at definition time
    def adder(x):
        return x + n        # free variable n from lexical scope
    return adder

add5 = make_adder(5)
print(add5(10))  # → 15  (always uses the n=5 from where adder was created)

Now imagine the same code but with dynamic scoping:

# Dynamic scoping version
def make_adder(n):
    def adder(x):
        return x + n        # n looked up at call time
    return adder

add5 = make_adder(5)

# Later, in a different context:
def test():
    n = 100             # shadows the earlier n
    return add5(10)     # dynamic lookup finds n=100 here

print(test())  # → 110  (not 15!)

Even though everything is pure (no mutation, same inputs produce deterministic outputs within one scoping rule), the meaning of the returned function changes depending on where you call it under dynamic scoping. Under lexical scoping, it is fixed at creation time.

Why this matters in pure FP

Pure functional languages (Haskell, OCaml, Elm, etc.) all use lexical scoping for these reasons. Dynamic scoping is rare in modern FP exactly because it causes these issues.

When the claim is sort of true

If you write extremely restrictive code — no higher-order functions, no returning lambdas, no free variables at all — then yes, the difference mostly disappears. But that's not "pure functional style"; that's basically avoiding the powerful parts of FP. As soon as you use closures (which pure FP encourages), scoping matters a lot.

The statement you saw is an oversimplification (it appears in some X/Twitter posts). In practice, lexical scoping is strongly preferred in functional programming for good reason.

Lexical vs Dynamic Scope in a Term Rewriting System