Static and Dynamic Scoping

Dear Computer

Chapter 2: Naming Things

Static and Dynamic Scoping

When we access a variable that is declared in the current scope, that variable is a bound variable. A variable that is not bound in the current scope is a free variable. This function h accesses two variables:

JavaScript
function h() {
  const angle = 360;
  return angle / n;
}

Within h, variable angle is bound and variable n is free. Is this reference to n legal?

How should a programming language handle free variables? Some possible options include:

Let's examine the difference between static and dynamic scoping with this pseudocode:

function main()
  int a = 1
  int b = 2

  function f()
    int a = 0
    b += 1
    print(a, b)

  function g()
    int b = 4
    print(a, b)
    f()
    print(a, b)

  print(a, b)
  g()
  print(a, b)

With static scoping, we identify which variables are accessed by looking only at the nesting of scopes in the code. A compiler assembles an environment data structure, which is a table of all visible variables and the scope from which they are drawn.

With dynamic scoping, the nesting of scopes is not considered when determining the environment. Instead, we must traverse the call stack. In general, we can't determine the environment just by looking at the code, as the sequence of function calls may be unpredictable. However, this particular pseudocode is predictable.

Explore how the program behaves under static scoping by stepping through from print statement to print statement.

Contrast this with dynamic scoping, which gives a different result.

Dynamic scoping is harder to reason about than static scoping because it depends on runtime behavior. You won't see it in many languages. Perl supports it through the poorly named local modifier. Unix environment variables are dynamically scoped. If one process sets an environment variable, any processes it spawns will see the same environment variables. Despite its unpopularity, we mention dynamic scoping here to emphasize that there's not just one way for programming languages to work and because it provides a counterpoint that helps illustrate the behavior of the more common static scoping.

← ScopeNamespaces →