3 ms·
Modern terminology is "dynamic" vs "lexical" scope[1][2]. Lexical scope makes it very easy to reason about closures[3]. Dynamic scoping is slightly easier for l
by olooney 7y ago
Modern terminology is "dynamic" vs "lexical" scope[1][2]. Lexical scope makes it very easy to reason about closures[3]. Dynamic scoping is slightly easier for language authors to implement. Terrible languages like ColdFusion[4] and MUMPS[5] use dynamic scoping, although lexical scoping constructs were bolted on later. LISP has both[6], at least it does now. Dynamic scope makes it possible to do certain kinds of code re-use not possible with lexical scope[7]; these are often called "macros" but what exactly is meant by this varies from language to language; in general, only an "unhygienic" macro requires dynamic scope to implement, while hygienic macros generally require a pre-processor but no access to dynamic scope[8]. Because dynamic scope leads to all kinds of unexpected side-effects, makes closures difficult to implement, and is only really useful for writing the worst and least useful kinds of macros, the programming language world has come down hard in favor of lexical scoping, which is now ubiquitous; almost every modern language you've heard of exclusively uses lexical scope.
[1]: https://en.wikipedia.org/wiki/Scope_(computer_science) https://en.wikipedia.org/wiki/Scope_(computer_science)
[2]: https://stackoverflow.com/questions/1047454/what-is-lexical-scope https://stackoverflow.com/questions/1047454/what-is-lexical-...
[3]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures https://developer.mozilla.org/en-US/docs/Web/JavaScript/Clos...
[4]: https://en.wikipedia.org/wiki/ColdFusion_Markup_Language https://en.wikipedia.org/wiki/ColdFusion_Markup_Language
[5]: [https://en.wikipedia.org/wiki/MUMPS https://en.wikipedia.org/wiki/MUMPS
[6]: https://www.emacswiki.org/emacs/DynamicBindingVsLexicalBinding https://www.emacswiki.org/emacs/DynamicBindingVsLexicalBindi...
[7]: https://en.wikipedia.org/wiki/Scope_(computer_science)#Macro_expansion https://en.wikipedia.org/wiki/Scope_(computer_science)#Macro...
[8]: https://en.wikipedia.org/wiki/Hygienic_macro https://en.wikipedia.org/wiki/Hygienic_macro
- AnimalMuppet 7y agoSo, if I understand all this correctly, Lisp originally had dynamic scope only (which was Dijkstra's criticism), and later came to rely mostly on lexical scoping? And, would you also comment on Dijkstra's "self-definition" comment?
- olooney 7y agoThe self-definition comment is a reference to the common LISP exercise of writing a "meta-circular evaluator"[1] - that is, writing a LISP interpreter in LISP. This is famously done[3] in "Structure and Interpretation of Computer Programs", which is a very popular textbook and MIT course which uses LISP as a teaching language[2]. This can be found for example, in lecture 7 of the SICP lecture series on Youtube[4]. Dijkstra's comment on this is quite acerbic, isn't it? Here is the full quote for easy reference: > [LISP's] promotion of the idea that a programming language should be able to formulate its own interpreter (which then could be used as the language’s definition) has caused a lot of confusion because the incestuous idea of self-definition was fundamentally flawed. I agree to the extent that the exercise of writing a LISP interpreter in LISP is indeed often a very confusing exercise for beginner, partly because writing any interpreter (or compiler) is fairly arcane for a beginner, and partly because keeping track of which parts are in implementation and which parts are in the target language can be made more difficult; also because it's easy to "cheat" and rely on outside language in inappropriate ways. I would recommend using a language you already know well and implementing a moderately simple language as a first exercise to a student. But on the whole the exercise of writing an interpreter in its own language - or alternatively writing a self-hosting compiler[5] - is rewarding and does teach you a great deal about how programs work. I also can't agree the so-called "incestuous idea of self-definition" is "fundamentally flawed:" it is in fact fairly interesting and related to important meta-mathematical concepts like Godel numbering[6], reductions[7], and the Church-Turing thesis[8]. Writing a meta-circular evaluator seems like a reasonably concrete way to start building intuition towards these important ideas. Perhaps Dijkstra has in mind such problems as Curry's Paradox[9] or Russel's Paradox[10], both of which are paradoxes arising from self-reference? In my view a meta-circular evaluator is much closer in spirit to Godel numbering (which is valid and useful) than these paradoxes. [1]: https://en.wikipedia.org/wiki/Meta-circular_evaluator https://en.wikipedia.org/wiki/Meta-circular_evaluator [2]: https://en.wikipedia.org/wiki/Structure_and_Interpretation_of_Computer_Programs https://en.wikipedia.org/wiki/Structure_and_Interpretation_o... [3]: http://www.sicpdistilled.com/section/4.1/ http://www.sicpdistilled.com/section/4.1/ [4]: https://www.youtube.com/watch?v=0m6hoOelZH8 https://www.youtube.com/watch?v=0m6hoOelZH8 [5]: https://en.wikipedia.org/wiki/Self-hosting_(compilers) https://en.wikipedia.org/wiki/Self-hosting_(compilers) [6]: https://en.wikipedia.org/wiki/G%C3%B6del_numbering https://en.wikipedia.org/wiki/G%C3%B6del_numbering [7]: https://en.wikipedia.org/wiki/Reduction_(complexity) https://en.wikipedia.org/wiki/Reduction_(complexity) [8]: https://en.wikipedia.org/wiki/Church%E2%80%93Turing_thesis https://en.wikipedia.org/wiki/Church%E2%80%93Turing_thesis [9]: https://en.wikipedia.org/wiki/Curry%27s_paradox https://en.wikipedia.org/wiki/Curry%27s_paradox [10]: https://en.wikipedia.org/wiki/Russell%27s_paradox https://en.wikipedia.org/wiki/Russell%27s_paradox