CSE 413 Spring 2011

Static and Dynamic Scoping

Scope rules define the visibility rules for names in a programming language. What if you have references to a variable named k in different parts of the program? Do these refer to the same variable or to different ones?

Most languages, including Algol, Ada, C, C++, Pascal, Scheme, and Miranda, are statically scoped. A block defines a new scope. Variables can be declared in that scope, and aren't visible from the outside. However, variables outside the scope -- in enclosing scopes -- are visible unless they are overridden. In Algol, Pascal, Miranda, and Scheme (but not C or Ada) these scope rules also apply to the names of functions and procedures.

Static scoping is also sometimes called lexical scoping.

Simple Static Scoping Example

    (define m 50)
    (define n 100)

    (define (hardy) 
        (display "in hardy; n = ")
        (display n))

    (define (laurel n)
        (display "in laurel; m, n = ")
        (display m)
        (display n)
        (hardy))

    

    (hardy) displays: in hardy; n = 100

    (laurel 1) displays: in laurel; m, n = 50 1
                         in hardy; n = 100

Blocks can be nested an arbitrary number of levels deep.

Dynamic Scoping

Dynamic scoping was used in early dialects of Lisp, and some older interpreted languages such as SNOBOL and APL. It is available as an option in Common Lisp. Using this scoping rule, we first look for a local definition of a variable. If it isn't found, we look up the calling stack for a definition. If dynamic scoping were used, the output would be:

    

    (hardy) displays: in hardy; n = 100

    (laurel 1) displays: in laurel; m, n = 50 1
                         in hardy; n = 1

Notice the difference: The second time hardy is executed, it is called from laurel instead of from the main program.