[Jeremy Hylton] > ... > There are few languages that use dynamic scoping for normal name > resolution. Many early Lisp implementations did, but I think all the > modern ones use lexical scoping instead. I believe all early Lisps were dynamically scoped. Scheme changed that, and Common Lisp followed. Many interpreted languages *start* life with dynamic scoping because it's easy to hack together, but that never lasts. REBOL went thru this a couple years ago, switching entirely from dynamic to lexical before its first public release, and breaking most existing programs in the process. Perl also started with dynamic scoping, but, in Perl-like fashion, Perl5 *added* lexical scoping on top of dynamic ("local" vars use dynamic scoping; "my" vars lexical; and all Perl5 gotcha guides stridently recommend never using "local" anymore). Here's some Perl5: $i = 1; sub f { local($i) = 2; &g(); } sub g { return $i; } print "i at start is $i\n"; print "i in g called directly is ", &g(), "\n"; print "i in g called indirectly via f is ", &f(), "\n"; print "i at end is $i\n"; Here's what it prints: i at start is 1 i in g called directly is 1 i in g called indirectly via f is 2 i at end is 1 > It is hard to write modular code using dynamic scope, because the > behavior of a function with free variables can not be determined by > the module that defines it. As shown above; dynamic scoping is a nightmare even in the absence of nested functions. > Not saying it isn't useful, just that it makes it much harder to reason > about how a particular modular or function works in isolation from the > rest of the system. People who spend too much time writing meta-systems <wink> overestimate its usefulness. Most programmers who need this kind of effect would be much better off explicitly passing a dict of name->value mappings explicitly manipulated, or simply passing the values of interest (if I want a function that sucks the value of "i" out of its caller, what clearer way than for the caller to pass i in the arglist?! dynamic scoping is much subtler, of course -- it sucks the value of "i" out of *whatever* function up the call chain happened to define an i "most recently"). Lexical scoping is much tamer, and, indeed, Python is one of the few modern languages that doesn't support it. Last time Guido and I hand-wrung over this, that was the chief reason to implement it: newcomers are endlessly surprised that when they write functions that visually nest, their scopes nevertheless don't nest. There's certainly nothing novel or unexpected about lexical scoping anymore. The problem unique to Python is its rule for determining which vrbls are local; in Lisps, REBOL and Perl, you have to explicitly name all vrbls local to a given scope, which renders "how do you rebind a non-local name?" a non-issue. has-the-feel-of-inevitability-ly y'rs - tim
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4