tl;dr A pedantic note on dynamic binding. Steven D'Aprano writes:
> The most common language today that uses dynamic scoping is probably > Emacs Lisp. AFAIK all Common-Lisp-ish languages implement dynamic scoping: anything defvar'd is dynamically-scoped. > Although dynamic scoping is very powerful, it is also harder > to implement correctly (so I believe) In fact, lexical scoping is harder to do correctly because you need to know what you're doing (determine whether a name is in the lexical scope). (Old) Emacs Lisp-style dynamic scoping (everything is dynamically scoped) is (conceptually) easy to implement correctly (but inefficiently!) simply by using a stack of bindings and doing all accesses by searching that stack top to bottom for a relevant binding. It's a pain in the butt to use *correctly* because every such binding can affect anything else in your program and any libraries you import. That's why Common Lisp and modern Emacs Lisp are lexically-scoped.[1] It's not that much harder to implement the dynamic scoping of defvars; you just have to add a check for the symbol being a defvar at binding time, and if not put it in the local namespace. It's true (as you write later in the thread) that Richard Stallman is still enamoured of dynamic scoping. The nicest thing I can say about Richard is that he has enormous capacity to hold huge complex structures in his head. The next nicest thing I can say about Richard is that he's an anomoly. If his enthusiasm for dynamic scoping is correct, it's a "stopped clock right twice a day" phenomenon. What's good for Richard may be *convenient* for the rest of us when hacking up one-offs, but I firmly believe that if *we* want to write reliable, nearly correct software for complex systems, dynamic scoping should be used sparingly at most. After 2 decades of maintaining Emacsen, I'd go so far as to say that Python's "global" and "nonlocal" declarations are distinctly preferable to Lisp's "defvar" and "special" declarations where Python's much more restricted constructs can do the job. > It is generally considered that dynamic scoping is equivalent to > the exclusive use of global variables That depends on your definition of "equivalent" and "global". At least psychologically, they can be very different regardless of the definition of "variable". In (old) Emacs Lisp, defun, lambda, and let all appear to define local variables, but they don't. They define local bindings of global variables, which affect any function called recursively from the function that does the binding that uses those variables as globals. And in any Lisp, it is in principle[2] impossible to write a correct program using dynamic scope if you import another module, because even if you've checked that module and there are no free occurrances of a given name at write-time, the module could be updated to use a free variable by that name before you run it and you will shadow its expected binding at run-time. To be safe, you need to implement lexical scope! In languages where "global" names are bound to memory locations at compile time, like C, or in Python where "global" means module scope, you don't have this problem. Sure, in C you can declare a variable "extern" or in Python you can import a name from another module, but that solves the problem: without an *explicit* declaration of that kind you know you can't affect another module. The point, of course, is not so much the "in principle" hazard, but rather the need to determine what the scope of a given binding *could* be and to check large extents of source code for bugs due to unexpected shadow bindings of free variables in order to be sure your program is correct, and that there is no restriction in principle on how large that extent might be. Steve Footnotes: [1] Technically, I think Emacs still defaults to dynamic scope and you have to turn lexical scope on with a pragma. [2] Again, technically, you can use dynamic scope safely in Common Lisp by interning your dynamic variables in a package, and so restricting their scope to your module plus any other modules that deliberate import those names. _______________________________________________ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/