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?
Languages such as Algol, Ada, C, Pascal and Scheme 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 (shadowed). In Algol and Pascal (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.
(define m 50) (define n 100) (define (hardy) (display (list "In Hardy, n=" n)) (newline)) (define (laurel n) (display (list "In Laurel, m=" m)) (newline) (display (list "In Laurel, n=" n)) (newline) (hardy)) (display (list "In main program, n=" n)) (newline) (laurel 1) (hardy)Output:
In main program, n = 100 In laurel, m = 50 In laurel, n = 1 In hardy, n = 100 ;; called from laurel in hardy -- n = 100 ;; called from main
We can declare a variable as dynamically scoped in Common Lisp using
defvar
(but not in Scheme). Example:
;; Repeat the example above, but assume ;; that Scheme is dynamically scoped.
(define m 50) (define n 100) (define (laurel n) (define (hardy) (display (list "In Hardy, n=" n)) (newline)) (display (list "In Laurel, m=" m)) (newline) (display (list "In Laurel, n=" n)) (newline) (hardy)) (display (list "In main program, n=" n)) (newline) (laurel 1) ;; THIS DOESN'T WORK: (hardy)Annotated Output:
In main program, n = 100 In laurel, m = 50 In laurel, n = 1 In hardy, n = 1 ;; called from laurelHere's the same example in Pascal:
begin integer m, n; procedure laurel(n: integer); begin procedure hardy; begin print("in hardy -- n = ", n); end; print("in laurel -- m = ", m); print("in laurel -- n = ", n); hardy; end; m := 50; n := 100; print("in main program -- n = ", n); laurel(1); /* we can't call hardy here, since the name isn't visible */ end;