As opposed to
dynamic scope, where bindings to
variables
in one
procedure are
visible in (assuming no further
rebinding) all the procedures it calls, all procedures they call, etc. Dynamic scope has among its many
disadvantages the problem that it is
impossible (in the sense of `
halting-complete') to ensure at
compile time that
variables are used only where they are
in scope.
This is perhaps the primary reason that most
real programming languages nowadays use
lexical scope.
When you combine lexical scope with functions as first-class objects (or, in general, escaping functions), you get (hopefully) closures. Not only do closures resolve free variables from the environment in which they were created---they do so even when called from outside that environment.
Languages with lexical scope include:
- Common Lisp (for non-special variables), Scheme, and indeed most modern Lisps. elisp does not have lexical scoping, but can simulate it with lexical-let.
- Most other functional languages. When you have functions as first-class objects, it becomes quite useful to be able to create closures---something dynamic scope doesn't allow.
- Pascal, Modula-2, and all the other Algol descendents.
- C and C++. The lack of nested functions makes the implementation of lexical scope particularly simple (no static links or displays, for example). It also makes it perhaps less useful. Note,
however, that nested blocks are nested scopes in C and C++,
though they may not be implemented as they are in other languages.
- my variables in Perl are lexically scoped. local variables, however, are dynamically scoped.
- Many more, of course.