* Re: Real-life examples of lexical binding in Emacs Lisp [not found] <mailman.3883.1432888152.904.help-gnu-emacs@gnu.org> @ 2015-05-29 9:30 ` Joost Kremers 2015-05-29 11:12 ` Andreas Röhler 2015-05-29 12:28 ` Pascal J. Bourguignon ` (2 subsequent siblings) 3 siblings, 1 reply; 48+ messages in thread From: Joost Kremers @ 2015-05-29 9:30 UTC (permalink / raw) To: help-gnu-emacs Marcin Borkowski wrote: > (Examples of general-purpose programming problems > made easier with l.b. are more or less obvious/easy to find, but Emacs > is a text editor, after all, and this is its primary area.) Yes, Emacs is a text editor, but I'd say the primary purpose of Elisp is to *implement* that editor. The fact that Elisp has more facilities for editing text than most other programming languages is just a consequence of that. So presumably lexical binding was added to Elisp not so much because it makes text editing easier, but because it makes implementing the text editor easier. -- Joost Kremers joostkremers@fastmail.fm Selbst in die Unterwelt dringt durch Spalten Licht EN:SiS(9) ^ permalink raw reply [flat|nested] 48+ messages in thread
* Re: Real-life examples of lexical binding in Emacs Lisp 2015-05-29 9:30 ` Real-life examples of lexical binding in Emacs Lisp Joost Kremers @ 2015-05-29 11:12 ` Andreas Röhler 2015-05-29 12:13 ` Dmitry Gutov 2015-05-29 16:21 ` Phillip Lord 0 siblings, 2 replies; 48+ messages in thread From: Andreas Röhler @ 2015-05-29 11:12 UTC (permalink / raw) To: help-gnu-emacs Am 29.05.2015 um 11:30 schrieb Joost Kremers: > Marcin Borkowski wrote: >> (Examples of general-purpose programming problems >> made easier with l.b. are more or less obvious/easy to find, but Emacs >> is a text editor, after all, and this is its primary area.) > Yes, Emacs is a text editor, but I'd say the primary purpose of Elisp is > to *implement* that editor. The fact that Elisp has more facilities for > editing text than most other programming languages is just a consequence > of that. > > So presumably lexical binding was added to Elisp not so much because it > makes text editing easier, but because it makes implementing the text > editor easier. > > Would be great to see an example where implementing the text editor is easier that way. Thanks, Andreas ^ permalink raw reply [flat|nested] 48+ messages in thread
* Re: Real-life examples of lexical binding in Emacs Lisp 2015-05-29 11:12 ` Andreas Röhler @ 2015-05-29 12:13 ` Dmitry Gutov 2015-05-29 16:21 ` Phillip Lord 1 sibling, 0 replies; 48+ messages in thread From: Dmitry Gutov @ 2015-05-29 12:13 UTC (permalink / raw) To: Andreas Röhler, help-gnu-emacs On 05/29/2015 02:12 PM, Andreas Röhler wrote: > Would be great to see an example where implementing the text editor is > easier that way. - Lexical scoping is easier to reason about. The byte-compiler also takes advantage of it and produces more useful warnings. - You can use normal closures instead of having to create lambda forms with quasiquotes for callbacks (or save the values somewhere globally). ^ permalink raw reply [flat|nested] 48+ messages in thread
* Re: Real-life examples of lexical binding in Emacs Lisp 2015-05-29 11:12 ` Andreas Röhler 2015-05-29 12:13 ` Dmitry Gutov @ 2015-05-29 16:21 ` Phillip Lord 2015-05-29 16:50 ` Yuri Khan 1 sibling, 1 reply; 48+ messages in thread From: Phillip Lord @ 2015-05-29 16:21 UTC (permalink / raw) To: Andreas Röhler; +Cc: help-gnu-emacs Andreas Röhler <andreas.roehler@easy-emacs.de> writes: > Am 29.05.2015 um 11:30 schrieb Joost Kremers: >> Marcin Borkowski wrote: >>> (Examples of general-purpose programming problems >>> made easier with l.b. are more or less obvious/easy to find, but Emacs >>> is a text editor, after all, and this is its primary area.) >> Yes, Emacs is a text editor, but I'd say the primary purpose of Elisp is >> to *implement* that editor. The fact that Elisp has more facilities for >> editing text than most other programming languages is just a consequence >> of that. >> >> So presumably lexical binding was added to Elisp not so much because it >> makes text editing easier, but because it makes implementing the text >> editor easier. >> >> > > Would be great to see an example where implementing the text editor is easier > that way. dash-functional.el makes extensive use of lexical binding and would not work without it. I've used it in my m-buffer package, in a small way. I could have done without. And, yes, it's mostly about closures (from the programmers POV). But asking for examples of where it makes editing easier seems to not make sense to me. Can you show me a real *text editing* problem that quick-sort solves, like something that is easier done than with bubble sort? Phil ^ permalink raw reply [flat|nested] 48+ messages in thread
* Re: Real-life examples of lexical binding in Emacs Lisp 2015-05-29 16:21 ` Phillip Lord @ 2015-05-29 16:50 ` Yuri Khan 0 siblings, 0 replies; 48+ messages in thread From: Yuri Khan @ 2015-05-29 16:50 UTC (permalink / raw) Cc: help-gnu-emacs@gnu.org On Fri, May 29, 2015 at 10:21 PM, Phillip Lord <phillip.lord@newcastle.ac.uk> wrote: > And, yes, it's mostly about closures (from the programmers POV). But > asking for examples of where it makes editing easier seems to not make > sense to me. I will give an example where I wanted closures in Emacs but they were not yet available. The setup is editing XHTML, using nxml-mode. What I wanted was to have a set of key bindings that would all behave similarly: namely, to accept a selected block, wrap it in a pair of tags and extend selection to include the newly inserted tags. Each binding would use a different tag. Example (brackets denote mark and point): lorem [ipsum dolor] sit amet —[C-l b]→ lorem [<strong>ipsum dolor</strong>] sit amet lorem [ipsum dolor] sit amet —[C-l i]→ lorem [<em>ipsum dolor</em>] sit amet I do not remember the exact half-solution I came up with, but it involved a helper function that accepted a region and a tag name: (defun yk-nxml-wrap-region (begin end tagname) (interactive "rs") …implementation omitted…) The other trivial half would be to bind closures of this function, with the tag name fixed to a different string for each binding: (define-key nxml-mode-map (kbd "C-l b") (make-closure yk-nxml-wrap-region "strong")) (define-key nxml-mode-map (kbd "C-l i") (make-closure yk-nxml-wrap-region "em")) But, as I said, lexical binding and therefore closures were not available at that time. I had to make do with a macro. (I replaced the whole solution with yasnippet and smartparens since then.) ^ permalink raw reply [flat|nested] 48+ messages in thread
* Re: Real-life examples of lexical binding in Emacs Lisp [not found] <mailman.3883.1432888152.904.help-gnu-emacs@gnu.org> 2015-05-29 9:30 ` Real-life examples of lexical binding in Emacs Lisp Joost Kremers @ 2015-05-29 12:28 ` Pascal J. Bourguignon 2015-05-29 17:16 ` Andreas Röhler 2015-05-29 18:43 ` Emanuel Berg 2015-05-30 5:49 ` Rusi 3 siblings, 1 reply; 48+ messages in thread From: Pascal J. Bourguignon @ 2015-05-29 12:28 UTC (permalink / raw) To: help-gnu-emacs Marcin Borkowski <mbork@mbork.pl> writes: > Hi all, > > I googled a bit, and could not find /real-world/ examples of using > lexical binding and its advantages /in Emacs Lisp/. I understand that > it's a nice thing to be able to create closures, and that lexical > binding is in general faster than dynamic binding (which is a bonus in > itself), but could anyone show me a real /text editing/ problem that > lexical binding solves, like something that is easier done with > l.b. than with d.b.? (Examples of general-purpose programming problems > made easier with l.b. are more or less obvious/easy to find, but Emacs > is a text editor, after all, and this is its primary area.) Lexical binding matters for two things: - it allows the creation of closures. - it prevents the clobbering of variables. Closures: A typical example, is visible in the thread "~`symbol-function' to get code as list even when byte-compiled?": ;;;; -*- mode:emacs-lisp;lexical-binding:t;coding:utf-8 -*- (defun add-one-shot-meat (hook fun) (let ((name (gensym))) (setf (symbol-function name) (lambda () (remove-hook hook name) (funcall fun))) (add-hook hook name))) Without lexical binding, fun and hook would be dynamic, and therefore their bindings would disappear when add-one-shot-meat returns. Therefore they would be undefined variable when the function is called, or worse, they may be bound at that time by some other function to something different. Compare: (setf lexical-binding t) (defun e (f) (let ((v 42)) (funcall f))) (let ((v 33)) (e (lambda () v))) --> 33 (setf lexical-binding nil) (defun e (f) (let ((v 42)) (funcall f))) (let ((v 33)) (e (lambda () v))) --> 42 Clobering variables: For example, if we have a package such as: (setf lexical-binding nil) (defun d () v) (defun e (f) (let ((v 42)) (funcall f))) and we used it with a function in another package such as: (defun h () (let ((v 33)) (d))) we obtain: (e (function h)) --> 33 instead of the expected 42. Hence the workaround of prefixing all variables by the package name, but this is often insufficient (because package names being often generic, a different package may name its internal variables similarly) and not always applied, notably for internal variables. To be 100% safe without lexical binding, you would have to prefix ALL your variables with very long package and function name prefixes. -- __Pascal Bourguignon__ http://www.informatimago.com/ “The factory of the future will have only two employees, a man and a dog. The man will be there to feed the dog. The dog will be there to keep the man from touching the equipment.” -- Carl Bass CEO Autodesk ^ permalink raw reply [flat|nested] 48+ messages in thread
* Re: Real-life examples of lexical binding in Emacs Lisp 2015-05-29 12:28 ` Pascal J. Bourguignon @ 2015-05-29 17:16 ` Andreas Röhler 0 siblings, 0 replies; 48+ messages in thread From: Andreas Röhler @ 2015-05-29 17:16 UTC (permalink / raw) To: help-gnu-emacs Am 29.05.2015 um 14:28 schrieb Pascal J. Bourguignon: > Marcin Borkowski <mbork@mbork.pl> writes: > >> Hi all, >> >> I googled a bit, and could not find /real-world/ examples of using >> lexical binding and its advantages /in Emacs Lisp/. I understand that >> it's a nice thing to be able to create closures, and that lexical >> binding is in general faster than dynamic binding (which is a bonus in >> itself), but could anyone show me a real /text editing/ problem that >> lexical binding solves, like something that is easier done with >> l.b. than with d.b.? (Examples of general-purpose programming problems >> made easier with l.b. are more or less obvious/easy to find, but Emacs >> is a text editor, after all, and this is its primary area.) > Lexical binding matters for two things: > > - it allows the creation of closures. > - it prevents the clobbering of variables. > > > Closures: > > A typical example, is visible in the thread "~`symbol-function' to > get code as list even when byte-compiled?": > > ;;;; -*- mode:emacs-lisp;lexical-binding:t;coding:utf-8 -*- > (defun add-one-shot-meat (hook fun) > (let ((name (gensym))) > (setf (symbol-function name) > (lambda () > (remove-hook hook name) > (funcall fun))) > (add-hook hook name))) > > Without lexical binding, fun and hook would be dynamic, and > therefore their bindings would disappear when add-one-shot-meat > returns. Therefore they would be undefined variable when the > function is called, or worse, they may be bound at that time by some > other function to something different. > > Compare: > > (setf lexical-binding t) > > (defun e (f) > (let ((v 42)) > (funcall f))) > > (let ((v 33)) > (e (lambda () v))) > > --> 33 > > > (setf lexical-binding nil) > > (defun e (f) > (let ((v 42)) > (funcall f))) > > (let ((v 33)) > (e (lambda () v))) > > --> 42 > > Thanks a lot all! Will take some time to work through the examples given. Cheers, Andreas ^ permalink raw reply [flat|nested] 48+ messages in thread
* Re: Real-life examples of lexical binding in Emacs Lisp [not found] <mailman.3883.1432888152.904.help-gnu-emacs@gnu.org> 2015-05-29 9:30 ` Real-life examples of lexical binding in Emacs Lisp Joost Kremers 2015-05-29 12:28 ` Pascal J. Bourguignon @ 2015-05-29 18:43 ` Emanuel Berg 2015-05-30 5:49 ` Rusi 3 siblings, 0 replies; 48+ messages in thread From: Emanuel Berg @ 2015-05-29 18:43 UTC (permalink / raw) To: help-gnu-emacs Marcin Borkowski <mbork@mbork.pl> writes: > I googled a bit, and could not find /real-world/ > examples of using lexical binding and its advantages > /in Emacs Lisp/. I understand that it's a nice thing > to be able to create closures, and that lexical > binding is in general faster than dynamic binding > (which is a bonus in itself), but could anyone show > me a real /text editing/ problem that lexical > binding solves, like something that is easier done > with l.b. than with d.b.? Here, Stefan Monnier will correct me if I'm wrong: Lexical scope is better for general purposes and the Joe Elisp Hacker, and this is illustrated by the fact that >99% of the Emacs code that is dynamically scoped would work just as well with lexical-binding. > (Examples of general-purpose programming problems > made easier with l.b. are more or less obvious/easy > to find, but Emacs is a text editor, after all, and > this is its primary area.) There is no contradiction between text and programming! And there is no hierarchy what is Emacs primary, secondary area and so on. From programming, Gnus, ERC, and Emacs-w3m, to writing love novels - it is all on the same level. -- underground experts united http://user.it.uu.se/~embe8573 ^ permalink raw reply [flat|nested] 48+ messages in thread
* Re: Real-life examples of lexical binding in Emacs Lisp [not found] <mailman.3883.1432888152.904.help-gnu-emacs@gnu.org> ` (2 preceding siblings ...) 2015-05-29 18:43 ` Emanuel Berg @ 2015-05-30 5:49 ` Rusi 2015-05-30 12:50 ` Pascal J. Bourguignon 2015-05-30 16:03 ` Emanuel Berg 3 siblings, 2 replies; 48+ messages in thread From: Rusi @ 2015-05-30 5:49 UTC (permalink / raw) To: help-gnu-emacs On Friday, May 29, 2015 at 1:59:14 PM UTC+5:30, Marcin Borkowski wrote: > Hi all, > > I googled a bit, and could not find /real-world/ examples of using > lexical binding and its advantages /in Emacs Lisp/. I understand that > it's a nice thing to be able to create closures, and that lexical > binding is in general faster than dynamic binding (which is a bonus in > itself), but could anyone show me a real /text editing/ problem that > lexical binding solves, like something that is easier done with > l.b. than with d.b.? (Examples of general-purpose programming problems > made easier with l.b. are more or less obvious/easy to find, but Emacs > is a text editor, after all, and this is its primary area.) I'd say you are getting this from the wrong end. Today (2015) dynamic scoping is considered a bug In 1960 when Lisp was invented of course people did not realize this. This is just a belated bug-fix [More OT] Ive been collecting material on history of functional programming and looking for early references on 'Lisp-as-a-functional-language'. Note I am not asking for early references on Lisp or on FP but on Lisp as FP. I know of Henderson's 1980 book on FP that uses Lisp. I'm looking for something earlier and more 'mainstream' ^ permalink raw reply [flat|nested] 48+ messages in thread
* Re: Real-life examples of lexical binding in Emacs Lisp 2015-05-30 5:49 ` Rusi @ 2015-05-30 12:50 ` Pascal J. Bourguignon 2015-05-30 15:23 ` Rusi 2015-05-30 16:03 ` Emanuel Berg 1 sibling, 1 reply; 48+ messages in thread From: Pascal J. Bourguignon @ 2015-05-30 12:50 UTC (permalink / raw) To: help-gnu-emacs Rusi <rustompmody@gmail.com> writes: > I'd say you are getting this from the wrong end. > Today (2015) dynamic scoping is considered a bug "Bug" is too strong a word here. > In 1960 when Lisp was invented of course people did not realize this. > This is just a belated bug-fix It is actually in 1960 (or a few years after) when LISP was invented, that people realized there was the so called "Funarg problem". During the 60s this problem has been studied, several (faulty) solutions proposed, and eventually the notions of lexical binding vs. dynamic binding and environments were elaborated. Other languages such as Fortran and Algol had already something like lexical binding, but it was actually as accidental as the dynamic binding of LISP, and of no consequence, since in those languages it was not possible to create closures anyways. At the end of the 60s the solution to the FUNARG problem, ie. lexical binding and the creation of closures was finally invented, and implemented in PAL and eventually in scheme. http://en.wikipedia.org/wiki/Closure_%28computer_programming%29#History_and_etymology But even in scheme, dynamic binding is useful and implemented (in libraries). In any lexical programming language, you can implement dynamic binding when needed. In conclusion, my point is that both lexical binding and dynamic binding are useful techniques that can be used in programs, and there's no reason to consider one or the others to be "bugs". They are tools, and you only have to know when to use them effectively. J. Weisenbaum, "The FUNARG Problem Explained", MIT memorandum, 1968 J. Moses, "The Function of FUNCTION in LISP, or Why the FUNARG Problem Should be Called the Environment Problem", AIM-199, June 1970. -- __Pascal Bourguignon__ http://www.informatimago.com/ “The factory of the future will have only two employees, a man and a dog. The man will be there to feed the dog. The dog will be there to keep the man from touching the equipment.” -- Carl Bass CEO Autodesk ^ permalink raw reply [flat|nested] 48+ messages in thread
* Re: Real-life examples of lexical binding in Emacs Lisp 2015-05-30 12:50 ` Pascal J. Bourguignon @ 2015-05-30 15:23 ` Rusi 2015-05-30 15:50 ` Pascal J. Bourguignon 0 siblings, 1 reply; 48+ messages in thread From: Rusi @ 2015-05-30 15:23 UTC (permalink / raw) To: help-gnu-emacs On Saturday, May 30, 2015 at 6:20:13 PM UTC+5:30, Pascal J. Bourguignon wrote: > Rusi writes: > > > I'd say you are getting this from the wrong end. > > Today (2015) dynamic scoping is considered a bug > > "Bug" is too strong a word here. > > > > In 1960 when Lisp was invented of course people did not realize this. > > This is just a belated bug-fix > > It is actually in 1960 (or a few years after) when LISP was invented, > that people realized there was the so called "Funarg problem". During > the 60s this problem has been studied, several (faulty) solutions > proposed, and eventually the notions of lexical binding vs. dynamic > binding and environments were elaborated. I dont understand why the funarg problem is at issue here. If foo calls bar (not nested within foo) And bar references x which it does not define The natural expection is a 'Variable undefined' error. However in a dynamic scoping discipline, you will get the error if foo does NOT define x; else bar will get foo's private x. I dont see how this can be regarded as not buggy -- no need to bring in functional/higher-order aspects at all. > > Other languages such as Fortran and Algol had already something like > lexical binding, but it was actually as accidental as the dynamic > binding of LISP, and of no consequence, since in those languages it was > not possible to create closures anyways. There is somebody-or-other's law (sorry cant remember the reference) to the effect: When a language is designed from ground up it usually gets scoping right. When a language slowly evolves out of mere configuration into more and more features into full Turing-completeness, it invariably gets scoping wrong. Examples (in addition to Lisp): perl, python, lua and most famously javascript I conclude: a. Scoping is a much harder problem than appears at first blush b. Compiled languages tend to get it more right than interpreted ^ permalink raw reply [flat|nested] 48+ messages in thread
* Re: Real-life examples of lexical binding in Emacs Lisp 2015-05-30 15:23 ` Rusi @ 2015-05-30 15:50 ` Pascal J. Bourguignon 2015-05-30 16:21 ` Rusi 0 siblings, 1 reply; 48+ messages in thread From: Pascal J. Bourguignon @ 2015-05-30 15:50 UTC (permalink / raw) To: help-gnu-emacs Rusi <rustompmody@gmail.com> writes: > On Saturday, May 30, 2015 at 6:20:13 PM UTC+5:30, Pascal J. Bourguignon wrote: >> Rusi writes: >> >> > I'd say you are getting this from the wrong end. >> > Today (2015) dynamic scoping is considered a bug >> >> "Bug" is too strong a word here. >> >> >> > In 1960 when Lisp was invented of course people did not realize this. >> > This is just a belated bug-fix >> >> It is actually in 1960 (or a few years after) when LISP was invented, >> that people realized there was the so called "Funarg problem". During >> the 60s this problem has been studied, several (faulty) solutions >> proposed, and eventually the notions of lexical binding vs. dynamic >> binding and environments were elaborated. > > I dont understand why the funarg problem is at issue here. > > If foo calls bar (not nested within foo) > And bar references x which it does not define > The natural expection is a 'Variable undefined' error. > However in a dynamic scoping discipline, you will get the error if > foo does NOT define x; else bar will get foo's private x. > I dont see how this can be regarded as not buggy -- no need to bring in > functional/higher-order aspects at all. It's not buggy, because it's the behavior of this tools. You cannot complain that chainsaw section arms and legs: this is the behavior of chainsaws. Just learn how to use them for good use: section only trees or zombies. The funarg problem shows that what was wanted with the introduction of lambda was not dynamic binding, but lexical binding, so that closures could be created by lambda. >> Other languages such as Fortran and Algol had already something like >> lexical binding, but it was actually as accidental as the dynamic >> binding of LISP, and of no consequence, since in those languages it was >> not possible to create closures anyways. > > There is somebody-or-other's law (sorry cant remember the reference) to the effect: > When a language is designed from ground up it usually gets scoping right. > When a language slowly evolves out of mere configuration into more and more > features into full Turing-completeness, it invariably gets scoping wrong. > Examples (in addition to Lisp): perl, python, lua and most famously javascript > > I conclude: > a. Scoping is a much harder problem than appears at first blush > b. Compiled languages tend to get it more right than interpreted When LISP was designed, the notion of scoping was just not considered. It's the invention of LISP and the detection of the funarg problem that made people think about it, and eventually invent lexical binding and environments. -- __Pascal Bourguignon__ http://www.informatimago.com/ “The factory of the future will have only two employees, a man and a dog. The man will be there to feed the dog. The dog will be there to keep the man from touching the equipment.” -- Carl Bass CEO Autodesk ^ permalink raw reply [flat|nested] 48+ messages in thread
* Re: Real-life examples of lexical binding in Emacs Lisp 2015-05-30 15:50 ` Pascal J. Bourguignon @ 2015-05-30 16:21 ` Rusi 0 siblings, 0 replies; 48+ messages in thread From: Rusi @ 2015-05-30 16:21 UTC (permalink / raw) To: help-gnu-emacs On Saturday, May 30, 2015 at 9:20:19 PM UTC+5:30, Pascal J. Bourguignon wrote: > Rusi writes: > > > On Saturday, May 30, 2015 at 6:20:13 PM UTC+5:30, Pascal J. Bourguignon wrote: > >> Rusi writes: > >> > >> > I'd say you are getting this from the wrong end. > >> > Today (2015) dynamic scoping is considered a bug > >> > >> "Bug" is too strong a word here. > >> > >> > >> > In 1960 when Lisp was invented of course people did not realize this. > >> > This is just a belated bug-fix > >> > >> It is actually in 1960 (or a few years after) when LISP was invented, > >> that people realized there was the so called "Funarg problem". During > >> the 60s this problem has been studied, several (faulty) solutions > >> proposed, and eventually the notions of lexical binding vs. dynamic > >> binding and environments were elaborated. > > > > I dont understand why the funarg problem is at issue here. > > > > If foo calls bar (not nested within foo) > > And bar references x which it does not define > > The natural expection is a 'Variable undefined' error. > > However in a dynamic scoping discipline, you will get the error if > > foo does NOT define x; else bar will get foo's private x. > > I dont see how this can be regarded as not buggy -- no need to bring in > > functional/higher-order aspects at all. > > It's not buggy, because it's the behavior of this tools. > > You cannot complain that chainsaw section arms and legs: this is the > behavior of chainsaws. Just learn how to use them for good use: section > only trees or zombies. > > > The funarg problem shows that what was wanted with the introduction of > lambda was not dynamic binding, but lexical binding, so that closures > could be created by lambda. Heh! If scope leaks in straightforward first-order code you say its what-you-ask-that-you-get -- chainsaw. If scope leaks (downward funarg) or breaks (upward funarg) you say the scoping is at fault. You're having it both ways aint you Pascal?! > > > >> Other languages such as Fortran and Algol had already something like > >> lexical binding, but it was actually as accidental as the dynamic > >> binding of LISP, and of no consequence, since in those languages it was > >> not possible to create closures anyways. > > > > There is somebody-or-other's law (sorry cant remember the reference) to the effect: > > When a language is designed from ground up it usually gets scoping right. > > When a language slowly evolves out of mere configuration into more and more > > features into full Turing-completeness, it invariably gets scoping wrong. > > Examples (in addition to Lisp): perl, python, lua and most famously javascript > > > > I conclude: > > a. Scoping is a much harder problem than appears at first blush > > b. Compiled languages tend to get it more right than interpreted > > When LISP was designed, the notion of scoping was just not considered. This much we can agree > It's the invention of LISP and the detection of the funarg problem that > made people think about it, and eventually invent lexical binding and > environments. Please see the Algol report www.masswerk.at/algol60/report.htm The notion of block is fundamental there In fact the scheme report RnRS used to to trace scheme's lineage as much to Algol as to Lisp. The Algol contribution was block structure. ^ permalink raw reply [flat|nested] 48+ messages in thread
* Re: Real-life examples of lexical binding in Emacs Lisp 2015-05-30 5:49 ` Rusi 2015-05-30 12:50 ` Pascal J. Bourguignon @ 2015-05-30 16:03 ` Emanuel Berg 2015-05-30 16:32 ` Rusi 1 sibling, 1 reply; 48+ messages in thread From: Emanuel Berg @ 2015-05-30 16:03 UTC (permalink / raw) To: help-gnu-emacs Rusi <rustompmody@gmail.com> writes: > I'd say you are getting this from the wrong end. > Today (2015) dynamic scoping is considered a bug In > 1960 when Lisp was invented of course people did not > realize this. This is just a belated bug-fix John MacCarthy's LISP first appeared in 1958 according to the Wikipedia LISP article [1]. But that might be a definition issue. "First appeared" refers to when "the specification" appeared in a paper. It says: Lisp was invented by John McCarthy in 1958 while he was at the Massachusetts Institute of Technology (MIT). McCarthy published its design in a paper in Communications of the ACM in 1960 ... But then they write: McCarthy's 1958 paper ... [?] Also, in the article: The first complete Lisp compiler, written in Lisp, was implemented in 1962 by Tim Hart and Mike Levin at MIT. So let's say 1962 and be home free. If we go with the specification definition we might as well say Ada Lovelace was the first programmer or something equally bizarre. > Ive been collecting material on history of > functional programming and looking for early > references on 'Lisp-as-a-functional-language'. > Note I am not asking for early references on Lisp or > on FP but on Lisp as FP. I know of Henderson's 1980 > book on FP that uses Lisp. I'm looking for something > earlier and more 'mainstream' FP is a programming paradigm. It is a model. The purpose of a model is not to describe reality but to be a pair of glasses that will enhance our understanding of the mechanisms of (some part of) reality. I some contexts models are necessary since what they model are totally abstract and/or all-but impossible to access in other ways (e.g., pre-ancient history, distant space, etc.). Contrary to this situation, Lisp is right in front of us. There is no modelling in the world that will enhance our understanding of Lisp more than we write, say, 50 lines of it every day. And, doing that, one might actually do something useful while at it! [1] https://en.wikipedia.org/w/index.php?title=LISP&printable=yes -- underground experts united http://user.it.uu.se/~embe8573 ^ permalink raw reply [flat|nested] 48+ messages in thread
* Re: Real-life examples of lexical binding in Emacs Lisp 2015-05-30 16:03 ` Emanuel Berg @ 2015-05-30 16:32 ` Rusi 2015-05-30 16:54 ` Pascal J. Bourguignon 0 siblings, 1 reply; 48+ messages in thread From: Rusi @ 2015-05-30 16:32 UTC (permalink / raw) To: help-gnu-emacs On Saturday, May 30, 2015 at 9:27:25 PM UTC+5:30, Emanuel Berg wrote: > Contrary to this situation, Lisp is right in front of > us. There is no modelling in the world that will > enhance our understanding of Lisp more than we write, > say, 50 lines of it every day. And, doing that, one > might actually do something useful while at it! Some very eminent Lispers perceive Lisp rather differently: | Lisp... McCarthy did as a theoretical exercise-- an effort to define a more | convenient alternative to the Turing Machine. Lisp was not really designed to | be a programming language From http://www.paulgraham.com/icad.html ^ permalink raw reply [flat|nested] 48+ messages in thread
* Re: Real-life examples of lexical binding in Emacs Lisp 2015-05-30 16:32 ` Rusi @ 2015-05-30 16:54 ` Pascal J. Bourguignon 2015-05-30 17:10 ` Rusi 0 siblings, 1 reply; 48+ messages in thread From: Pascal J. Bourguignon @ 2015-05-30 16:54 UTC (permalink / raw) To: help-gnu-emacs Rusi <rustompmody@gmail.com> writes: > On Saturday, May 30, 2015 at 9:27:25 PM UTC+5:30, Emanuel Berg wrote: >> Contrary to this situation, Lisp is right in front of >> us. There is no modelling in the world that will >> enhance our understanding of Lisp more than we write, >> say, 50 lines of it every day. And, doing that, one >> might actually do something useful while at it! > > Some very eminent Lispers perceive Lisp rather differently: > > | Lisp... McCarthy did as a theoretical exercise-- an effort to > define a more | convenient alternative to the Turing Machine. Lisp was > not really designed to | be a programming language > > From http://www.paulgraham.com/icad.html You have to understand what Paul Graham is saying. But historically, John McCarthy definitely was designing a programming language, not just a theorical exercise. One perhaps may be mislead by the way "scientific" "papers" are written, including mere AI Memos. But that's just the "academic" style. John McCarthy definitely was designing a programming language, and this can be shown by the complains he had and requirements he made of the languages he had to use before he invented LISP, ie. Fortran and Algol. He wanted a ternary IF from Fortran (which was rejected at the time), he wanted a COND form from Algol (which was also rejected). Seeing that he couldn't have his ideas integrated in the existing programming languages, he set to define his own. But indeed, John McCarthy expected to refine a M-expression syntax for his lisp programming language; the S-expression syntax was used only for data, but since he defined an eval function working on code represented as data, and since his student Bertrand Russel implemented this eval function and realized that nothing more was needed to evaluate code expressed as data S-expressions, lisp in its S-expression form took off and flew out of the hands of John McCarthy. So indeed, the lisp we have with S-expressions is not the lisp John McCarthy wanted to design, but it is still definitely a programming language that John McCarthy wanted to and did define, for perfectly practical purposes at the AILab. And if it were a theorical exercice, John McCarthy wouldn't have missed the problem of defining lambda without closures. -- __Pascal Bourguignon__ http://www.informatimago.com/ “The factory of the future will have only two employees, a man and a dog. The man will be there to feed the dog. The dog will be there to keep the man from touching the equipment.” -- Carl Bass CEO Autodesk ^ permalink raw reply [flat|nested] 48+ messages in thread
* Re: Real-life examples of lexical binding in Emacs Lisp 2015-05-30 16:54 ` Pascal J. Bourguignon @ 2015-05-30 17:10 ` Rusi 2015-05-30 19:12 ` Pascal J. Bourguignon 0 siblings, 1 reply; 48+ messages in thread From: Rusi @ 2015-05-30 17:10 UTC (permalink / raw) To: help-gnu-emacs On Saturday, May 30, 2015 at 10:24:49 PM UTC+5:30, Pascal J. Bourguignon wrote: > Rusi writes: > > > On Saturday, May 30, 2015 at 9:27:25 PM UTC+5:30, Emanuel Berg wrote: > >> Contrary to this situation, Lisp is right in front of > >> us. There is no modelling in the world that will > >> enhance our understanding of Lisp more than we write, > >> say, 50 lines of it every day. And, doing that, one > >> might actually do something useful while at it! > > > > Some very eminent Lispers perceive Lisp rather differently: > > > > | Lisp... McCarthy did as a theoretical exercise-- an effort to > > define a more | convenient alternative to the Turing Machine. Lisp was > > not really designed to | be a programming language > > > > From http://www.paulgraham.com/icad.html > > You have to understand what Paul Graham is saying. Yeah I think I do (at least somewhat). I just find it hilarious that the intentions behind Lisp were not strongly theory-oriented. That they were equally strongly practically oriented I wont dispute. > > But historically, John McCarthy definitely was designing a programming > language, not just a theorical exercise. One perhaps may be mislead by > the way "scientific" "papers" are written, including mere AI Memos. But > that's just the "academic" style. John McCarthy definitely was > designing a programming language, and this can be shown by the complains > he had and requirements he made of the languages he had to use before he > invented LISP, ie. Fortran and Algol. He wanted a ternary IF from > Fortran (which was rejected at the time), he wanted a COND form from > Algol (which was also rejected). Seeing that he couldn't have his ideas > integrated in the existing programming languages, he set to define his > own. > > But indeed, John McCarthy expected to refine a M-expression syntax for > his lisp programming language; the S-expression syntax was used only for > data, but since he defined an eval function working on code represented > as data, and since his student Bertrand Russel... Student Bertrand Russell? Now we're into alternate history methinks <wink> To come back to my earlier request: I would really appreciate some early key references on Lisp as a functional language. [And I am guessing that you Pascal will know more about this than many others] The reason is that the more I poke into this the more interesting (juicy) titbits come up; eg Here is an interview McCarthy gave a little before he died http://www.infoq.com/interviews/Steele-Interviews-John-McCarthy In the very first question he says he learnt functional programming from Backus' Fortran!!!!! What do you think of that?! ^ permalink raw reply [flat|nested] 48+ messages in thread
* Re: Real-life examples of lexical binding in Emacs Lisp 2015-05-30 17:10 ` Rusi @ 2015-05-30 19:12 ` Pascal J. Bourguignon 0 siblings, 0 replies; 48+ messages in thread From: Pascal J. Bourguignon @ 2015-05-30 19:12 UTC (permalink / raw) To: help-gnu-emacs Rusi <rustompmody@gmail.com> writes: > On Saturday, May 30, 2015 at 10:24:49 PM UTC+5:30, Pascal J. Bourguignon wrote: >> as data, and since his student Bertrand Russel... > > Student Bertrand Russell? > Now we're into alternate history methinks <wink> I meant Steve Russell, sorry. > To come back to my earlier request: I would really appreciate some > early key references on Lisp as a functional language. > [And I am guessing that you Pascal will know more about this than many others] > > The reason is that the more I poke into this the more interesting (juicy) > titbits come up; > eg Here is an interview McCarthy gave a little before he died > http://www.infoq.com/interviews/Steele-Interviews-John-McCarthy > In the very first question he says he learnt functional programming from Backus' Fortran!!!!! > > What do you think of that?! Indeed :-) You'll be surprised to learn that list programming was invented by Newell, A., Shaw, J. C., and Simon, H. A. (NSS) in the IPL programming language. Then an implementation in Fortran of the list processing primitives was implemented as a library named FLPL: Fortran-Compiled List Programming Language. In FLPL already thefamous machine instructions CAR and CDR were made available as XCARF and XCDRF functions. http://www.informatimago.com/articles/flpl/index.html And since the rest of Fortran didn't match John McCarthy's expectation for an AI programming language, he invented lisp :-) http://en.wikipedia.org/wiki/Information_Processing_Language http://www-formal.stanford.edu/jmc/history/lisp/lisp.html http://www.softwarepreservation.org/projects/LISP/ http://www.informatimago.com/develop/lisp/com/informatimago/small-cl-pgms/aim-8/index.html http://www.informatimago.com/develop/lisp/com/informatimago/small-cl-pgms/aim-8/aim-8.html -- __Pascal Bourguignon__ http://www.informatimago.com/ “The factory of the future will have only two employees, a man and a dog. The man will be there to feed the dog. The dog will be there to keep the man from touching the equipment.” -- Carl Bass CEO Autodesk ^ permalink raw reply [flat|nested] 48+ messages in thread
* Real-life examples of lexical binding in Emacs Lisp @ 2015-05-29 8:28 Marcin Borkowski 2015-05-30 8:28 ` Tassilo Horn [not found] ` <mailman.3950.1432974543.904.help-gnu-emacs@gnu.org> 0 siblings, 2 replies; 48+ messages in thread From: Marcin Borkowski @ 2015-05-29 8:28 UTC (permalink / raw) To: Help Gnu Emacs mailing list Hi all, I googled a bit, and could not find /real-world/ examples of using lexical binding and its advantages /in Emacs Lisp/. I understand that it's a nice thing to be able to create closures, and that lexical binding is in general faster than dynamic binding (which is a bonus in itself), but could anyone show me a real /text editing/ problem that lexical binding solves, like something that is easier done with l.b. than with d.b.? (Examples of general-purpose programming problems made easier with l.b. are more or less obvious/easy to find, but Emacs is a text editor, after all, and this is its primary area.) TIA, -- Marcin Borkowski http://octd.wmi.amu.edu.pl/en/Marcin_Borkowski Faculty of Mathematics and Computer Science Adam Mickiewicz University ^ permalink raw reply [flat|nested] 48+ messages in thread
* Re: Real-life examples of lexical binding in Emacs Lisp 2015-05-29 8:28 Marcin Borkowski @ 2015-05-30 8:28 ` Tassilo Horn 2015-06-14 10:52 ` Marcin Borkowski [not found] ` <mailman.4976.1434279182.904.help-gnu-emacs@gnu.org> [not found] ` <mailman.3950.1432974543.904.help-gnu-emacs@gnu.org> 1 sibling, 2 replies; 48+ messages in thread From: Tassilo Horn @ 2015-05-30 8:28 UTC (permalink / raw) To: Marcin Borkowski; +Cc: Help Gnu Emacs mailing list Marcin Borkowski <mbork@mbork.pl> writes: Hi Marcin, > I googled a bit, and could not find /real-world/ examples of using > lexical binding and its advantages /in Emacs Lisp/. I understand that > it's a nice thing to be able to create closures, and that lexical > binding is in general faster than dynamic binding (which is a bonus in > itself), but could anyone show me a real /text editing/ problem that > lexical binding solves, like something that is easier done with > l.b. than with d.b.? (Examples of general-purpose programming > problems made easier with l.b. are more or less obvious/easy to find, > but Emacs is a text editor, after all, and this is its primary area.) The emacs paper has a section explaining why emacs used dynamic binding from the start: http://www.gnu.org/software/emacs/emacs-paper.html#SEC17 However, to me the two example use-cases only motivate why you want to be able to use dynamic scoping for special variables (defvar), not really for local variables (let) or function parameters, although the first Edit Picture example explicitly speaks of binding command arguments but I don't understand it. To me, having lexical scoping in general plus special, dynamically bound variables is the ideal model. If there wouldn't be special variables anymore, the examples from the paper would need to be implemented by setq-ing the variables and later re-setting them to their old value which would be error-prone and wouldn't work if we ever get concurrency. You can make special variables thread-local like in Clojure thus hiding this additional complexity from programmers. But there are good use-cases for dynamic variables also in "normal" programs. One example is to be able to bind some *error-handler* dynamically in order to customize how to cope with errors that happen far below the call stack. I'm not able to come up with benefits of lexical scoping which are especially important for editing text. The general benefits of being safer, faster, and having closures are still valid of course. Bye, Tassilo ^ permalink raw reply [flat|nested] 48+ messages in thread
* Re: Real-life examples of lexical binding in Emacs Lisp 2015-05-30 8:28 ` Tassilo Horn @ 2015-06-14 10:52 ` Marcin Borkowski [not found] ` <mailman.4976.1434279182.904.help-gnu-emacs@gnu.org> 1 sibling, 0 replies; 48+ messages in thread From: Marcin Borkowski @ 2015-06-14 10:52 UTC (permalink / raw) To: Help Gnu Emacs mailing list OK, so I finally got to study this discussion. (It seems I have kind of a talent for inadvertently starting long discussions...) On 2015-05-30, at 10:28, Tassilo Horn <tsdh@gnu.org> wrote: > Marcin Borkowski <mbork@mbork.pl> writes: > > Hi Marcin, > >> I googled a bit, and could not find /real-world/ examples of using >> lexical binding and its advantages /in Emacs Lisp/. I understand that >> it's a nice thing to be able to create closures, and that lexical >> binding is in general faster than dynamic binding (which is a bonus in >> itself), but could anyone show me a real /text editing/ problem that >> lexical binding solves, like something that is easier done with >> l.b. than with d.b.? (Examples of general-purpose programming >> problems made easier with l.b. are more or less obvious/easy to find, >> but Emacs is a text editor, after all, and this is its primary area.) > > The emacs paper has a section explaining why emacs used dynamic binding > from the start: http://www.gnu.org/software/emacs/emacs-paper.html#SEC17 Yes, I'm aware of that, and I read this paper some time ago (even before asking my question). > However, to me the two example use-cases only motivate why you want to > be able to use dynamic scoping for special variables (defvar), not > really for local variables (let) or function parameters, although the > first Edit Picture example explicitly speaks of binding command > arguments but I don't understand it. > > To me, having lexical scoping in general plus special, dynamically bound > variables is the ideal model. If there wouldn't be special variables > anymore, the examples from the paper would need to be implemented by > setq-ing the variables and later re-setting them to their old value > which would be error-prone and wouldn't work if we ever get concurrency. > You can make special variables thread-local like in Clojure thus hiding > this additional complexity from programmers. > > But there are good use-cases for dynamic variables also in "normal" > programs. One example is to be able to bind some *error-handler* > dynamically in order to customize how to cope with errors that happen > far below the call stack. > > I'm not able to come up with benefits of lexical scoping which are > especially important for editing text. The general benefits of being > safer, faster, and having closures are still valid of course. Exactly. What I'm curious is how lexical scoping might make some tasks *connected to editing* easier/more natural. > Bye, > Tassilo Thanks, -- Marcin Borkowski http://octd.wmi.amu.edu.pl/en/Marcin_Borkowski Faculty of Mathematics and Computer Science Adam Mickiewicz University ^ permalink raw reply [flat|nested] 48+ messages in thread
[parent not found: <mailman.4976.1434279182.904.help-gnu-emacs@gnu.org>]
* Re: Real-life examples of lexical binding in Emacs Lisp [not found] ` <mailman.4976.1434279182.904.help-gnu-emacs@gnu.org> @ 2015-06-14 11:31 ` Pascal J. Bourguignon 2015-06-16 23:48 ` Jim Diamond 0 siblings, 1 reply; 48+ messages in thread From: Pascal J. Bourguignon @ 2015-06-14 11:31 UTC (permalink / raw) To: help-gnu-emacs Marcin Borkowski <mbork@mbork.pl> writes: > Exactly. What I'm curious is how lexical scoping might make some tasks > *connected to editing* easier/more natural. It depends what you mean by "editing". Until a few decades ago, editing was performed using red pens, paper, scissors, glue. Then, lexical scoping was totally useless. Nowdays, editing is performed by software programs. Writing programs is easier and more natural with lexical scoping, IN GENERAL! Therefore, it is easier and mode natural IN PARTICULAR, to write editing programs. Writing programs in general is not *connected to editing*. But writing editor programs in particular is particularly *connected to editing*, even if programming has nothing to do with editing at all, ever. Actually, the programming activity has never anything to do with the application domain! When programming a four legged robot running across fields and parkings, the programmer DOES NOT run across fields and parkings, on his four. I repeat, this is very important: when programming a four legged robot running across fields and parkings, the programmer DOES NOT run across fields and parkings, on his four. No, what the programmer does, is sit on his ass, think, and type a program into a computer, using a keyboard. Now with editing, there may be some understandable confusion, since the programmer will actually use an editor to edit his program, notably when writing an editing program. But you must distinguish the editor being used to write the program from the editor program being written! For example, you could use ed to edit the emacs editor program. The fact that you will be happier and write a better emacs editor program using lexical scoping has NOTHING to do with how the ed editor edits your editor program! Just like you don't run in the fields when you write a robot that runs in the fields. -- __Pascal Bourguignon__ http://www.informatimago.com/ “The factory of the future will have only two employees, a man and a dog. The man will be there to feed the dog. The dog will be there to keep the man from touching the equipment.” -- Carl Bass CEO Autodesk ^ permalink raw reply [flat|nested] 48+ messages in thread
* Re: Real-life examples of lexical binding in Emacs Lisp 2015-06-14 11:31 ` Pascal J. Bourguignon @ 2015-06-16 23:48 ` Jim Diamond 2015-06-17 0:06 ` Emanuel Berg ` (3 more replies) 0 siblings, 4 replies; 48+ messages in thread From: Jim Diamond @ 2015-06-16 23:48 UTC (permalink / raw) To: help-gnu-emacs On 2015-06-14 at 08:31 ADT, Pascal J. Bourguignon <pjb@informatimago.com> wrote: > Marcin Borkowski <mbork@mbork.pl> writes: > >> Exactly. What I'm curious is how lexical scoping might make some tasks >> *connected to editing* easier/more natural. <snip> > Writing programs is easier and more natural with lexical scoping, IN > GENERAL! <snip> Really? Are there well-agreed-upon studies showing those things? Or are they your opinion? It strikes me that lexical scoping is easier to implement for compiled languages (that is an "off the cuff" comment from someone (me) with basic knowledge of compiler construction). But if lexical scoping is "more natural", is that because more people were "brought up" with lexically-scoped languages than dynamically-scoped languages? The first language I "learned" was lexically scoped. But the first language I used a lot was dynamically scoped. It seemed quite reasonable and natural to me at the time. A few versions of emacs ago something I was using went from dynamic scoping to lexical scoping. Working around that change was not trivial, casting suspicion on the universality of "easier". Cheers. Jim ^ permalink raw reply [flat|nested] 48+ messages in thread
* Re: Real-life examples of lexical binding in Emacs Lisp 2015-06-16 23:48 ` Jim Diamond @ 2015-06-17 0:06 ` Emanuel Berg 2015-06-17 6:23 ` Andreas Röhler [not found] ` <mailman.5136.1434522217.904.help-gnu-emacs@gnu.org> 2015-06-17 0:43 ` Pascal J. Bourguignon ` (2 subsequent siblings) 3 siblings, 2 replies; 48+ messages in thread From: Emanuel Berg @ 2015-06-17 0:06 UTC (permalink / raw) To: help-gnu-emacs Jim Diamond <Jim.Diamond@deletethis.AcadiaU.ca> writes: > Really? Are there well-agreed-upon studies showing > those things? Or are they your opinion? > > It strikes me that lexical scoping is easier to > implement for compiled languages (that is an "off > the cuff" comment from someone (me) with basic > knowledge of compiler construction). But if lexical > scoping is "more natural", is that because more > people were "brought up" with lexically-scoped > languages than dynamically-scoped languages? This discussion is much easier to have if that confusing terminology is dropped for a second and we instead study the simple example of a `let' form: (let ((scratch-buffer "*scratch*")) (when (bufferp scratch-buffer) (kill-buffer scratch-buffer) )) Here we have one piece of data which is used twice, so that data is named and when it is used it is indirectly refered to. In this example, what is natural to me? Answer: I don't expect `let' to affect any other code than the code in the `let' itself! And this is "lexical scoping". Is it really so, that you expect it to be in another way? If so - OK. I don't think most people feel like that and I certainly don't, because I don't program that way and the impression is made even stronger with the LISP syntax of enclosed lists. -- underground experts united http://user.it.uu.se/~embe8573 ^ permalink raw reply [flat|nested] 48+ messages in thread
* Re: Real-life examples of lexical binding in Emacs Lisp 2015-06-17 0:06 ` Emanuel Berg @ 2015-06-17 6:23 ` Andreas Röhler [not found] ` <mailman.5136.1434522217.904.help-gnu-emacs@gnu.org> 1 sibling, 0 replies; 48+ messages in thread From: Andreas Röhler @ 2015-06-17 6:23 UTC (permalink / raw) To: help-gnu-emacs Am 17.06.2015 um 02:06 schrieb Emanuel Berg: > Jim Diamond <Jim.Diamond@deletethis.AcadiaU.ca> > writes: > >> Really? Are there well-agreed-upon studies showing >> those things? Or are they your opinion? >> >> It strikes me that lexical scoping is easier to >> implement for compiled languages (that is an "off >> the cuff" comment from someone (me) with basic >> knowledge of compiler construction). But if lexical >> scoping is "more natural", is that because more >> people were "brought up" with lexically-scoped >> languages than dynamically-scoped languages? > This discussion is much easier to have if that > confusing terminology is dropped for a second and we > instead study the simple example of a `let' form: > > (let ((scratch-buffer "*scratch*")) > (when (bufferp scratch-buffer) > (kill-buffer scratch-buffer) )) > > Here we have one piece of data which is used twice, so > that data is named and when it is used it is > indirectly refered to. > > In this example, what is natural to me? Answer: > I don't expect `let' to affect any other code than the > code in the `let' itself! And this is "lexical > scoping". Nonetheless, that's the way Emacs acted all the time, while called "dynamically" scoped. Now with "lexical" we have instead an injection, if a function with same arguments' symbol is called inside let. Seems neither "lexical" nor "dynamic" express the real thing. ^ permalink raw reply [flat|nested] 48+ messages in thread
[parent not found: <mailman.5136.1434522217.904.help-gnu-emacs@gnu.org>]
* Re: Real-life examples of lexical binding in Emacs Lisp [not found] ` <mailman.5136.1434522217.904.help-gnu-emacs@gnu.org> @ 2015-06-17 10:49 ` Pascal J. Bourguignon 2015-06-17 10:53 ` Pascal J. Bourguignon 2015-06-17 20:33 ` Emanuel Berg 1 sibling, 1 reply; 48+ messages in thread From: Pascal J. Bourguignon @ 2015-06-17 10:49 UTC (permalink / raw) To: help-gnu-emacs Andreas Röhler <andreas.roehler@easy-emacs.de> writes: > Am 17.06.2015 um 02:06 schrieb Emanuel Berg: >> Jim Diamond <Jim.Diamond@deletethis.AcadiaU.ca> >> writes: >> >>> Really? Are there well-agreed-upon studies showing >>> those things? Or are they your opinion? >>> >>> It strikes me that lexical scoping is easier to >>> implement for compiled languages (that is an "off >>> the cuff" comment from someone (me) with basic >>> knowledge of compiler construction). But if lexical >>> scoping is "more natural", is that because more >>> people were "brought up" with lexically-scoped >>> languages than dynamically-scoped languages? >> This discussion is much easier to have if that >> confusing terminology is dropped for a second and we >> instead study the simple example of a `let' form: >> >> (let ((scratch-buffer "*scratch*")) >> (when (bufferp scratch-buffer) >> (kill-buffer scratch-buffer) )) >> >> Here we have one piece of data which is used twice, so >> that data is named and when it is used it is >> indirectly refered to. >> >> In this example, what is natural to me? Answer: >> I don't expect `let' to affect any other code than the >> code in the `let' itself! And this is "lexical >> scoping". > > Nonetheless, that's the way Emacs acted all the time, while called > "dynamically" scoped. > > Now with "lexical" we have instead an injection, if a function with > same arguments' symbol is called inside let. > > Seems neither "lexical" nor "dynamic" express the real thing. To be more concrete, here is a case where something wrong happens: (setf lexical-binding nil) (defun do-something (arg) (format "\n%S\n" arg)) (defun some-function (arg) (setf scratch-buffer (get-buffer-create " *some-function scratch buffer*")) (with-current-buffer scratch-buffer (insert (do-something arg)))) (defun some-other-function () (with-current-buffer scratch-buffer (buffer-substring (point-min) (point-max)))) ;; and then in some unrelated code in a different file: (setq lexical-binding nil) (let ((scratch-buffer (get-buffer-create "*scratch*"))) (with-current-buffer scratch-buffer (insert "hello")) (some-function "Howdy?") (with-current-buffer scratch-buffer (buffer-substring (point-min) (point-max)))) --> " \"Howdy?\" \"Howdy?\" " ; instead of "hello" !!! On the other hand, if you use lexical binding: (setq lexical-binding t) (let ((scratch-buffer (get-buffer-create "*scratch*"))) (with-current-buffer scratch-buffer (insert "hello")) (some-function "Howdy?") (with-current-buffer scratch-buffer (buffer-substring-no-properties (point-min) (point-max)))) --> ";; This buffer is for notes you don't want to save, and for Lisp evaluation. ;; If you want to create a file, visit that file with C-x C-f, ;; then enter the text in that file's own buffer. hello" then this independent code stays independent and clean, and no other function may fuck it. -- __Pascal Bourguignon__ http://www.informatimago.com/ “The factory of the future will have only two employees, a man and a dog. The man will be there to feed the dog. The dog will be there to keep the man from touching the equipment.” -- Carl Bass CEO Autodesk ^ permalink raw reply [flat|nested] 48+ messages in thread
* Re: Real-life examples of lexical binding in Emacs Lisp 2015-06-17 10:49 ` Pascal J. Bourguignon @ 2015-06-17 10:53 ` Pascal J. Bourguignon 2015-06-17 14:42 ` Stefan Monnier 0 siblings, 1 reply; 48+ messages in thread From: Pascal J. Bourguignon @ 2015-06-17 10:53 UTC (permalink / raw) To: help-gnu-emacs "Pascal J. Bourguignon" <pjb@informatimago.com> writes: > ;; and then in some unrelated code in a different file: > > (setq lexical-binding nil) > (let ((scratch-buffer (get-buffer-create "*scratch*"))) > (with-current-buffer scratch-buffer (insert "hello")) > (some-function "Howdy?") > (with-current-buffer scratch-buffer > (buffer-substring (point-min) (point-max)))) Without lexical binding, to try to get some independence from other functions, you would have to PREFIX ALL THE LOCAL VARIABLES WITH FUNCTION SPECIFIC PREFIXES! (defun pjb-package--pjb-example-function () (let ((pjb-package--pjb-example-function--scratch-buffer (get-buffer-create "*scratch*"))) (with-current-buffer pjb-package--pjb-example-function--scratch-buffer (insert "hello")) (some-function "Howdy?") (with-current-buffer pjb-package--pjb-example-function--scratch-buffer (buffer-substring (point-min) (point-max))))) And this is only a convention that wouldn't prevent another-package--evil-function to modify pjb-package--pjb-example-function--scratch-buffer anyways. Now look at all the el code arround, and count how many local variables are named like this!!! -- __Pascal Bourguignon__ http://www.informatimago.com/ “The factory of the future will have only two employees, a man and a dog. The man will be there to feed the dog. The dog will be there to keep the man from touching the equipment.” -- Carl Bass CEO Autodesk ^ permalink raw reply [flat|nested] 48+ messages in thread
* Re: Real-life examples of lexical binding in Emacs Lisp 2015-06-17 10:53 ` Pascal J. Bourguignon @ 2015-06-17 14:42 ` Stefan Monnier 2015-06-17 16:19 ` Andreas Röhler ` (2 more replies) 0 siblings, 3 replies; 48+ messages in thread From: Stefan Monnier @ 2015-06-17 14:42 UTC (permalink / raw) To: help-gnu-emacs > Without lexical binding, to try to get some independence from other > functions, you would have to PREFIX ALL THE LOCAL VARIABLES WITH > FUNCTION SPECIFIC PREFIXES! Actually, not really. The Elisp convention to only use prefixes for global variables is 99% sufficient. In your example, the problem is that `some-function' modifies the (presumably global) variable `scratch-buffer' and that this variable does not have an appropriate prefix. The only case where non-prefixed local variables cause problem is when you introduce higher-order functions, as in: (defun my-map (f l) (if l (cons (funcall f (car l)) (my-map f (cdr l))))) (defun my-function (input) (let ((l ...)) (my-map (lambda (x) (unless (memq x l) (error "invalid mapping"))) input))) Suddenly the `l' used inside the lambda will not refer to the `l' nearby but to the `l' argument of `my-map'. For this reason, some higher-order functions used to use weird argument names to try and avoid such name capture. Nowadays they can use lexical scoping and hence choose their variable names sanely and without fear. Stefan ^ permalink raw reply [flat|nested] 48+ messages in thread
* Re: Real-life examples of lexical binding in Emacs Lisp 2015-06-17 14:42 ` Stefan Monnier @ 2015-06-17 16:19 ` Andreas Röhler 2015-06-17 19:30 ` Tassilo Horn [not found] ` <mailman.5171.1434557990.904.help-gnu-emacs@gnu.org> 2015-06-17 20:22 ` Emanuel Berg 2 siblings, 1 reply; 48+ messages in thread From: Andreas Röhler @ 2015-06-17 16:19 UTC (permalink / raw) To: help-gnu-emacs Am 17.06.2015 um 16:42 schrieb Stefan Monnier: >> Without lexical binding, to try to get some independence from other >> functions, you would have to PREFIX ALL THE LOCAL VARIABLES WITH >> FUNCTION SPECIFIC PREFIXES! > Actually, not really. The Elisp convention to only use prefixes for > global variables is 99% sufficient. In your example, the problem is > that `some-function' modifies the (presumably global) variable > `scratch-buffer' and that this variable does not have an > appropriate prefix. > > The only case where non-prefixed local variables cause problem is when > you introduce higher-order functions, as in: > > (defun my-map (f l) > (if l (cons (funcall f (car l)) (my-map f (cdr l))))) > > (defun my-function (input) > (let ((l ...)) > (my-map (lambda (x) (unless (memq x l) (error "invalid mapping"))) > input))) > > Suddenly the `l' used inside the lambda will not refer to the `l' nearby > but to the `l' argument of `my-map'. For this reason, some higher-order > functions used to use weird argument names to try and avoid such > name capture. Nowadays they can use lexical scoping and hence choose > their variable names sanely and without fear. > > Checked this with ;;; -*- lexical-binding: t; -*- (defun my-map (f l) (if l (cons (funcall f (car l)) (my-map f (cdr l))))) (defun my-function (input) (let ((l ())) (my-map (lambda (x) (unless (memq x l) (error "invalid mapping"))) input))) (my-function '(4 5)) Got identic results also without lexical-binding seen here. l is taken from inside lambda in both modes. ^ permalink raw reply [flat|nested] 48+ messages in thread
* Re: Real-life examples of lexical binding in Emacs Lisp 2015-06-17 16:19 ` Andreas Röhler @ 2015-06-17 19:30 ` Tassilo Horn 0 siblings, 0 replies; 48+ messages in thread From: Tassilo Horn @ 2015-06-17 19:30 UTC (permalink / raw) To: Andreas Röhler; +Cc: help-gnu-emacs Andreas Röhler <andreas.roehler@easy-emacs.de> writes: > ;;; -*- lexical-binding: t; -*- > > (defun my-map (f l) > (if l (cons (funcall f (car l)) (my-map f (cdr l))))) > > (defun my-function (input) > (let ((l ())) > (my-map (lambda (x) (unless (memq x l) (error "invalid mapping"))) > input))) > > (my-function '(4 5)) > > Got identic results also without lexical-binding seen here. l is > taken from inside lambda in both modes. You have to byte-compile. Then you get for the lexical version: --8<---------------cut here---------------start------------->8--- byte code for my-function: doc: ... args: 257 0 constant nil 1 constant my-map 2 constant make-byte-code 3 constant 257 4 constant "\211\300>?\205\n.\301\302!\207" 5 constant vconcat 6 constant vector 7 stack-ref 6 9 call 1 10 constant [error "invalid mapping"] 11 call 2 12 constant 3 13 constant "\n\n(fn X)" 14 call 5 15 stack-ref 3 16 call 2 17 return --8<---------------cut here---------------end--------------->8--- That gives: (my-function '(4 5)) => Lisp error: (error "invalid mapping") For the dynamic version: --8<---------------cut here---------------start------------->8--- byte code for my-function: args: (input) 0 constant nil 1 varbind l 2 constant my-map 3 constant <compiled-function> args: (x) 0 varref x 1 varref l 2 memq 3 not 4 goto-if-nil-else-pop 1 7 constant error 8 constant "invalid mapping" 9 call 1 10:1 return 4 varref input 5 call 2 6 unbind 1 7 return --8<---------------cut here---------------end--------------->8--- Note the varref l. When the lambda is called in the dynamic version, l will refer to the l argument from my-map. That gives: (my-function '(4 5)) => (nil nil) Bye, Tassilo ^ permalink raw reply [flat|nested] 48+ messages in thread
[parent not found: <mailman.5171.1434557990.904.help-gnu-emacs@gnu.org>]
* Re: Real-life examples of lexical binding in Emacs Lisp [not found] ` <mailman.5171.1434557990.904.help-gnu-emacs@gnu.org> @ 2015-06-17 17:12 ` Stefan Monnier 0 siblings, 0 replies; 48+ messages in thread From: Stefan Monnier @ 2015-06-17 17:12 UTC (permalink / raw) To: help-gnu-emacs > Got identical results also without lexical-binding seen here. You obviously botched the test for when lexical-binding is nil. My crystal ball tells me you just changed the ":t" to ":nil" without making sure this directive is re-evaluated (which happens when the file is opened). > l is taken from inside lambda in both modes. This doesn't make any sense: there is no `l' bound inside the lambda. Stefan ^ permalink raw reply [flat|nested] 48+ messages in thread
* Re: Real-life examples of lexical binding in Emacs Lisp 2015-06-17 14:42 ` Stefan Monnier 2015-06-17 16:19 ` Andreas Röhler [not found] ` <mailman.5171.1434557990.904.help-gnu-emacs@gnu.org> @ 2015-06-17 20:22 ` Emanuel Berg 2015-06-17 22:13 ` Pascal J. Bourguignon 2015-06-18 14:57 ` Udyant Wig 2 siblings, 2 replies; 48+ messages in thread From: Emanuel Berg @ 2015-06-17 20:22 UTC (permalink / raw) To: help-gnu-emacs Stefan Monnier <monnier@iro.umontreal.ca> writes: >> independence from other functions, you would have >> to PREFIX ALL THE LOCAL VARIABLES WITH FUNCTION >> SPECIFIC PREFIXES! > > Actually, not really. The Elisp convention to only > use prefixes for global variables is 99% sufficient. > In your example, the problem is that `some-function' > modifies the (presumably global) variable > `scratch-buffer' and that this variable does not > have an appropriate prefix. I'm curious, the techno-science books always speak of LISP as a language for "symbolic manipulation". Sometimes they mention AI. Anyone care to explain this? Does it somehow relate to the "dynamic scope"? Or is an implementation-derived situation, i.e. a practical measure somewhere along the way? > The only case where non-prefixed local variables > cause problem is when you introduce higher-order > functions, as in: > > (defun my-map (f l) (if l (cons (funcall f (car l)) > (my-map f (cdr l))))) > > (defun my-function (input) (let ((l ...)) (my-map > (lambda (x) (unless (memq x l) (error "invalid > mapping"))) input))) > > Suddenly the `l' used inside the lambda will not > refer to the `l' nearby but to the `l' argument of > `my-map'. For this reason, some higher-order > functions used to use weird argument names to try > and avoid such name capture. Nowadays they can use > lexical scoping and hence choose their variable > names sanely and without fear. And that is not only desired for that reason but also for "1-order functions" (? - i.e., a plebeian function with non-function arguments only) because then you can just name your variables whatever comes to mind - be it good or bad, you don't want to worry about the world outside that cozy form. It is the blue collar bottom up, contrary to the "top-down" (yuk!) hysteria of white collar hackers... I once read that "the programmer has the whole program in his head" (pseudo-quote). That's not how I experience it. I have some general knowledge of the entire program for sure, but the only thing I have 100% in my head is the function or even code block I'm currently typing. The dynamic scope breaks that zone of comfort, which here, is where you want to be. This "dynamic scope" as a method is like programming on acid with the ant queen communicating to her minions through telepathy telling them what to do all the time. "Lexical scope" is layed-back, having the ants do their work semi-autonomously, now and then interfering to solve a well-defined and delimited problem. ... Right? -- underground experts united http://user.it.uu.se/~embe8573 ^ permalink raw reply [flat|nested] 48+ messages in thread
* Re: Real-life examples of lexical binding in Emacs Lisp 2015-06-17 20:22 ` Emanuel Berg @ 2015-06-17 22:13 ` Pascal J. Bourguignon 2015-06-17 23:46 ` Emanuel Berg 2015-06-18 14:57 ` Udyant Wig 1 sibling, 1 reply; 48+ messages in thread From: Pascal J. Bourguignon @ 2015-06-17 22:13 UTC (permalink / raw) To: help-gnu-emacs Emanuel Berg <embe8573@student.uu.se> writes: > Stefan Monnier <monnier@iro.umontreal.ca> writes: > >>> independence from other functions, you would have >>> to PREFIX ALL THE LOCAL VARIABLES WITH FUNCTION >>> SPECIFIC PREFIXES! >> >> Actually, not really. The Elisp convention to only >> use prefixes for global variables is 99% sufficient. >> In your example, the problem is that `some-function' >> modifies the (presumably global) variable >> `scratch-buffer' and that this variable does not >> have an appropriate prefix. > > I'm curious, the techno-science books always speak of > LISP as a language for "symbolic manipulation". > Sometimes they mention AI. Anyone care to explain > this? This is because the stress the language puts on symbols and symbolic expressions (sexps) and the availability of operators to easily process them. Consider a simple function to derivate functions (it's about 100 lines of lisp code), allowing to do things like: (simplify (deriv-expr '(+ (* 3 x x) (* 9 x) 3) 'x)) --> (+ (* 6 x) 9) Or consider some natural language processing program, like eliza, or this expression generator: http://paste.lisp.org/+37QP In early eliza, the natural language words were represented using symbols (nowadays, lisp NLP programs would use strings for the representation of words, or even CLOS objects, but there would still be good arguments for the use of symbols with property lists in terms of simplicity and flexibility). Anyways, in expressions like: (defvar insults '( ("accapareur" (nm)) ("aérolithe" (nm)) ("amiral de bateaulavoir" (gnm)) ("anacoluthe" (nf)) ("analphabète" (n a)) ("athlète complet" (n)) ("boitsanssoif" (ni)) ("vieux" (a)) ;; … )) (defvar nm (remove-if-not (lambda (x) (intersection '(n np nm gnm) (second x))) insults)) (defvar nf (remove-if-not (lambda (x) (intersection '(nf np) (second x))) insults)) (defvar ad (remove-if-not (lambda (x) (member 'a (second x))) insults)) the use of symbols to denote the grammatical categories, and their manipulation to sort out the lexicon is very easy and natural. In lisp, it's easy to program something like that, because you don't need to do anything special to encode a symbol like x or nm. In other programming language, the stress is often on some other data type, like int in C (if you don't write a type when declaring a variable, which is possible in C, it is int by default!). And you will also have vectors instead of lists, so as soon as you write a collection of data, you will HAVE to use integers, to index into those vectors (in lisp when using lists, you don't need integers, just the functions first and rest). So in those non-lisp languages, you will have to invent a representation for these symbolic data, using integers (constants, or enums), or strings, (or even objects! in OO languages). And naturally you will have to encode the data using those vectors of integers (and what if you need to mix integers representing integers and integer representing symbols as in (+ (* 3 x x) (* 9 x) 3)? Dang! Now you need some more complex representtion, perhaps a structure or an object with variants for integers and symbols. And soon you're re-implementing a half-assed buggy lisp: you are greenspunning. A function to perform symbolic derivation was one of the first lisp programs written by John McCarthy, this was exactly the kind of application he had in mind for lisp; nowadays we have maxima :-) (And mathematica which is to maxima what ruby is to lisp). For an early symbolic application have a look at Wang's algorithm for propositional calculus: http://www.informatimago.com/develop/lisp/com/informatimago/small-cl-pgms/wang.html > Does it somehow relate to the "dynamic scope"? Not at all. Dynamic scope was just an implementation accident, because not enough about language design was know when lisp was invented. When you don't have theory, programs may just happen to behave a certain way depending on how they're implemented. This is what occured for lisp. McCarthy wanted to be able to define anonymous functions using Church's lambda notation, and it was implemented, but since we didn't have the language design theory about scopes and bindings, it just happened that dynamic binding as implemented, and then somebody remarked that this was a problem (the so called funarg problem), and they spent ten years developing the theory and practical solution with lexical binding. > Or is an implementation-derived situation, i.e. > a practical measure somewhere along the way? Yes. > I once read that "the programmer has the whole program > in his head" (pseudo-quote). That's not how > I experience it. I have some general knowledge of the > entire program for sure, but the only thing I have > 100% in my head is the function or even code block I'm > currently typing. The dynamic scope breaks that zone > of comfort, which here, is where you want to be. Of course. You could have the whole program in your head, when computers had 4 Kwords of memory, and the whole program was at most a ten-page listing. But nowadays programs are tens of megabytes of sources! (Firefox sources were more than 50 megabytes last time I checked; there are more than 50 MB; emacs are 51 MB compressed! $ ls -lh /usr/local/src/emacs-24.3.tar.gz -rw-r--r-- 1 pjb pjb 51M Dec 1 2013 /usr/local/src/emacs-24.3.tar.gz I've got more than 2.5 GIGA bytes of Common Lisp libraries sources! $ du -shc ~/quicklisp/dists/ 2.6G /home/pjb/quicklisp/dists/ Granted, this is not a single program, but a given program could use any subset of those libraries, so it is very important to ensure encapsulation, data hiding and locality of effects, and only lexical binding does that, not dynamic binding. > This "dynamic scope" as a method is like programming > on acid with the ant queen communicating to her > minions through telepathy telling them what to do all > the time. "Lexical scope" is layed-back, having the > ants do their work semi-autonomously, now and then > interfering to solve a well-defined and delimited > problem. ... Right? Indeed. A dynamic variable is global for the time of the dynamic scope. A lexical variable is local, for the space of the lexical scope. Notice time/space. This is important. Lexical means space, something that is statical and easily observable, eternal, with delimited contours. Dynamic means time, something that is dynamic, changing with time, and therefore more difficult to conceptualize and observe. We cannot "observe" time, we have to transform it into slowly moving mechanisms, so that we observe the SPACIAL position of the hands. Also, it's proven scientifically, that the brain constructs time perception in a non monotonous and linear way (check the experience, where we flash successive dots aligned on a screen at a given rythm, red dots on the left side, and green dot on the right side. People will tell you that the dots changed color right in the middle between the red and green dots, which is not possible, because they didn't know that the next dot would be green at the time the imaginary moving dot passed on this middle! So time is hard on us, and dynamic is difficult to reason about, and therefore it leads to more bugs. -- __Pascal Bourguignon__ http://www.informatimago.com/ “The factory of the future will have only two employees, a man and a dog. The man will be there to feed the dog. The dog will be there to keep the man from touching the equipment.” -- Carl Bass CEO Autodesk ^ permalink raw reply [flat|nested] 48+ messages in thread
* Re: Real-life examples of lexical binding in Emacs Lisp 2015-06-17 22:13 ` Pascal J. Bourguignon @ 2015-06-17 23:46 ` Emanuel Berg 0 siblings, 0 replies; 48+ messages in thread From: Emanuel Berg @ 2015-06-17 23:46 UTC (permalink / raw) To: help-gnu-emacs "Pascal J. Bourguignon" <pjb@informatimago.com> writes: > This is because the stress the language puts on > symbols and symbolic expressions (sexps) and the > availability of operators to easily process them ... Man, you should send this post to a magazine! -- underground experts united http://user.it.uu.se/~embe8573 ^ permalink raw reply [flat|nested] 48+ messages in thread
* Re: Real-life examples of lexical binding in Emacs Lisp 2015-06-17 20:22 ` Emanuel Berg 2015-06-17 22:13 ` Pascal J. Bourguignon @ 2015-06-18 14:57 ` Udyant Wig 2015-06-18 15:47 ` Emanuel Berg 1 sibling, 1 reply; 48+ messages in thread From: Udyant Wig @ 2015-06-18 14:57 UTC (permalink / raw) To: help-gnu-emacs Emanuel Berg <embe8573@student.uu.se> writes: > I'm curious, the techno-science books always speak of LISP as a > language for "symbolic manipulation". I really wish they'd get on with the times and start speaking of "Lisp" instead of "LISP". -- Udyant Wig GitHub: https://github.com/udyant Poetry: http://www.writing.com/main/profile/biography/frosthrone ^ permalink raw reply [flat|nested] 48+ messages in thread
* Re: Real-life examples of lexical binding in Emacs Lisp 2015-06-18 14:57 ` Udyant Wig @ 2015-06-18 15:47 ` Emanuel Berg 2015-06-19 13:49 ` Udyant Wig 0 siblings, 1 reply; 48+ messages in thread From: Emanuel Berg @ 2015-06-18 15:47 UTC (permalink / raw) To: help-gnu-emacs Udyant Wig <udyantw@gmail.com> writes: >> I'm curious, the techno-science books always speak >> of LISP as a language for "symbolic manipulation". > > I really wish they'd get on with the times and start > speaking of "Lisp" instead of "LISP". Is there an agreed-upon rule what is what? I use "LISP" in the context of the history and origin of the technology but I don't have a defined endpoint at what time history gives way to your everyday "Lisp". -- underground experts united http://user.it.uu.se/~embe8573 ^ permalink raw reply [flat|nested] 48+ messages in thread
* Re: Real-life examples of lexical binding in Emacs Lisp 2015-06-18 15:47 ` Emanuel Berg @ 2015-06-19 13:49 ` Udyant Wig 0 siblings, 0 replies; 48+ messages in thread From: Udyant Wig @ 2015-06-19 13:49 UTC (permalink / raw) To: help-gnu-emacs Emanuel Berg <embe8573@student.uu.se> writes: > I use "LISP" in the context of the history and origin > of the technology but I don't have a defined endpoint > at what time history gives way to your everyday > "Lisp". It seems to have been a byproduct of the general attitude that also made "UNIX" "Unix", "COBOL" "Cobol", "FORTH" "Forth", "EMACS" "Emacs", etc. -- Udyant Wig GitHub: https://github.com/udyant Poetry: http://www.writing.com/main/profile/biography/frosthrone ^ permalink raw reply [flat|nested] 48+ messages in thread
* Re: Real-life examples of lexical binding in Emacs Lisp [not found] ` <mailman.5136.1434522217.904.help-gnu-emacs@gnu.org> 2015-06-17 10:49 ` Pascal J. Bourguignon @ 2015-06-17 20:33 ` Emanuel Berg 2015-06-17 22:07 ` Robert Thorpe 1 sibling, 1 reply; 48+ messages in thread From: Emanuel Berg @ 2015-06-17 20:33 UTC (permalink / raw) To: help-gnu-emacs Andreas Röhler <andreas.roehler@easy-emacs.de> writes: > Seems neither "lexical" nor "dynamic" express the > real thing. I take it "lexical" refers to you can make it out by looking at the code. "Dynamic" refers to it depends on the code and the program state in execution. I agree those terms are confusing. To me, it sounds like they refer to call-by-value vs. call-by-reference, which isn't so. I'd call it "normal scope" vs. "stacked scope", perhaps. > Nonetheless, that's the way Emacs acted all the > time, while called "dynamically" scoped. Well yeah, no one said it can't be done that way. I experience it as unnatural and consider it unpractical, but I'm not saying it cannot be done that way. The supreme techno-pope will beat his cardinals to the punch using anything, however typically he is using the *best* thing (that's why he is number one) and then the cardinals better do the same if they can less they are at an ever worse disadvantage. No one is telling you you can't use it or that it is inherently bad and always so. However tho a non-conformist myself I dare say here my intuition coincides with how most programmers will see it - be it by genes or upbringing. -- underground experts united http://user.it.uu.se/~embe8573 ^ permalink raw reply [flat|nested] 48+ messages in thread
* Re: Real-life examples of lexical binding in Emacs Lisp 2015-06-17 20:33 ` Emanuel Berg @ 2015-06-17 22:07 ` Robert Thorpe 2015-06-17 22:17 ` Pascal J. Bourguignon 0 siblings, 1 reply; 48+ messages in thread From: Robert Thorpe @ 2015-06-17 22:07 UTC (permalink / raw) To: Emanuel Berg; +Cc: help-gnu-emacs Emanuel Berg <embe8573@student.uu.se> writes: > I take it "lexical" refers to you can make it out by > looking at the code. Yes. > "Dynamic" refers to it depends on the code and the > program state in execution. Yes. > I agree those terms are confusing. To me, it sounds > like they refer to call-by-value vs. > call-by-reference, which isn't so. > > I'd call it "normal scope" vs. > "stacked scope", perhaps. Both cases are usually implemented using stacks. Thinking about this helps understanding. In the lexical scope case we can think of one huge stack. Each entry in the stack can contain many elements. When execution enters a "let" form a new entry is created on the stack and the variables declared there are stored in that entry. They "shadow" other variables with the same name - they take precedence over them. When execution exits the let form that stack entry is deleted. This is usually how lexical scope is implement too. For dynamic scope we can think of each variable name as being associated with it's own stack. When execution reaches a let form a new value is pushed onto the stack for the relevant name. When the let form exits it's deleted from the top of the stack. Code always uses the top-of-stack value, so earlier let forms are shadowed by later ones. This is one way of implementing dynamic scope too, it's "shallow binding". I think it's how Elisp implements it. Dynamic scope was an accident of how Lisp was first written. See: http://www-formal.stanford.edu/jmc/history/lisp/node4.html The question of "extent" rather than "scope" brings up more problems. So does "deep" vs "shallow" binding with dynamic scope. BR, Robert Thorpe ^ permalink raw reply [flat|nested] 48+ messages in thread
* Re: Real-life examples of lexical binding in Emacs Lisp 2015-06-17 22:07 ` Robert Thorpe @ 2015-06-17 22:17 ` Pascal J. Bourguignon 0 siblings, 0 replies; 48+ messages in thread From: Pascal J. Bourguignon @ 2015-06-17 22:17 UTC (permalink / raw) To: help-gnu-emacs Robert Thorpe <rt@robertthorpeconsulting.com> writes: > Emanuel Berg <embe8573@student.uu.se> writes: >> I take it "lexical" refers to you can make it out by >> looking at the code. > > Yes. > >> "Dynamic" refers to it depends on the code and the >> program state in execution. > > Yes. > >> I agree those terms are confusing. To me, it sounds >> like they refer to call-by-value vs. >> call-by-reference, which isn't so. >> >> I'd call it "normal scope" vs. >> "stacked scope", perhaps. > > Both cases are usually implemented using stacks. Thinking about this > helps understanding. > > In the lexical scope case we can think of one huge stack. Each entry in > the stack can contain many elements. When execution enters a "let" form > a new entry is created on the stack and the variables declared there are > stored in that entry. They "shadow" other variables with the same name > - they take precedence over them. When execution exits the let form > that stack entry is deleted. This is usually how lexical scope is > implement too. However, contrarily to dynamic binding, lexical binding requires the use of the heap to implement non-delimited closures. This is why it was less obvious. -- __Pascal Bourguignon__ http://www.informatimago.com/ “The factory of the future will have only two employees, a man and a dog. The man will be there to feed the dog. The dog will be there to keep the man from touching the equipment.” -- Carl Bass CEO Autodesk ^ permalink raw reply [flat|nested] 48+ messages in thread
* Re: Real-life examples of lexical binding in Emacs Lisp 2015-06-16 23:48 ` Jim Diamond 2015-06-17 0:06 ` Emanuel Berg @ 2015-06-17 0:43 ` Pascal J. Bourguignon 2015-06-17 16:02 ` Phillip Lord [not found] ` <mailman.5167.1434556959.904.help-gnu-emacs@gnu.org> 3 siblings, 0 replies; 48+ messages in thread From: Pascal J. Bourguignon @ 2015-06-17 0:43 UTC (permalink / raw) To: help-gnu-emacs Jim Diamond <Jim.Diamond@deletethis.AcadiaU.ca> writes: > On 2015-06-14 at 08:31 ADT, Pascal J. Bourguignon <pjb@informatimago.com> wrote: >> Marcin Borkowski <mbork@mbork.pl> writes: >> >>> Exactly. What I'm curious is how lexical scoping might make some tasks >>> *connected to editing* easier/more natural. > > <snip> > >> Writing programs is easier and more natural with lexical scoping, IN >> GENERAL! > > <snip> > > Really? Are there well-agreed-upon studies showing those things? > Or are they your opinion? Yes, there are well-agreed-upon studies showing this. This is the reason ALL programming languages created since 1970, use lexical binding exclusively. > It strikes me that lexical scoping is easier to implement for compiled > languages (that is an "off the cuff" comment from someone (me) with > basic knowledge of compiler construction). But if lexical scoping is > "more natural", is that because more people were "brought up" with > lexically-scoped languages than dynamically-scoped languages? No, this is for theorical reasons, and in practice, because lexical scoping allows to understand the semantics of programs by just looking at the source, without executing it, and therefore make it easier on the programmers, and ease debugging and maintainance. > A few versions of emacs ago something I was using went from dynamic > scoping to lexical scoping. Working around that change was not > trivial, casting suspicion on the universality of "easier". The not trivial comes from the fact that it was wanted to perform the transition without rewriting all the existing elisp code, not only in the GNU emacs distribution, but also all the unpublished elisp code on the disks of all the users. Therefore, in emacs: 1- dynamic binding is still the default, 2- lexical binding is optional (you have to mark a file specially to get it). There may also be some technicalities with respect to the buffer-local variables which is an emacs specific complexity; I've not looked into it yet. Also, I would say that in emacs, given the number of hooks there are, lexical binding should demonstrate definite and overwhelming advantages over dynamic binding, since there is no closure with dynamic binding. For example, compare: (setq lexical-binding nil) (let ((message (read-from-minibuffer "Message: "))) (push (lambda () (insert message)) text-mode-hook)) [enter some text, type RET, then switch to *scratch* and:] M-x text-mode RET (pop text-mode-hook) with: (setq lexical-binding t) (let ((message (read-from-minibuffer "Message: "))) (push (lambda () (insert message)) text-mode-hook)) [enter some text, type RET, then switch to *scratch* and:] M-x text-mode RET (pop text-mode-hook) -- __Pascal Bourguignon__ http://www.informatimago.com/ “The factory of the future will have only two employees, a man and a dog. The man will be there to feed the dog. The dog will be there to keep the man from touching the equipment.” -- Carl Bass CEO Autodesk ^ permalink raw reply [flat|nested] 48+ messages in thread
* Re: Real-life examples of lexical binding in Emacs Lisp 2015-06-16 23:48 ` Jim Diamond 2015-06-17 0:06 ` Emanuel Berg 2015-06-17 0:43 ` Pascal J. Bourguignon @ 2015-06-17 16:02 ` Phillip Lord [not found] ` <mailman.5167.1434556959.904.help-gnu-emacs@gnu.org> 3 siblings, 0 replies; 48+ messages in thread From: Phillip Lord @ 2015-06-17 16:02 UTC (permalink / raw) To: Jim Diamond; +Cc: help-gnu-emacs Jim Diamond <Jim.Diamond@deletethis.AcadiaU.ca> writes: > The first language I "learned" was lexically scoped. But the first > language I used a lot was dynamically scoped. It seemed quite > reasonable and natural to me at the time. > > A few versions of emacs ago something I was using went from dynamic > scoping to lexical scoping. Working around that change was not > trivial, casting suspicion on the universality of "easier". You should write these problems up, with your solutions. Potentially useful to someone else, iff they have the same problems. Phil ^ permalink raw reply [flat|nested] 48+ messages in thread
[parent not found: <mailman.5167.1434556959.904.help-gnu-emacs@gnu.org>]
* Re: Real-life examples of lexical binding in Emacs Lisp [not found] ` <mailman.5167.1434556959.904.help-gnu-emacs@gnu.org> @ 2015-06-23 23:49 ` Jim Diamond 0 siblings, 0 replies; 48+ messages in thread From: Jim Diamond @ 2015-06-23 23:49 UTC (permalink / raw) To: help-gnu-emacs On 2015-06-17 at 13:02 ADT, Phillip Lord <phillip.lord@newcastle.ac.uk> wrote: > Jim Diamond <Jim.Diamond@deletethis.AcadiaU.ca> writes: >> The first language I "learned" was lexically scoped. But the first >> language I used a lot was dynamically scoped. It seemed quite >> reasonable and natural to me at the time. >> >> A few versions of emacs ago something I was using went from dynamic >> scoping to lexical scoping. Working around that change was not >> trivial, casting suspicion on the universality of "easier". > > > You should write these problems up, with your solutions. Potentially > useful to someone else, iff they have the same problems. Phil, It is quite a while ago now, and took me a while to dig up the details. Reviewing the solution, I see that it required a patch to a file which went from dynamic scoping to lexical scoping. Stefan Monnier was a huge help in getting this sorted out. Anyone interested in the particular issue and the particular solution can read the messages in the thread found at http://lists.gnu.org/archive/html/help-gnu-emacs/2012-06/msg00040.html It is not all that long. Cheers. Jim ^ permalink raw reply [flat|nested] 48+ messages in thread
[parent not found: <mailman.3950.1432974543.904.help-gnu-emacs@gnu.org>]
* Re: Real-life examples of lexical binding in Emacs Lisp [not found] ` <mailman.3950.1432974543.904.help-gnu-emacs@gnu.org> @ 2015-05-30 12:59 ` Pascal J. Bourguignon 2015-06-14 10:55 ` Marcin Borkowski [not found] ` <mailman.4977.1434279342.904.help-gnu-emacs@gnu.org> 0 siblings, 2 replies; 48+ messages in thread From: Pascal J. Bourguignon @ 2015-05-30 12:59 UTC (permalink / raw) To: help-gnu-emacs Tassilo Horn <tsdh@gnu.org> writes: > The emacs paper has a section explaining why emacs used dynamic binding > from the start: http://www.gnu.org/software/emacs/emacs-paper.html#SEC17 > > However, to me the two example use-cases only motivate why you want to > be able to use dynamic scoping for special variables (defvar), not > really for local variables (let) or function parameters, although the > first Edit Picture example explicitly speaks of binding command > arguments but I don't understand it. Indeed, in general, you want lexical binding for local variables. However, I would argue that for global variables, lexical binding would be useful too, even by default. In Common Lisp, we can implement global lexical variables, using eg. symbol macros, but in emacs lisp, we're missing operators for the global lexical case: dynamic lexical global defvar - local let(1) let(2) (1) when lexical-binding is nil or the variable has been defvar'ed. (2) when lexical-binding is t and the variable has not been defvar'ed. > But there are good use-cases for dynamic variables also in "normal" > programs. One example is to be able to bind some *error-handler* > dynamically in order to customize how to cope with errors that happen > far below the call stack. Definitely. https://groups.google.com/forum/#!original/comp.lang.lisp/oC5gDvn42pM/IudCXzCtxowJ -- __Pascal Bourguignon__ http://www.informatimago.com/ “The factory of the future will have only two employees, a man and a dog. The man will be there to feed the dog. The dog will be there to keep the man from touching the equipment.” -- Carl Bass CEO Autodesk ^ permalink raw reply [flat|nested] 48+ messages in thread
* Re: Real-life examples of lexical binding in Emacs Lisp 2015-05-30 12:59 ` Pascal J. Bourguignon @ 2015-06-14 10:55 ` Marcin Borkowski [not found] ` <mailman.4977.1434279342.904.help-gnu-emacs@gnu.org> 1 sibling, 0 replies; 48+ messages in thread From: Marcin Borkowski @ 2015-06-14 10:55 UTC (permalink / raw) To: help-gnu-emacs On 2015-05-30, at 14:59, Pascal J. Bourguignon <pjb@informatimago.com> wrote: > Tassilo Horn <tsdh@gnu.org> writes: > >> The emacs paper has a section explaining why emacs used dynamic binding >> from the start: http://www.gnu.org/software/emacs/emacs-paper.html#SEC17 >> >> However, to me the two example use-cases only motivate why you want to >> be able to use dynamic scoping for special variables (defvar), not >> really for local variables (let) or function parameters, although the >> first Edit Picture example explicitly speaks of binding command >> arguments but I don't understand it. > > Indeed, in general, you want lexical binding for local variables. > > However, I would argue that for global variables, lexical binding would > be useful too, even by default. > > In Common Lisp, we can implement global lexical variables, using > eg. symbol macros, but in emacs lisp, we're missing operators for the > global lexical case: > > dynamic lexical > global defvar - > local let(1) let(2) > > (1) when lexical-binding is nil or the variable has been defvar'ed. > (2) when lexical-binding is t and the variable has not been defvar'ed. > > >> But there are good use-cases for dynamic variables also in "normal" >> programs. One example is to be able to bind some *error-handler* >> dynamically in order to customize how to cope with errors that happen >> far below the call stack. > > Definitely. > > https://groups.google.com/forum/#!original/comp.lang.lisp/oC5gDvn42pM/IudCXzCtxowJ I'm sorry to say that I didn't understand that post. (Though I admit that I didn't try /very/ hard. I'll try harder again later.) Thanks anyway, -- Marcin Borkowski http://octd.wmi.amu.edu.pl/en/Marcin_Borkowski Faculty of Mathematics and Computer Science Adam Mickiewicz University ^ permalink raw reply [flat|nested] 48+ messages in thread
[parent not found: <mailman.4977.1434279342.904.help-gnu-emacs@gnu.org>]
* Re: Real-life examples of lexical binding in Emacs Lisp [not found] ` <mailman.4977.1434279342.904.help-gnu-emacs@gnu.org> @ 2015-06-14 20:04 ` Stefan Monnier 2015-06-14 21:44 ` Pascal J. Bourguignon 0 siblings, 1 reply; 48+ messages in thread From: Stefan Monnier @ 2015-06-14 20:04 UTC (permalink / raw) To: help-gnu-emacs >> However, I would argue that for global variables, lexical binding would >> be useful too, even by default. I'm not sure what that means. But you can set a global value to a variable without declaring it as dynamically scoped: (setq my-lex-var 3) Inside Emacs we also have a few global vars (e.g. `pi' and `argv') which we would want to declare with something like defvar for various reasons (providing a docstring, recording where is the declaration, etc...) yet we don't want them to be dynamically scoped. For `pi' we just used `setq', and for `argv' we used defvar followed by an ugly hack called internal-make-var-non-special. Stefan ^ permalink raw reply [flat|nested] 48+ messages in thread
* Re: Real-life examples of lexical binding in Emacs Lisp 2015-06-14 20:04 ` Stefan Monnier @ 2015-06-14 21:44 ` Pascal J. Bourguignon 2015-06-14 21:49 ` Pascal J. Bourguignon 0 siblings, 1 reply; 48+ messages in thread From: Pascal J. Bourguignon @ 2015-06-14 21:44 UTC (permalink / raw) To: help-gnu-emacs Stefan Monnier <monnier@iro.umontreal.ca> writes: >>> However, I would argue that for global variables, lexical binding would >>> be useful too, even by default. > > I'm not sure what that means. But you can set a global value to > a variable without declaring it as dynamically scoped: > > (setq my-lex-var 3) Wrong. Having a file lex.el: ------------------------------------------------------------------------ ;; -*- mode:emacs-lisp; lexical-binding:nil -*- (setq lexical? 33) (defun f () lexical?) (defun g () (let ((lexical? 42)) (f))) (print (g)) ------------------------------------------------------------------------ Then M-x load-file RET lex.el RET writes 42 in *Message* which shows that lexical? IS a dynamic variable! If it was lexical, we would get 33, because the lexical scope of the closure f is the global scope, where lexical? as been bound to 33, not the local dynamic scope of the function g when the variable lexical? is bound to 42. > Inside Emacs we also have a few global vars (e.g. `pi' and `argv') which > we would want to declare with something like defvar for various reasons > (providing a docstring, recording where is the declaration, etc...) yet > we don't want them to be dynamically scoped. > > For `pi' we just used `setq', and for `argv' we used defvar followed by > an ugly hack called internal-make-var-non-special. > > > Stefan -- __Pascal Bourguignon__ http://www.informatimago.com/ “The factory of the future will have only two employees, a man and a dog. The man will be there to feed the dog. The dog will be there to keep the man from touching the equipment.” -- Carl Bass CEO Autodesk ^ permalink raw reply [flat|nested] 48+ messages in thread
* Re: Real-life examples of lexical binding in Emacs Lisp 2015-06-14 21:44 ` Pascal J. Bourguignon @ 2015-06-14 21:49 ` Pascal J. Bourguignon 0 siblings, 0 replies; 48+ messages in thread From: Pascal J. Bourguignon @ 2015-06-14 21:49 UTC (permalink / raw) To: help-gnu-emacs "Pascal J. Bourguignon" <pjb@informatimago.com> writes: > Stefan Monnier <monnier@iro.umontreal.ca> writes: > >>>> However, I would argue that for global variables, lexical binding would >>>> be useful too, even by default. >> >> I'm not sure what that means. But you can set a global value to >> a variable without declaring it as dynamically scoped: >> >> (setq my-lex-var 3) > > Wrong. Not. > Having a file lex.el: > ------------------------------------------------------------------------ > ;; -*- mode:emacs-lisp; lexical-binding:nil -*- > > (setq lexical? 33) > (defun f () > lexical?) > (defun g () > (let ((lexical? 42)) > (f))) > > (print (g)) > ------------------------------------------------------------------------ > > Then M-x load-file RET lex.el RET writes 42 in *Message* which shows > that lexical? IS a dynamic variable! If it was lexical, we would get > 33, because the lexical scope of the closure f is the global scope, > where lexical? as been bound to 33, not the local dynamic scope of the > function g when the variable lexical? is bound to 42. Oops, sorry, I intended to run two tests. With lexical-binding:t indeed, setq defines the global variable and leaves it lexical. Reloading the file with lexical-binding:t even suppresses the dynamic aspect of a previously defined (with defvar) dynamic variable. -- __Pascal Bourguignon__ http://www.informatimago.com/ “The factory of the future will have only two employees, a man and a dog. The man will be there to feed the dog. The dog will be there to keep the man from touching the equipment.” -- Carl Bass CEO Autodesk ^ permalink raw reply [flat|nested] 48+ messages in thread
end of thread, other threads:[~2015-06-23 23:49 UTC | newest] Thread overview: 48+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- [not found] <mailman.3883.1432888152.904.help-gnu-emacs@gnu.org> 2015-05-29 9:30 ` Real-life examples of lexical binding in Emacs Lisp Joost Kremers 2015-05-29 11:12 ` Andreas Röhler 2015-05-29 12:13 ` Dmitry Gutov 2015-05-29 16:21 ` Phillip Lord 2015-05-29 16:50 ` Yuri Khan 2015-05-29 12:28 ` Pascal J. Bourguignon 2015-05-29 17:16 ` Andreas Röhler 2015-05-29 18:43 ` Emanuel Berg 2015-05-30 5:49 ` Rusi 2015-05-30 12:50 ` Pascal J. Bourguignon 2015-05-30 15:23 ` Rusi 2015-05-30 15:50 ` Pascal J. Bourguignon 2015-05-30 16:21 ` Rusi 2015-05-30 16:03 ` Emanuel Berg 2015-05-30 16:32 ` Rusi 2015-05-30 16:54 ` Pascal J. Bourguignon 2015-05-30 17:10 ` Rusi 2015-05-30 19:12 ` Pascal J. Bourguignon 2015-05-29 8:28 Marcin Borkowski 2015-05-30 8:28 ` Tassilo Horn 2015-06-14 10:52 ` Marcin Borkowski [not found] ` <mailman.4976.1434279182.904.help-gnu-emacs@gnu.org> 2015-06-14 11:31 ` Pascal J. Bourguignon 2015-06-16 23:48 ` Jim Diamond 2015-06-17 0:06 ` Emanuel Berg 2015-06-17 6:23 ` Andreas Röhler [not found] ` <mailman.5136.1434522217.904.help-gnu-emacs@gnu.org> 2015-06-17 10:49 ` Pascal J. Bourguignon 2015-06-17 10:53 ` Pascal J. Bourguignon 2015-06-17 14:42 ` Stefan Monnier 2015-06-17 16:19 ` Andreas Röhler 2015-06-17 19:30 ` Tassilo Horn [not found] ` <mailman.5171.1434557990.904.help-gnu-emacs@gnu.org> 2015-06-17 17:12 ` Stefan Monnier 2015-06-17 20:22 ` Emanuel Berg 2015-06-17 22:13 ` Pascal J. Bourguignon 2015-06-17 23:46 ` Emanuel Berg 2015-06-18 14:57 ` Udyant Wig 2015-06-18 15:47 ` Emanuel Berg 2015-06-19 13:49 ` Udyant Wig 2015-06-17 20:33 ` Emanuel Berg 2015-06-17 22:07 ` Robert Thorpe 2015-06-17 22:17 ` Pascal J. Bourguignon 2015-06-17 0:43 ` Pascal J. Bourguignon 2015-06-17 16:02 ` Phillip Lord [not found] ` <mailman.5167.1434556959.904.help-gnu-emacs@gnu.org> 2015-06-23 23:49 ` Jim Diamond [not found] ` <mailman.3950.1432974543.904.help-gnu-emacs@gnu.org> 2015-05-30 12:59 ` Pascal J. Bourguignon 2015-06-14 10:55 ` Marcin Borkowski [not found] ` <mailman.4977.1434279342.904.help-gnu-emacs@gnu.org> 2015-06-14 20:04 ` Stefan Monnier 2015-06-14 21:44 ` Pascal J. Bourguignon 2015-06-14 21:49 ` Pascal J. Bourguignon
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).