Why not dynamic scope?

Dynamic scope is not popular. Most languages are moving toward lexical, or static, scoping. However, there are still a few modern, dynamically scoped languages. Perl, Common Lisp, newLisp all use dynamic scope (although each has lexical mechanisms.)

Going over the technical definitions of the terms would be redundant; if you need a refresher, look at Wikipedia's entry on scope.

The common complaint about dynamic scope is that it is unsafe because a function cannot predict the environment in which it will be applied. That argument does not hold much water for me. Writing solid code means avoiding coupling functions and external variables too tightly and avoiding side effects whenever possible. When a side effect is necessary, such as in a function that prints out data, alters or depends on an external variable, or modifies a parameter destructively, it should be well-documented so that a careful programmer will know what to expect. Lexical scoping should not be used as a bandage over poor programming technique.

Interestingly enough, Scheme, which is lexically scoped, champions this form of side effect free programming, as do most functional languages (although they are often lexically scoped out of necessity).

Lisps have a lexical variable binding mechanism- let. Perl has the "my" keyword, which defines a variable as local to the lexical enclosure (although I hesitate to mention Perl's scoping in any context). newLisp has contexts, which create manually managed lexical scopes that double as hash tables. These are useful utilities, but I tend to think that dynamic scope is more elegant in that it 1) more expressively reflects the state of the program, and 2) aligns more cleanly with the idea of lambda calculus (arguably the basis of Lisp).

Of course, saying dynamic scoping is elegant is not the same as saying that lexical scoping is not. In large, complex programs, dynamic scoping makes it much more difficult to troubleshoot; lexical scopes allow the programmer to more easily visualize the local variable context when looking at a block of code. This is especially true of compiled languages where debugging is not a matter of simply stepping through a bit of code in the REPL. In REPL-deficient languages, lexical scopes are a must.

The common case of interpreted languages, even the object oriented ones, is essentially procedural. The goal is to get from point A to point B, especially with web programming. In these cases, dynamic namespaces make the job much easier, and allow much more concise, expressive code.