* Lexical vs. dynamic: small examples? @ 2021-08-14 3:34 Eduardo Ochs 2021-08-14 3:56 ` Emanuel Berg via Users list for the GNU Emacs text editor ` (3 more replies) 0 siblings, 4 replies; 61+ messages in thread From: Eduardo Ochs @ 2021-08-14 3:34 UTC (permalink / raw) To: help-gnu-emacs Hi list, I am trying to write a section on lexical vs. dynamic binding for a tutorial on Emacs Lisp, and I am looking for very short demos that show how things work differently in dynamic and in lexical binding... Right now what I have is this: http://angg.twu.net/eev-intros/find-lexical-intro.html (find-lexical-intro) I have tried really hard to the make its section "0. How to use this", that is at: http://angg.twu.net/eev-intros/find-lexical-intro.html#0 (find-lexical-intro "0. How to use this") both clear AND useful to people who do not use eev, and I think that the big example in section 3, http://angg.twu.net/eev-intros/find-lexical-intro.html#3 (find-lexical-intro "3. `get/set'") is quite nice - especially because of its last part, that inspects two different getter-setter pairs, shows that their lexical environments are the cadrs of their closures, and shows that `geta' and `seta' share the same lexical environment and that `getb' and `setb' share another lexical environment... My current knowledge of lexical binding stops there, though. Any comments (or help) would be very welcome... Cheers, Eduardo Ochs http://angg.twu.net/#eev ^ permalink raw reply [flat|nested] 61+ messages in thread
* Re: Lexical vs. dynamic: small examples? 2021-08-14 3:34 Lexical vs. dynamic: small examples? Eduardo Ochs @ 2021-08-14 3:56 ` Emanuel Berg via Users list for the GNU Emacs text editor 2021-08-14 4:12 ` Eduardo Ochs 2021-08-14 7:35 ` tomas ` (2 subsequent siblings) 3 siblings, 1 reply; 61+ messages in thread From: Emanuel Berg via Users list for the GNU Emacs text editor @ 2021-08-14 3:56 UTC (permalink / raw) To: help-gnu-emacs Eduardo Ochs wrote: > is quite nice - especially because of its last part, that > inspects two different getter-setter pairs, shows that their > lexical environments are the cadrs of their closures, and > shows that `geta' and `seta' share the same lexical > environment and that `getb' and `setb' share another lexical > environment... > > My current knowledge of lexical binding stops there, though. > Any comments (or help) would be very welcome... OK, IIUC with lexical (AKA static) binding the variable's value is determined by the code and the scope, so you can always find out what value it is by looking at that and move within that and only that delimited area. Move outside of that the variable bindings don't mean anything. Move from A to B, and you wanna know what goes on in B, it doesn't matter what happened in A and you look for the answer in BB (B and only B). Have a look: (let ((a 1)) (do-something a) ; 1 is here (do-something-else) ) ; but if a is referenced here, it isn't 1 ; not the same a! This is more useful and clear to the regular user and perhaps the advanced one as well and most people should think this natural from experience but also from what makes sense looking at that code :) This style seems to make for more independent, well-defined, more reusable and less vulnerable units of computation... With dynamic binding however the variable's value is rather read from the top of a stack data structure, everyone who sets the value then pushes it onto the top of the stack - and when it is unset that value is popped - but even so if it is thereafter referenced, it is still defined, one just looks for the plate below. This style is more like one mastermind keeping track of everything thru telepathy... -- underground experts united https://dataswamp.org/~incal ^ permalink raw reply [flat|nested] 61+ messages in thread
* Re: Lexical vs. dynamic: small examples? 2021-08-14 3:56 ` Emanuel Berg via Users list for the GNU Emacs text editor @ 2021-08-14 4:12 ` Eduardo Ochs 0 siblings, 0 replies; 61+ messages in thread From: Eduardo Ochs @ 2021-08-14 4:12 UTC (permalink / raw) To: Emanuel Berg, help-gnu-emacs On Sat, 14 Aug 2021 at 00:56, Emanuel Berg via Users list for the GNU Emacs text editor <help-gnu-emacs@gnu.org> wrote: > > Have a look: > > (let ((a 1)) > (do-something a) ; 1 is here > (do-something-else) ) ; but if a is referenced here, it isn't 1 > ; not the same a! Hi Emanuel, Thanks! I converted your idea to this... (setq a 42) (defun *a10 () (* a 10)) (let ((a 99)) (list (* a 10) (*a10)) ) (let ((b 99)) (list (* b 10) (*a10)) ) Cheers =), Eduardo Ochs ^ permalink raw reply [flat|nested] 61+ messages in thread
* Re: Lexical vs. dynamic: small examples? 2021-08-14 3:34 Lexical vs. dynamic: small examples? Eduardo Ochs 2021-08-14 3:56 ` Emanuel Berg via Users list for the GNU Emacs text editor @ 2021-08-14 7:35 ` tomas 2021-08-14 16:00 ` Eduardo Ochs 2021-08-14 19:31 ` Emanuel Berg via Users list for the GNU Emacs text editor 2021-08-14 13:35 ` [External] : " Drew Adams 2021-08-14 19:00 ` Gregory Heytings 3 siblings, 2 replies; 61+ messages in thread From: tomas @ 2021-08-14 7:35 UTC (permalink / raw) To: help-gnu-emacs [-- Attachment #1: Type: text/plain, Size: 2122 bytes --] On Sat, Aug 14, 2021 at 12:34:31AM -0300, Eduardo Ochs wrote: > Hi list, > > I am trying to write a section on lexical vs. dynamic binding for a > tutorial on Emacs Lisp, and I am looking for very short demos that > show how things work differently in dynamic and in lexical binding... > > Right now what I have is this: > > http://angg.twu.net/eev-intros/find-lexical-intro.html > (find-lexical-intro) Hm. I have the feeling that it'll difficult to appreciate the differences between lexical and dynamic bindings whithin such short snippets. You don't have much room to build up a lexical environment worth its salt :-) The metaphor which, for me, did "click" was: lexical binding is a binding along "space", dynamic binding along "time". Usually you want both (and civilised languages, like CL, Scheme, Perl [1] and, of course, Emacs Lisp, the most civilised of all) do offer facilities for both. The easiest default, though (for compilers and for users alike) is lexical binding. Especially if you use other people's code in yours. Imagine that library `setq'-ing xyzzy "down there", although xyzzy happens to be an important variable in your missile-control program (to reuse an already tired analogy ;-) Of course, civilised library providers wouldn't do that, they would make sure `xyzzy' is let-bound before `setq'-ing anything. If the dynamic state doesn't do uncommon things and only walks the stack "up and down", then it's their variable to `setq', no matter whether dynamically or lexically. The corollary is that for most civilised code, there is no difference whether it is interpreted in a lexical or dynamic scoping regime. Stefan, who has taken up the Herculean task of going through the existing Emacs Lisp code to convert it to lexical sure has a lot of interesting things to say about that :-) Cheers [1] Perl originally had only lexical scope, like any decent shell always had. It was with Perl5 (about 1994) that it acquired lexical scope (called "my" in Perl-land) as the recommended variable localisation strategy. - t [-- Attachment #2: Digital signature --] [-- Type: application/pgp-signature, Size: 198 bytes --] ^ permalink raw reply [flat|nested] 61+ messages in thread
* Re: Lexical vs. dynamic: small examples? 2021-08-14 7:35 ` tomas @ 2021-08-14 16:00 ` Eduardo Ochs 2021-08-14 19:41 ` Emanuel Berg via Users list for the GNU Emacs text editor 2021-08-14 20:42 ` tomas 2021-08-14 19:31 ` Emanuel Berg via Users list for the GNU Emacs text editor 1 sibling, 2 replies; 61+ messages in thread From: Eduardo Ochs @ 2021-08-14 16:00 UTC (permalink / raw) To: tomas; +Cc: help-gnu-emacs On Sat, 14 Aug 2021 at 04:35, <tomas@tuxteam.de> wrote: > > Hm. I have the feeling that it'll difficult to appreciate the > differences between lexical and dynamic bindings whithin such > short snippets. You don't have much room to build up a lexical > environment worth its salt :-) > > The metaphor which, for me, did "click" was: lexical binding is > a binding along "space", dynamic binding along "time". Hi Tomas, I forgot to explain some things about the style of that tutorial... I thought that they would be obvious, but they're not. The two programming languages that I use more are Elisp and Lua, and Lua only has lexical binding... so I know how lexical binding works, how to use it, and what are its advantages, but its exact semantics in Lua only became clear to me when I learned 1) how to inspect all the "local variables" of a running Lua function - in Lua this includes the arguments that the function received, and 2) how some local variables are "captured" to become upvales. This is explained in pages 8 and 9 here: https://web.tecgraf.puc-rio.br/~lhf/ftp/doc/jucs05.pdf#page=9 My main intent with eev since the beginning (in the mid-90s) has always been to create my own "executable notes" and share them, and to make other people create and share their executable notes too... there seemed to be some kind of taboo against that at that time: people shared textual explanations happily but hesitated an almost infinite number of times before sharing runnable snippets, and I was tired of spending hours every time undoing their translations from snippets to textual explanations to reconstruct the runnable snippets that they didn't want to share... Two days ago someone on IRC told me that the documentation of Common Lisp has great explanations of how lexical bindings works on CL, and that lots of it applied to lexical binding in Emacs too. I forgot to ask for links - when I get them I will add them to my tutorial, probably just preceding them by a "See:", because I am trying to keep my own textual explanations very short. This page http://www.gnu.org/software/emacs/manual/html_node/elisp/Closures.html (find-elnode "Closures") says: However, the fact that the internal structure of a closure is exposed to the rest of the Lisp world is considered an internal implementation detail. For this reason, we recommend against directly examining or altering the structure of closure objects. but for me, and for many people that I know, the easiest way to understand a specification that can be implemented in many ways is to study the specification AND one implementation of it. Snippets that show the "internal implementation details" of the current implementation of lexical binding in Emacs are hard to find, so I'm writing them myself - and asking for help. Eev has several kinds of hyperlinks to source code, like this one, ;; (find-efunction 'defvar "declared_special") that finds the definition of defvar - a DEFUN ("defvar", ...) - in the C source of Emacs and searches for string "declared_special" in it, and I am using them in my notes and tutorials to point the primary source of information about the implementation details - the source code! - instead of writing my own textual explanations. So, that's why I was so happy when I found the getter/setter example that is here: http://angg.twu.net/eev-intros/find-lexical-intro.html#3 (find-lexical-intro "3. `get/set'") https://0x0.st/-JRW.bin (find-wget-elisp "https://0x0.st/-JRW.bin") It has some code that was quite mysterious to me until a few days ago - the (defun get/set0 ...), that buils two closures that share the same lexical environment - and it shows how that code gets translated to lower-level elisp code that I could understand. Cheers, Eduardo Ochs http://angg.twu.net/#eev http://angg.twu.net/eev-intros/find-elisp-intro.html http://angg.twu.net/eev-intros/find-lexical-intro.html ^ permalink raw reply [flat|nested] 61+ messages in thread
* Re: Lexical vs. dynamic: small examples? 2021-08-14 16:00 ` Eduardo Ochs @ 2021-08-14 19:41 ` Emanuel Berg via Users list for the GNU Emacs text editor 2021-08-14 20:42 ` tomas 1 sibling, 0 replies; 61+ messages in thread From: Emanuel Berg via Users list for the GNU Emacs text editor @ 2021-08-14 19:41 UTC (permalink / raw) To: help-gnu-emacs Eduardo Ochs wrote: > The two programming languages that I use more are Elisp and > Lua, and Lua They (the Brazilians) did Lua (moon in Portugese) because Python wasn't around, and Lisp was too cryptic with its "unfriendly" syntax :) [1] > the easiest way to understand a specification that can be > implemented in many ways is to study the specification AND > one implementation of it. ikr? > details [...] of the current implementation of lexical > binding in Emacs are hard to find, so I'm writing them > myself Okay, but how many situations are they? You already have the example with `let', what other situations can you think of? One example per situation should be enough and do them as short as possible. Because there aren't that many, are there? [1] https://en.wikipedia.org/wiki/Lua_(programming_language) -- underground experts united https://dataswamp.org/~incal ^ permalink raw reply [flat|nested] 61+ messages in thread
* Re: Lexical vs. dynamic: small examples? 2021-08-14 16:00 ` Eduardo Ochs 2021-08-14 19:41 ` Emanuel Berg via Users list for the GNU Emacs text editor @ 2021-08-14 20:42 ` tomas 1 sibling, 0 replies; 61+ messages in thread From: tomas @ 2021-08-14 20:42 UTC (permalink / raw) To: Eduardo Ochs; +Cc: help-gnu-emacs [-- Attachment #1: Type: text/plain, Size: 715 bytes --] On Sat, Aug 14, 2021 at 01:00:34PM -0300, Eduardo Ochs wrote: > On Sat, 14 Aug 2021 at 04:35, <tomas@tuxteam.de> wrote: > > > > Hm. I have the feeling that it'll difficult to appreciate the > > differences between lexical and dynamic bindings whithin such > > short snippets. You don't have much room to build up a lexical > > environment worth its salt :-) > > > > The metaphor which, for me, did "click" was: lexical binding is > > a binding along "space", dynamic binding along "time". > > > Hi Tomas, > > I forgot to explain some things about the style of that tutorial... I > thought that they would be obvious, but they're not. Hm. I'll have to wrap my head around that. Cheers - t [-- Attachment #2: Digital signature --] [-- Type: application/pgp-signature, Size: 198 bytes --] ^ permalink raw reply [flat|nested] 61+ messages in thread
* Re: Lexical vs. dynamic: small examples? 2021-08-14 7:35 ` tomas 2021-08-14 16:00 ` Eduardo Ochs @ 2021-08-14 19:31 ` Emanuel Berg via Users list for the GNU Emacs text editor 2021-08-14 20:31 ` tomas 1 sibling, 1 reply; 61+ messages in thread From: Emanuel Berg via Users list for the GNU Emacs text editor @ 2021-08-14 19:31 UTC (permalink / raw) To: help-gnu-emacs tomas wrote: > The metaphor which, for me, did "click" was: lexical binding > is a binding along "space", dynamic binding along "time". Okay, but as for dynamic, isn't that the definition rather than a metaphor? "Lexical" refers to how the code is written - in particular where a variable is defined and how it is scoped in the source, when the source is compiled. Lexical binding (or scope) could just as well be called static scoping. Dynamic or lexical binding answers the question how a variable is looked up when it is referenced, i.e. called by its name. -- underground experts united https://dataswamp.org/~incal ^ permalink raw reply [flat|nested] 61+ messages in thread
* Re: Lexical vs. dynamic: small examples? 2021-08-14 19:31 ` Emanuel Berg via Users list for the GNU Emacs text editor @ 2021-08-14 20:31 ` tomas 2021-08-14 21:26 ` Emanuel Berg via Users list for the GNU Emacs text editor 0 siblings, 1 reply; 61+ messages in thread From: tomas @ 2021-08-14 20:31 UTC (permalink / raw) To: help-gnu-emacs [-- Attachment #1: Type: text/plain, Size: 607 bytes --] On Sat, Aug 14, 2021 at 09:31:20PM +0200, Emanuel Berg via Users list for the GNU Emacs text editor wrote: > tomas wrote: > > > The metaphor which, for me, did "click" was: lexical binding > > is a binding along "space", dynamic binding along "time". > > Okay, but as for dynamic, isn't that the definition rather > than a metaphor? If you take it too seriously, you end up with a strange time, which goes back and forth and branches. Calls stacks like to do funny things :-/ If you add nonlocal exits (exceptions, setjmp/longjmp, continuations), you are in hot water ;-) Cheers - t [-- Attachment #2: Digital signature --] [-- Type: application/pgp-signature, Size: 198 bytes --] ^ permalink raw reply [flat|nested] 61+ messages in thread
* Re: Lexical vs. dynamic: small examples? 2021-08-14 20:31 ` tomas @ 2021-08-14 21:26 ` Emanuel Berg via Users list for the GNU Emacs text editor 2021-08-14 21:29 ` Emanuel Berg via Users list for the GNU Emacs text editor 0 siblings, 1 reply; 61+ messages in thread From: Emanuel Berg via Users list for the GNU Emacs text editor @ 2021-08-14 21:26 UTC (permalink / raw) To: help-gnu-emacs tomas wrote: > If you add nonlocal exits (exceptions, setjmp/longjmp, > continuations), you are in hot water ;-) Let's see, an exception is an exception... setjmp/longjmp are C functions to save state and then restore/resume execution at a specific location after an error. A continuation - the functional equivalent of the GOTO statement <https://en.wikipedia.org/wiki/Continuation> - is used in continuation-passing style computing, CPS, where an explicit continuation function is sent to a function and that gets called with the value instead of returning it. So if f(a, f') = f'(f(a)) then f' is the continuation? "Nonlocal exits unbind all variable bindings made by the constructs being exited." <https://www.gnu.org/software/emacs/manual/html_node/elisp/Nonlocal-Exits.html> -- underground experts united https://dataswamp.org/~incal ^ permalink raw reply [flat|nested] 61+ messages in thread
* Re: Lexical vs. dynamic: small examples? 2021-08-14 21:26 ` Emanuel Berg via Users list for the GNU Emacs text editor @ 2021-08-14 21:29 ` Emanuel Berg via Users list for the GNU Emacs text editor 0 siblings, 0 replies; 61+ messages in thread From: Emanuel Berg via Users list for the GNU Emacs text editor @ 2021-08-14 21:29 UTC (permalink / raw) To: help-gnu-emacs > <https://www.gnu.org/software/emacs/manual/html_node/elisp/Nonlocal-Exits.html> That page doesn't have a title BTW. -- underground experts united https://dataswamp.org/~incal ^ permalink raw reply [flat|nested] 61+ messages in thread
* RE: [External] : Lexical vs. dynamic: small examples? 2021-08-14 3:34 Lexical vs. dynamic: small examples? Eduardo Ochs 2021-08-14 3:56 ` Emanuel Berg via Users list for the GNU Emacs text editor 2021-08-14 7:35 ` tomas @ 2021-08-14 13:35 ` Drew Adams 2021-08-14 16:15 ` Eduardo Ochs 2021-08-14 19:00 ` Gregory Heytings 3 siblings, 1 reply; 61+ messages in thread From: Drew Adams @ 2021-08-14 13:35 UTC (permalink / raw) To: Eduardo Ochs, help-gnu-emacs The advantages of lexical binding are easy to find, and all of them are true advantages, for both programming and program analysis. The advantages of dynamic binding are not so easy to find, but they're quite important to an environment such as that of Emacs. RMS gave good arguments _for Emacs_ (and similar, user-programmer environments) to support dynamic binding, here: https://www.gnu.org/software/emacs/emacs-paper.html#SEC17 Every Emacs user should, I think, be aware of these advantages - as well as their attendant limitations/drawbacks. Support of dynamic binding does _not_ require non-support of lexical binding. Common Lisp has purposefully had both from the outset (lexical is the default). Emacs Lisp took a long time to add lexical binding (and it is still not the default), but it too has both now. And yes, combining both in the same language provides perils as well as advantages. ___ This 1986 MIT video might be of interest here. It goes over the introduction of side effects into a purely functional Scheme (Lisp-1 dialect). https://www.youtube.com/watch?v=jl8EHP1WrWY It talks about the motivation for doing that (and for dynamic binding, though that might not be mentioned explicitly in this session). This is the 10th session of the Structure and Interpretation of Computer Programs course (presented by the authors), so it builds on top of a pure lambda-calculus model, with its many advantages of simple substitution etc. You have to imagine that context for this session, i.e., that until then only a purely functional, lexically scoped language was used/presented. ^ permalink raw reply [flat|nested] 61+ messages in thread
* Re: [External] : Lexical vs. dynamic: small examples? 2021-08-14 13:35 ` [External] : " Drew Adams @ 2021-08-14 16:15 ` Eduardo Ochs 0 siblings, 0 replies; 61+ messages in thread From: Eduardo Ochs @ 2021-08-14 16:15 UTC (permalink / raw) To: Drew Adams; +Cc: help-gnu-emacs On Sat, 14 Aug 2021 at 10:36, Drew Adams <drew.adams@oracle.com> wrote: > > The advantages of lexical binding are easy to find, and all of them > are true advantages, for both programming and program analysis. The > advantages of dynamic binding are not so easy to find, but they're > quite important to an environment such as that of Emacs. > > RMS gave good arguments _for Emacs_ (and similar, user-programmer > environments) to support dynamic binding, here: Hi Drew! Fantastic! Thanks! =) By the way, here's a package that installs SICP converted to info format, for those (not Drew!) who don't know that this exists... http://melpa.org/#/sicp https://github.com/webframp/sicp-info Cheers =), Eduardo Ochs http://angg.twu.net/#eev ^ permalink raw reply [flat|nested] 61+ messages in thread
* Re: Lexical vs. dynamic: small examples? 2021-08-14 3:34 Lexical vs. dynamic: small examples? Eduardo Ochs ` (2 preceding siblings ...) 2021-08-14 13:35 ` [External] : " Drew Adams @ 2021-08-14 19:00 ` Gregory Heytings 2021-08-14 20:16 ` Emanuel Berg via Users list for the GNU Emacs text editor ` (2 more replies) 3 siblings, 3 replies; 61+ messages in thread From: Gregory Heytings @ 2021-08-14 19:00 UTC (permalink / raw) To: Eduardo Ochs; +Cc: help-gnu-emacs > > I am trying to write a section on lexical vs. dynamic binding for a > tutorial on Emacs Lisp, and I am looking for very short demos that show > how things work differently in dynamic and in lexical binding... > Suppose you write a function to remove unnecessary whitespaces at the end of lines: (defun delete-whitespace-at-eol () (interactive) (save-excursion (replace-regexp " *$" "" nil (point-min) (point-max)))) Now if you M-x trim-whitespaces-at-eol in a read-only buffer, you'll get a "Buffer is read-only" error. Suppose you want to make that function work for read-only buffers. If Emacs Lisp only had lexical binding, you would have to alter the global "buffer-read-only" variable, that is, to do something like: (defvar saved-buffer-read-only) (defun delete-whitespace-at-eol () (interactive) (setq saved-buffer-read-only buffer-read-only) (setq buffer-read-only nil) (save-excursion (replace-regexp " *$" "" nil (point-min) (point-max))) (setq buffer-read-only saved-buffer-read-only)) This becomes much simpler with dynamic binding: (defun delete-whitespace-at-eol () (interactive) (let ((buffer-read-only nil)) (save-excursion (replace-regexp " *$" "" nil (point-min) (point-max))))) The "let ((buffer-read-only nil))" creates a new "buffer-read-only" variable and sets it to nil. When "replace-regexp", and the functions called by "replace-regexp", consult the value of the "buffer-read-only" variable, they will see the "buffer-read-only" variable created in "delete-whitespace-at-eol", and its value "nil", instead of the global "buffer-read-only" variable. It is easier to think that "let ((buffer-read-only nil))" creates a new "buffer-read-only" variable, but technically this is not correct. What happens instead is that the old value of "buffer-read-only" is saved, the value of "buffer-read-only" is updated, and upon returning from the "let", the saved value is restored. ^ permalink raw reply [flat|nested] 61+ messages in thread
* Re: Lexical vs. dynamic: small examples? 2021-08-14 19:00 ` Gregory Heytings @ 2021-08-14 20:16 ` Emanuel Berg via Users list for the GNU Emacs text editor 2021-08-14 20:23 ` Gregory Heytings 2021-08-14 20:41 ` tomas 2021-08-15 0:29 ` [External] : " Drew Adams 2 siblings, 1 reply; 61+ messages in thread From: Emanuel Berg via Users list for the GNU Emacs text editor @ 2021-08-14 20:16 UTC (permalink / raw) To: help-gnu-emacs Gregory Heytings wrote: > (defun delete-whitespace-at-eol () > (interactive) > (save-excursion (replace-regexp " *$" "" nil (point-min) (point-max)))) OK, that's an example, but let's mention there is `delete-trailing-whitespace'. (defun untab-all () (unless (member major-mode '(makefile-gmake-mode makefile-mode) ) ; exceptions (untabify (point-min) (point-max))) nil) ; "did not write buffer to disk" (defun before-save-hook-f () (untab-all) (delete-trailing-whitespace) ) (add-hook 'before-save-hook #'before-save-hook-f) > Now if you M-x trim-whitespaces-at-eol in a read-only > buffer, you'll get a "Buffer is read-only" error. > Suppose you want to make that function work for read-only > buffers. If Emacs Lisp only had lexical binding, you would > have to alter the global "buffer-read-only" variable, that > is, to do something like: > > (defvar saved-buffer-read-only) > (defun delete-whitespace-at-eol () > (interactive) > (setq saved-buffer-read-only buffer-read-only) > (setq buffer-read-only nil) > (save-excursion (replace-regexp " *$" "" nil (point-min) (point-max))) > (setq buffer-read-only saved-buffer-read-only)) OK, but you don't need to store the old value in a global variable... > This becomes much simpler with dynamic binding: > > (defun delete-whitespace-at-eol () > (interactive) > (let ((buffer-read-only nil)) > (save-excursion (replace-regexp " *$" "" nil (point-min) (point-max))))) Can't we have two `let', the old let that is lexical/static and another let that is dynamic, only we call it something else, and then everyone can use whatever they like and it is always clear from the code which it is and we can even have both from the same file, with no need to say it's this way or the other? It doesn't work like that? Why not? -- underground experts united https://dataswamp.org/~incal ^ permalink raw reply [flat|nested] 61+ messages in thread
* Re: Lexical vs. dynamic: small examples? 2021-08-14 20:16 ` Emanuel Berg via Users list for the GNU Emacs text editor @ 2021-08-14 20:23 ` Gregory Heytings 2021-08-14 21:05 ` Emanuel Berg via Users list for the GNU Emacs text editor 0 siblings, 1 reply; 61+ messages in thread From: Gregory Heytings @ 2021-08-14 20:23 UTC (permalink / raw) To: Emanuel Berg; +Cc: help-gnu-emacs >> (defvar saved-buffer-read-only) >> (defun delete-whitespace-at-eol () >> (interactive) >> (setq saved-buffer-read-only buffer-read-only) >> (setq buffer-read-only nil) >> (save-excursion (replace-regexp " *$" "" nil (point-min) (point-max))) >> (setq buffer-read-only saved-buffer-read-only)) > > OK, but you don't need to store the old value in a global variable... > Of course you do, you need to restore the original value, which could be either t or nil. But indeed TIMTOWTDI: for this specific example, another way to do it would be to introduce a conditional. In general however variables can hold more than two values, so for didactic purposes the above is much clearer. ^ permalink raw reply [flat|nested] 61+ messages in thread
* Re: Lexical vs. dynamic: small examples? 2021-08-14 20:23 ` Gregory Heytings @ 2021-08-14 21:05 ` Emanuel Berg via Users list for the GNU Emacs text editor 2021-08-14 21:13 ` tomas 0 siblings, 1 reply; 61+ messages in thread From: Emanuel Berg via Users list for the GNU Emacs text editor @ 2021-08-14 21:05 UTC (permalink / raw) To: help-gnu-emacs Gregory Heytings wrote: >>> (defvar saved-buffer-read-only) >>> (defun delete-whitespace-at-eol () >>> (interactive) >>> (setq saved-buffer-read-only buffer-read-only) >>> (setq buffer-read-only nil) >>> (save-excursion (replace-regexp " *$" "" nil (point-min) (point-max))) >>> (setq buffer-read-only saved-buffer-read-only)) >> >> OK, but you don't need to store the old value in a global variable... >> > Of course you do, you need to restore the original value [...] But there is still no need to use a global variable... -- underground experts united https://dataswamp.org/~incal ^ permalink raw reply [flat|nested] 61+ messages in thread
* Re: Lexical vs. dynamic: small examples? 2021-08-14 21:05 ` Emanuel Berg via Users list for the GNU Emacs text editor @ 2021-08-14 21:13 ` tomas 2021-08-14 21:28 ` Emanuel Berg via Users list for the GNU Emacs text editor 0 siblings, 1 reply; 61+ messages in thread From: tomas @ 2021-08-14 21:13 UTC (permalink / raw) To: help-gnu-emacs [-- Attachment #1: Type: text/plain, Size: 827 bytes --] On Sat, Aug 14, 2021 at 11:05:53PM +0200, Emanuel Berg via Users list for the GNU Emacs text editor wrote: > Gregory Heytings wrote: > > >>> (defvar saved-buffer-read-only) > >>> (defun delete-whitespace-at-eol () > >>> (interactive) > >>> (setq saved-buffer-read-only buffer-read-only) > >>> (setq buffer-read-only nil) > >>> (save-excursion (replace-regexp " *$" "" nil (point-min) (point-max))) > >>> (setq buffer-read-only saved-buffer-read-only)) > >> > >> OK, but you don't need to store the old value in a global variable... > >> > > Of course you do, you need to restore the original value [...] > > But there is still no need to use a global variable... That's not the point. You perhaps don't want to trample on one. The let-binding helps you with that. In both cases. Cheers - t [-- Attachment #2: Digital signature --] [-- Type: application/pgp-signature, Size: 198 bytes --] ^ permalink raw reply [flat|nested] 61+ messages in thread
* Re: Lexical vs. dynamic: small examples? 2021-08-14 21:13 ` tomas @ 2021-08-14 21:28 ` Emanuel Berg via Users list for the GNU Emacs text editor 0 siblings, 0 replies; 61+ messages in thread From: Emanuel Berg via Users list for the GNU Emacs text editor @ 2021-08-14 21:28 UTC (permalink / raw) To: help-gnu-emacs tomas wrote: >> But there is still no need to use a global variable... > > That's not the point. It is my point. -- underground experts united https://dataswamp.org/~incal ^ permalink raw reply [flat|nested] 61+ messages in thread
* Re: Lexical vs. dynamic: small examples? 2021-08-14 19:00 ` Gregory Heytings 2021-08-14 20:16 ` Emanuel Berg via Users list for the GNU Emacs text editor @ 2021-08-14 20:41 ` tomas 2021-08-15 0:29 ` [External] : " Drew Adams 2 siblings, 0 replies; 61+ messages in thread From: tomas @ 2021-08-14 20:41 UTC (permalink / raw) To: help-gnu-emacs [-- Attachment #1: Type: text/plain, Size: 1234 bytes --] On Sat, Aug 14, 2021 at 07:00:29PM +0000, Gregory Heytings wrote: > > > > >I am trying to write a section on lexical vs. dynamic binding for > >a tutorial on Emacs Lisp, and I am looking for very short demos > >that show how things work differently in dynamic and in lexical > >binding... > > > > Suppose you write a function to remove unnecessary whitespaces at > the end of lines: > > (defun delete-whitespace-at-eol () > (interactive) > (save-excursion (replace-regexp " *$" "" nil (point-min) (point-max)))) This is a good example. There are other ones. Basically, whenever you want some "dynamic state" to be in effect for the whole "call tree" below you. Typically those are well-known things with an agreed-upon purpose. My favourite example is some kind of "debug setting" (a function, a value, whatever). There's a reason why the convention in CL is to have those variable named with asterisks around, like *this*. (I had many arguments whithin Perl. With the arrival of lexical variables, there was a fraction which tried to convince people to /never/ use dynamic variables, and I tried to explain that, yes, use sparingly, but sometimes they can make code clearer. Cheers - t [-- Attachment #2: Digital signature --] [-- Type: application/pgp-signature, Size: 198 bytes --] ^ permalink raw reply [flat|nested] 61+ messages in thread
* RE: [External] : Re: Lexical vs. dynamic: small examples? 2021-08-14 19:00 ` Gregory Heytings 2021-08-14 20:16 ` Emanuel Berg via Users list for the GNU Emacs text editor 2021-08-14 20:41 ` tomas @ 2021-08-15 0:29 ` Drew Adams 2021-08-15 0:52 ` Emanuel Berg via Users list for the GNU Emacs text editor ` (2 more replies) 2 siblings, 3 replies; 61+ messages in thread From: Drew Adams @ 2021-08-15 0:29 UTC (permalink / raw) To: Gregory Heytings, Eduardo Ochs; +Cc: help-gnu-emacs > Now if you M-x trim-whitespaces-at-eol in a read-only buffer, you'll get a > "Buffer is read-only" error. Suppose you want to make that function work > for read-only buffers. If Emacs Lisp only had lexical binding, you would > have to alter the global "buffer-read-only" variable, that is, to do > something like: > > (defvar saved-buffer-read-only) > (defun delete-whitespace-at-eol () > (interactive) > (setq saved-buffer-read-only buffer-read-only) > (setq buffer-read-only nil) > ... > (setq buffer-read-only saved-buffer-read-only)) `buffer-read-only' is a dynamically scoped, set, and bound variable. (It's also buffer-local.) What you did there was change the value for the dynamic extent of the function call. It's not defined by the scope of the function definition. All variables defined using defvar and defcustom are dynamically scoped. Same with top-level `setq', i.e., variables that are not explicitly defined in any scope, other that the top level. Same with frame parameters, faces, etc. - all essentially dynamically-scoped variables. Their values have indefinite scope and dynamic extent. "Dynamic scope" is a misnomer, BTW; it means only that - no particular scope and dynamic extent. See the very good explanation in CLTL: https://www.cs.cmu.edu/Groups/AI/html/cltl/clm/node43.html#SECTION00700000000000000000 Common Lisp calls such variables "special" variables. Wrt usefulness: if you've ever used user options or defvar variables, or frame parameters, or faces,... then you recognize their utility. Now try to imagine Emacs, as a flexible, dynamic user-interaction environment/lab _without_ dynamic binding... > This becomes much simpler with dynamic binding: > (defun delete-whitespace-at-eol () > (interactive) > (let ((buffer-read-only nil)) > ...)) That's just a simpler way to do the same thing. In both cases, it is the globally visible (buffer-local) variable whose value is changed for the _duration_ of the function call (unless something else changes it in the meantime). `let' binds the global variable (which, again, happens to be buffer-local). That's how `let' behaves with a "special" var. Otherwise, i.e., for vars that are not "special", `let' provides a lexical binding - the scope ends where the `let' ends, lexically. Dynamic scope/binding means variable name capture is always an inherent, potential problem. From the CLTL chapter on Scope and Extent cited above, remember this: "A reference by name to an entity with dynamic extent will always refer to the entity of that name that has been most recently established that has not yet been disestablished." ^ permalink raw reply [flat|nested] 61+ messages in thread
* Re: [External] : Re: Lexical vs. dynamic: small examples? 2021-08-15 0:29 ` [External] : " Drew Adams @ 2021-08-15 0:52 ` Emanuel Berg via Users list for the GNU Emacs text editor 2021-08-15 1:04 ` Emanuel Berg via Users list for the GNU Emacs text editor 2021-08-15 1:18 ` Emanuel Berg via Users list for the GNU Emacs text editor 2 siblings, 0 replies; 61+ messages in thread From: Emanuel Berg via Users list for the GNU Emacs text editor @ 2021-08-15 0:52 UTC (permalink / raw) To: help-gnu-emacs Drew Adams wrote: > `let' binds the global variable (which, again, > happens to be buffer-local). That's how `let' > behaves with a "special" var. Otherwise, i.e., > for vars that are not "special", `let' provides > a lexical binding - the scope ends where the > `let' ends, lexically. Can't we have a "let-special" that makes its own variables special within its scope? Then one could use let-special for dynamic scope (which now would in fact be scoped!) and `let' would always be lexical and one would never have to use ;;; -*- lexical-binding: t -*- ? -- underground experts united https://dataswamp.org/~incal ^ permalink raw reply [flat|nested] 61+ messages in thread
* Re: [External] : Re: Lexical vs. dynamic: small examples? 2021-08-15 0:29 ` [External] : " Drew Adams 2021-08-15 0:52 ` Emanuel Berg via Users list for the GNU Emacs text editor @ 2021-08-15 1:04 ` Emanuel Berg via Users list for the GNU Emacs text editor 2021-08-15 1:18 ` Emanuel Berg via Users list for the GNU Emacs text editor 2 siblings, 0 replies; 61+ messages in thread From: Emanuel Berg via Users list for the GNU Emacs text editor @ 2021-08-15 1:04 UTC (permalink / raw) To: help-gnu-emacs Drew Adams wrote: > Wrt usefulness: if you've ever used user options or defvar > variables, or frame parameters, or faces,... then you > recognize their utility. Now try to imagine Emacs, as > a flexible, dynamic user-interaction environment/lab > _without_ dynamic binding... Options as global variables - useful. -- underground experts united https://dataswamp.org/~incal ^ permalink raw reply [flat|nested] 61+ messages in thread
* Re: [External] : Re: Lexical vs. dynamic: small examples? 2021-08-15 0:29 ` [External] : " Drew Adams 2021-08-15 0:52 ` Emanuel Berg via Users list for the GNU Emacs text editor 2021-08-15 1:04 ` Emanuel Berg via Users list for the GNU Emacs text editor @ 2021-08-15 1:18 ` Emanuel Berg via Users list for the GNU Emacs text editor 2021-08-15 4:44 ` Emanuel Berg via Users list for the GNU Emacs text editor 2021-08-15 15:42 ` FW: " Drew Adams 2 siblings, 2 replies; 61+ messages in thread From: Emanuel Berg via Users list for the GNU Emacs text editor @ 2021-08-15 1:18 UTC (permalink / raw) To: help-gnu-emacs Drew Adams wrote: > "Dynamic scope" is a misnomer, BTW; it means only that - no > particular scope and dynamic extent [...] `let' provides > a lexical binding - the scope ends where the `let' > ends, lexically. But with `let' doesn't the scope end where the let ends even for dynamic binding? And one can think of global variables as having the whole program as their scope. If this is only about let "let's" have two lets, one "let-stay" and one "let-follow". If it isn't only about let, what is it about more? -- underground experts united https://dataswamp.org/~incal ^ permalink raw reply [flat|nested] 61+ messages in thread
* Re: [External] : Re: Lexical vs. dynamic: small examples? 2021-08-15 1:18 ` Emanuel Berg via Users list for the GNU Emacs text editor @ 2021-08-15 4:44 ` Emanuel Berg via Users list for the GNU Emacs text editor 2021-08-15 5:02 ` Emanuel Berg via Users list for the GNU Emacs text editor 2021-08-15 15:49 ` Drew Adams 2021-08-15 15:42 ` FW: " Drew Adams 1 sibling, 2 replies; 61+ messages in thread From: Emanuel Berg via Users list for the GNU Emacs text editor @ 2021-08-15 4:44 UTC (permalink / raw) To: help-gnu-emacs Drew Adams wrote, somewhere else: > If this is only about let "let's" have two lets, one > "let-stay" and one "let-follow". `let' is not the only construct that can define a scope. For example, a function definition (a `defun' or a lambda) defines the scope of its formal parameters - they're lexically scoped. Yes, and what happens is, the formal parameters are check first, only after that are global variables checked! But that is completely normal and 100% expected. If that is "lexical scope", how would one do it in another way? (OK, it _is_ lexical binding for the arguments and dynamic for the globals but has this any practical implications?) No, the only thing I've seen so far - maybe the only thing it is? - is `let', and that acts in two ways, the lexical way if one puts ;;; -*- lexical-binding: t -*- first thing in the source file, and if one doesn't, it acts in the dynamic way. So I wonder again, why not just have two let, one "let-stay" (the variables stay so has to be used and/or passed explicitely), and "let-follow" (the variables follow everywhere the code goes within the let form). Then one could drop this whole discussion because everything would work as expected and everyone could use whatever they wanted and instead of explaining some scope vs another in terms of theory one would have one docstring for "let-stay" and one for "let-follow" and these would also not confuse anything by engaging in a theoretical discussion but just describe what the function does and what its purpose is. ? -- underground experts united https://dataswamp.org/~incal ^ permalink raw reply [flat|nested] 61+ messages in thread
* Re: [External] : Re: Lexical vs. dynamic: small examples? 2021-08-15 4:44 ` Emanuel Berg via Users list for the GNU Emacs text editor @ 2021-08-15 5:02 ` Emanuel Berg via Users list for the GNU Emacs text editor 2021-08-15 15:49 ` Drew Adams 1 sibling, 0 replies; 61+ messages in thread From: Emanuel Berg via Users list for the GNU Emacs text editor @ 2021-08-15 5:02 UTC (permalink / raw) To: help-gnu-emacs > So I wonder again, why not just have two let, one "let-stay" > (the variables stay so has to be used and/or passed > explicitely), and "let-follow" (the variables follow > everywhere the code goes within the let form). Even better, let `let' be the lexical let. Then the old dynamic let will be called "with-variables-as". So this (let ((x 1) (y 2) (z -1) ) (draw-grid x y z) ) would be the equivalent of (with-variables-as ((x 1) (y 2) (z -1) ) (draw-grid) ) -- underground experts united https://dataswamp.org/~incal ^ permalink raw reply [flat|nested] 61+ messages in thread
* RE: [External] : Re: Lexical vs. dynamic: small examples? 2021-08-15 4:44 ` Emanuel Berg via Users list for the GNU Emacs text editor 2021-08-15 5:02 ` Emanuel Berg via Users list for the GNU Emacs text editor @ 2021-08-15 15:49 ` Drew Adams 2021-08-15 18:49 ` Emanuel Berg via Users list for the GNU Emacs text editor 1 sibling, 1 reply; 61+ messages in thread From: Drew Adams @ 2021-08-15 15:49 UTC (permalink / raw) To: Emanuel Berg; +Cc: 'Help-Gnu-Emacs (help-gnu-emacs@gnu.org)' [-- Attachment #1: Type: text/plain, Size: 1231 bytes --] > (OK, it _is_ lexical binding for the arguments and dynamic > for the globals but has this any practical implications?) As I said, `let' (in both Elisp and Common Lisp) binds "special" vars dynamically and non-special vars lexically. There's nothing else to it. > No, the only thing I've seen so far - maybe the only thing it > is? - is `let', and that acts in two ways, the lexical way if > one puts > > ;;; -*- lexical-binding: t -*- > > first thing in the source file, and if one doesn't, it acts in > the dynamic way. See above. In Elisp we have var `lexical-binding', and lexical binding is not not turned on by default. With Common Lisp there's no such variable, and the effect is as if `lexical-binding' were always non-nil. (There are other differences, wrt how/where you can declare vars to be "special".) > So I wonder again, why not just have two let, one "let-stay" > (the variables stay so has to be used and/or passed > explicitely), and "let-follow" (the variables follow > everywhere the code goes within the let form). Sorry, I don't follow you. It's not clear to me what you're proposing or (more importantly) what problem you think you have with the designed behavior. [-- Attachment #2: winmail.dat --] [-- Type: application/ms-tnef, Size: 13878 bytes --] ^ permalink raw reply [flat|nested] 61+ messages in thread
* Re: [External] : Re: Lexical vs. dynamic: small examples? 2021-08-15 15:49 ` Drew Adams @ 2021-08-15 18:49 ` Emanuel Berg via Users list for the GNU Emacs text editor 2021-08-15 21:55 ` Stefan Monnier via Users list for the GNU Emacs text editor ` (2 more replies) 0 siblings, 3 replies; 61+ messages in thread From: Emanuel Berg via Users list for the GNU Emacs text editor @ 2021-08-15 18:49 UTC (permalink / raw) To: help-gnu-emacs Drew Adams wrote: >> So I wonder again, why not just have two let, one >> "let-stay" (the variables stay so has to be used and/or >> passed explicitely), and "let-follow" (the variables follow >> everywhere the code goes within the let form). > > Sorry, I don't follow you. It's not clear to me what you're > proposing or (more importantly) what problem you think you > have with the designed behavior. `let' does two different things, that is confusing, and it is usually explained with theory - and the terms are confusing as well - and to set what usage one gets one has to mess with a variable - what kind of style is that? Just imagine, instead of `+', `-', etc we would have just one function, "do-math" which would look for for the value of "operator" to determine what to do... So the proposal/question is, instead one could have `let' _always_ be lexical, and one "with-variables-as" which would be what is now called "dynamic binding" with let. "Dynamic" is something that changes over time, but TBH I don't really see the static/dynamic aspect or difference here? But OK, for the sake of the discussion, let's call them "letl" (the lexical one) and "letd" (the dynamic one). If one did it like that, for practical purposes, the whole lexical/static vs special/dynamic binding or scope (and extent) could be dropped, one would just write one docstring for "letl" and one for "letd"! (Let's not bring in the issue of nonlocal exits like exceptions and continuations because if they are indeed "exceptions" they can be whatever.) OK, that's let, you also mention global variables, they are always special/dynamic. However I don't see how that could or should be done in any other way, how can they be lexical? If they can't, that issue (the issue of global variables) can be cancelled out from the discussion as well. You also mention functions (`defun's) which are lexical in terms of the their formal parameters (= arguments, only theoretically, not applied). Because the whole idea with functions is to modularize and encapsulate I find the concept of function dynamic scope a bit bizarre, so in a way this issue (defuns) could be cancelled out as well. But sure, if someone want them to be dynamic, then why don't we do the same as I proposed for `let' (which was `let' = "letl", lexical; and "letd", dynamic), i.e. we would have `defun' = "defunl", lexical; and "defund", dynamic ? Then no one would have to mess with `lexical-binding', in any way (especially not that commented way that reminds me of a C preprocessor or something), one would just use whatever one wanted and to explain it to newcomers one would just refer to the docstrings, no need for CS theory or anything (not saying it should be forbidden or anything) but for practical purposes it wouldn't be needed. Everyone would see in the code - ah, here it is used like that, there it is used the other way. -- underground experts united https://dataswamp.org/~incal ^ permalink raw reply [flat|nested] 61+ messages in thread
* Re: [External] : Re: Lexical vs. dynamic: small examples? 2021-08-15 18:49 ` Emanuel Berg via Users list for the GNU Emacs text editor @ 2021-08-15 21:55 ` Stefan Monnier via Users list for the GNU Emacs text editor 2021-08-15 22:04 ` Emanuel Berg via Users list for the GNU Emacs text editor 2021-08-15 21:57 ` Drew Adams 2021-08-15 22:02 ` Lars Ingebrigtsen 2 siblings, 1 reply; 61+ messages in thread From: Stefan Monnier via Users list for the GNU Emacs text editor @ 2021-08-15 21:55 UTC (permalink / raw) To: help-gnu-emacs > "Dynamic" is something that changes over time, but TBH I don't > really see the static/dynamic aspect or difference here? This use of the term is the same as used in code analysis. "static" refers to the fact that you can find the definition corresponding to a particular use by just looking at the code without having "run" it. In contrast "dynamic" refers to the fact that in order to find which definition corresponds to a particular use can only be done you need to run the code (or simulate a run, typically in your head). It can also be considered from the following point of view: with lexical/static scoping, a given variable reference will always refer to the same definition point, i.e. the "use-to-def" doesn't change and is hence "static", whereas with dynamic scoping, a given variable reference can refer to various definitions at different moments of a program execution, i.e. the "use-to-def" can change and is hence dynamic. Stefan ^ permalink raw reply [flat|nested] 61+ messages in thread
* Re: [External] : Re: Lexical vs. dynamic: small examples? 2021-08-15 21:55 ` Stefan Monnier via Users list for the GNU Emacs text editor @ 2021-08-15 22:04 ` Emanuel Berg via Users list for the GNU Emacs text editor 0 siblings, 0 replies; 61+ messages in thread From: Emanuel Berg via Users list for the GNU Emacs text editor @ 2021-08-15 22:04 UTC (permalink / raw) To: help-gnu-emacs Stefan Monnier via Users list for the GNU Emacs text editor wrote: >> "Dynamic" is something that changes over time, but TBH >> I don't really see the static/dynamic aspect or >> difference here? > > This use of the term is the same as used in code analysis. > "static" refers to the fact that you can find the definition > corresponding to a particular use by just looking at the > code without having "run" it. > > In contrast "dynamic" refers to the fact that in order to > find which definition corresponds to a particular use can > only be done you need to run the code (or simulate a run, > typically in your head). > > It can also be considered from the following point of view: > with lexical/static scoping, a given variable reference will > always refer to the same definition point, i.e. > the "use-to-def" doesn't change and is hence "static", > whereas with dynamic scoping, a given variable reference can > refer to various definitions at different moments of > a program execution, i.e. the "use-to-def" can change and is > hence dynamic. Great, thanks! -- underground experts united https://dataswamp.org/~incal ^ permalink raw reply [flat|nested] 61+ messages in thread
* RE: [External] : Re: Lexical vs. dynamic: small examples? 2021-08-15 18:49 ` Emanuel Berg via Users list for the GNU Emacs text editor 2021-08-15 21:55 ` Stefan Monnier via Users list for the GNU Emacs text editor @ 2021-08-15 21:57 ` Drew Adams 2021-08-15 22:20 ` Emanuel Berg via Users list for the GNU Emacs text editor ` (2 more replies) 2021-08-15 22:02 ` Lars Ingebrigtsen 2 siblings, 3 replies; 61+ messages in thread From: Drew Adams @ 2021-08-15 21:57 UTC (permalink / raw) To: Emanuel Berg; +Cc: 'Help-Gnu-Emacs (help-gnu-emacs@gnu.org)' [-- Attachment #1: Type: text/plain, Size: 5973 bytes --] > So the proposal/question is, instead one could have `let' > _always_ be lexical, and one "with-variables-as" which would > be what is now called "dynamic binding" with let. You might want to send your proposal/question along via `M-x report-emacs-bug'. That's the best way to request enhancements, new features, and bug fixes. You might also want to consider that Common Lisp, designed by pretty much all of the wizards of Lisp at the time, does what Emacs Lisp does. With the exception that Emacs is not yet there all the way: we have variable `lexical-binding', which, yes, is a kludge indicating that we're straddling two chairs. IMHO, there is no confusion in the Common Lisp world/community about `let' (or other constructs) wrt lexical vs dynamic binding of a variable. I think there's confusion in the Emacs world because (1) Emacs long had only dynamic binding, (2) dynamic binding is what Emacs users (but maybe less so Elisp programmers) expect and make good use of when it comes their own binding/setting of variables (e.g. options), and (3) as noted above, Emacs is "entre deux chaises". > OK, that's let, you also mention global variables, they are > always special/dynamic. However I don't see how that could or > should be done in any other way, how can they be lexical? Many/most languages have pretty much only lexical binding. But yes, an exception is made for top-level definitions, in the sense that you can dynamically issue another define/defun/defvar for the same thing. There's _no_ scope for such definitions (though each defines a scope _within_ it, for other bindings). Each name defined with those constructs has indefinite scope and dynamic extent (duration). > If they can't, that issue (the issue of global variables) > can be cancelled out from the discussion as well. There's no "issue". I mentioned defvar, defcustom, defconst, defface, frame parameters, etc. as examples of dynamically bound things that Emacs users are used to. The point was that dynamic binding is not exotic or foreign for Emacs users. But like Monsieur Jourdain, they might well not be aware that they've been speaking such prose all their Emacs lives. The question was raised as to the usefulness of dynamic binding for Emacs users. I pointed to RMS's (excellent) reasons for supporting it, and to the (dynamic) behavior of those constructs, as what you (I, anyway) really want in an interactive environment such as Emacs. You can see that, when it comes to interaction with such an environment, pretty much all languages have a dynamic top level. You can _imagine_ no defuns etc. but only a big let, but you'll soon see that interacting with that could be cumbersome. Beyond such top-level dynamic binding of names, the real advantages that RMS cites are what are important, and they are more controversial. Disparagement of "monkey patching" is common. And beyond the question of dynamic/lexical binding, there are plenty of other "dirty" things to disparage in Lisp. You can start with side effects. And `quote' (which on its own is enough to destroy referential transparency). And you can continue with applicative-order, instead of normal-order, evaluation. That can lead to incorrect results and to unnecessary infinite computation. There are Lisps and other, more declarative, more purely functional or logic languages, that do away with this or that dirtiness. And they're wonderful, and safe, and more amenable to proof, and... But maybe not so wonderful for an editing environment. (You can even program in "pure", "academic" Lisp - essentially lambda calculus with some built-in data types. That's used mainly for papers and proofs.) > You also mention functions (`defun's) which are lexical in > terms of the their formal parameters (= arguments, only > theoretically, not applied). No idea what you mean by only theoretically. A function definition. whether by defun or as a lambda, is a binding construct, just like let is, or an integral or sigma expression is, or a logic expression with quantification is. You can define `forall' using lambda, just as you can define let using lambda. They're all abstractions - their purpose is to abstract. (https://www.youtube.com/watch?v=-J_xL4IGhJA, minute 29:00) As such, they all introduce variables and variable binding. (There's no _need_ for variables actually. Combinatory logic is equivalent to lambda calculus, and it involves no variables. But for mere mortals, variables give us some peace of mind and a map of the territory.) Actual arguments to functions are bound lexically in Lisp (modulo... depending on the approach). There's a difference between how a function's parameters are handled (which is lexically) and how the function name itself is handled (dynamically, for a defun). > Because the whole idea with functions is to modularize > and encapsulate I find the concept of function dynamic > scope a bit bizarre Do you want to be able to redefine a function easily? (defun foo (a) ...) ;; later... (defun foo (a b c) ...) > why don't we do the same as I proposed for `let' > (which was `let' = "letl", lexical; > and "letd", dynamic), i.e. we would have > > `defun' = "defunl", lexical; and > "defund", dynamic See CLTL, flet and labels: https://www.cs.cmu.edu/Groups/AI/html/cltl/clm/node83.html defun is convenient. Even non-Emacsing lispers want the convenience of a supple interactive environment. (You have a similar situation with setq as with let, BTW. It can assign to a lexical variable or a dynamic one.) > Then no one would have to mess with `lexical-binding', Having to mess with the variable `lexical-binding' is orthogonal. As mentioned, that's only an Emacs thing, and it's there only because we're between two chairs at the moment (it's been a long moment). [-- Attachment #2: winmail.dat --] [-- Type: application/ms-tnef, Size: 17094 bytes --] ^ permalink raw reply [flat|nested] 61+ messages in thread
* Re: [External] : Re: Lexical vs. dynamic: small examples? 2021-08-15 21:57 ` Drew Adams @ 2021-08-15 22:20 ` Emanuel Berg via Users list for the GNU Emacs text editor 2021-08-15 22:54 ` Drew Adams 2021-08-15 23:16 ` Drew Adams 2021-08-15 23:42 ` Arthur Miller 2 siblings, 1 reply; 61+ messages in thread From: Emanuel Berg via Users list for the GNU Emacs text editor @ 2021-08-15 22:20 UTC (permalink / raw) To: help-gnu-emacs Drew Adams wrote: >> Because the whole idea with functions is to modularize and >> encapsulate I find the concept of function dynamic scope >> a bit bizarre > > Do you want to be able to redefine a function easily? > > (defun foo (a) ...) > ;; later... > (defun foo (a b c) ...) No, they are global, of course! I meant dynamic with respect to the functional parameters. I think that would be bizarre but I'm a maximalist in terms of features so why not. However then one would call it something else, for example `defund' (d for "dynamic" and it refers to how the function would handle the functional parameters, not back on the function itself). >> why don't we do the same as I proposed for `let' >> (which was `let' = "letl", lexical; >> and "letd", dynamic), i.e. we would have >> >> `defun' = "defunl", lexical; and >> "defund", dynamic > > See CLTL, flet and labels: > > https://www.cs.cmu.edu/Groups/AI/html/cltl/clm/node83.html > > defun is convenient. Even non-Emacsing lispers want > the convenience of a supple interactive environment. > > (You have a similar situation with setq as with let, > BTW. It can assign to a lexical variable or a dynamic > one.) OK, now we got it plain and clear: 1. Remove `lexical-binding'. 2. Duplicate everything that acts differently because of it into "func" (the same as "funcl") and "funcd" (funk'd, ha) -- underground experts united https://dataswamp.org/~incal ^ permalink raw reply [flat|nested] 61+ messages in thread
* RE: [External] : Re: Lexical vs. dynamic: small examples? 2021-08-15 22:20 ` Emanuel Berg via Users list for the GNU Emacs text editor @ 2021-08-15 22:54 ` Drew Adams 0 siblings, 0 replies; 61+ messages in thread From: Drew Adams @ 2021-08-15 22:54 UTC (permalink / raw) To: Emanuel Berg; +Cc: 'Help-Gnu-Emacs (help-gnu-emacs@gnu.org)' [-- Attachment #1: Type: text/plain, Size: 887 bytes --] > >> Because the whole idea with functions is to modularize and > >> encapsulate I find the concept of function dynamic scope > >> a bit bizarre > > > > Do you want to be able to redefine a function easily? > > > > (defun foo (a) ...) > > ;; later... > > (defun foo (a b c) ...) > > No, they are global, of course! > > I meant dynamic with respect to the functional parameters. > I think that would be bizarre but I'm a maximalist in terms of > features so why not. As I explained, args to a function are bound lexically. (This is all documented, of course, in both CLTL and the Elisp manual.) A defun essentially dynamically binds a lambda to a name, the function name. It is the binding of that name that is dynamic. A lambda is itself a binding construct, and its formal parameters are bound to its actual arguments lexically. But I repeat myself. [-- Attachment #2: winmail.dat --] [-- Type: application/ms-tnef, Size: 14126 bytes --] ^ permalink raw reply [flat|nested] 61+ messages in thread
* RE: [External] : Re: Lexical vs. dynamic: small examples? 2021-08-15 21:57 ` Drew Adams 2021-08-15 22:20 ` Emanuel Berg via Users list for the GNU Emacs text editor @ 2021-08-15 23:16 ` Drew Adams 2022-01-09 7:08 ` Jean Louis 2021-08-15 23:42 ` Arthur Miller 2 siblings, 1 reply; 61+ messages in thread From: Drew Adams @ 2021-08-15 23:16 UTC (permalink / raw) To: Emanuel Berg; +Cc: 'Help-Gnu-Emacs (help-gnu-emacs@gnu.org)' [-- Attachment #1: Type: text/plain, Size: 837 bytes --] FWIW, I just wrote a tiny library, `dyna-show.el', that defines minor mode `dyna-show-mode', which highlights occurrences of "special" (aka dynamically scoped) variables. It just uses `special-variable-p', which is limited. From the attachment, you can see another limitation: occurrences of a function, e.g. `font-lock-mode', that has the same name as a dynamic variable are also highlighted. If it helps, good; if not, don't use it. ;-) You can use it together with library `hl-defined.el', which highlights symbols known to be defined as Emacs-Lisp functions or variables or both. (It can also highlight symbols _not_ known to be defined as fns or vars.) https://www.emacswiki.org/emacs/dyna-show.el https://www.emacswiki.org/emacs/HighlightLispFunctions https://www.emacswiki.org/emacs/hl-defined.el [-- Attachment #2: throw-dyna-show.png --] [-- Type: image/png, Size: 94588 bytes --] ^ permalink raw reply [flat|nested] 61+ messages in thread
* Re: [External] : Re: Lexical vs. dynamic: small examples? 2021-08-15 23:16 ` Drew Adams @ 2022-01-09 7:08 ` Jean Louis 2022-01-09 15:03 ` Emanuel Berg via Users list for the GNU Emacs text editor 0 siblings, 1 reply; 61+ messages in thread From: Jean Louis @ 2022-01-09 7:08 UTC (permalink / raw) To: Drew Adams Cc: 'Help-Gnu-Emacs (help-gnu-emacs@gnu.org)', Emanuel Berg * Drew Adams <drew.adams@oracle.com> [2021-08-16 02:17]: > FWIW, I just wrote a tiny library, `dyna-show.el', > that defines minor mode `dyna-show-mode', which > highlights occurrences of "special" (aka dynamically > scoped) variables. > > It just uses `special-variable-p', which is limited. > > From the attachment, you can see another limitation: > occurrences of a function, e.g. `font-lock-mode', > that has the same name as a dynamic variable are also > highlighted. Thanks, it is very helpful for cosmetics of the code. -- Jean Take action in Free Software Foundation campaigns: https://www.fsf.org/campaigns In support of Richard M. Stallman https://stallmansupport.org/ ^ permalink raw reply [flat|nested] 61+ messages in thread
* Re: [External] : Re: Lexical vs. dynamic: small examples? 2022-01-09 7:08 ` Jean Louis @ 2022-01-09 15:03 ` Emanuel Berg via Users list for the GNU Emacs text editor 0 siblings, 0 replies; 61+ messages in thread From: Emanuel Berg via Users list for the GNU Emacs text editor @ 2022-01-09 15:03 UTC (permalink / raw) To: help-gnu-emacs Jean Louis wrote: >> FWIW, I just wrote a tiny library, `dyna-show.el', that >> defines minor mode `dyna-show-mode', which highlights >> occurrences of "special" (aka dynamically >> scoped) variables. >> >> It just uses `special-variable-p', which is limited. >> >> From the attachment, you can see another limitation: >> occurrences of a function, e.g. `font-lock-mode', that has >> the same name as a dynamic variable are also highlighted. > > Thanks, it is very helpful for cosmetics of the code. But here it also has a functional value. Or to be even more precise, the functional value is also what is appealing, since I think it started in that end. -- underground experts united https://dataswamp.org/~incal ^ permalink raw reply [flat|nested] 61+ messages in thread
* Re: [External] : Re: Lexical vs. dynamic: small examples? 2021-08-15 21:57 ` Drew Adams 2021-08-15 22:20 ` Emanuel Berg via Users list for the GNU Emacs text editor 2021-08-15 23:16 ` Drew Adams @ 2021-08-15 23:42 ` Arthur Miller 2 siblings, 0 replies; 61+ messages in thread From: Arthur Miller @ 2021-08-15 23:42 UTC (permalink / raw) To: Drew Adams Cc: 'Help-Gnu-Emacs (help-gnu-emacs@gnu.org)', Emanuel Berg Drew Adams <drew.adams@oracle.com> writes: > You might also want to consider that Common Lisp, > designed by pretty much all of the wizards of Lisp > at the time, does what Emacs Lisp does. > > With the exception that Emacs is not yet there all > the way: I wish Emacs stayed at simpler Lisp, rather than redoing CL, but that is just my personal opinion. ^ permalink raw reply [flat|nested] 61+ messages in thread
* Re: [External] : Re: Lexical vs. dynamic: small examples? 2021-08-15 18:49 ` Emanuel Berg via Users list for the GNU Emacs text editor 2021-08-15 21:55 ` Stefan Monnier via Users list for the GNU Emacs text editor 2021-08-15 21:57 ` Drew Adams @ 2021-08-15 22:02 ` Lars Ingebrigtsen 2021-08-15 22:22 ` Emanuel Berg via Users list for the GNU Emacs text editor 2021-08-15 22:44 ` Emanuel Berg via Users list for the GNU Emacs text editor 2 siblings, 2 replies; 61+ messages in thread From: Lars Ingebrigtsen @ 2021-08-15 22:02 UTC (permalink / raw) To: help-gnu-emacs Emanuel Berg via Users list for the GNU Emacs text editor <help-gnu-emacs@gnu.org> writes: > So the proposal/question is, instead one could have `let' > _always_ be lexical, and one "with-variables-as" which would > be what is now called "dynamic binding" with let. These are `lexical-let' and `dlet' (in Emacs 28). -- (domestic pets only, the antidote for overdose, milk.) bloggy blog: http://lars.ingebrigtsen.no ^ permalink raw reply [flat|nested] 61+ messages in thread
* Re: [External] : Re: Lexical vs. dynamic: small examples? 2021-08-15 22:02 ` Lars Ingebrigtsen @ 2021-08-15 22:22 ` Emanuel Berg via Users list for the GNU Emacs text editor 2021-08-15 22:44 ` Stefan Monnier via Users list for the GNU Emacs text editor 2021-08-15 22:44 ` Emanuel Berg via Users list for the GNU Emacs text editor 1 sibling, 1 reply; 61+ messages in thread From: Emanuel Berg via Users list for the GNU Emacs text editor @ 2021-08-15 22:22 UTC (permalink / raw) To: help-gnu-emacs Lars Ingebrigtsen wrote: >> So the proposal/question is, instead one could have `let' >> _always_ be lexical, and one "with-variables-as" which >> would be what is now called "dynamic binding" with let. > > These are `lexical-let' and `dlet' (in Emacs 28). Ha! Now you are telling... -- underground experts united https://dataswamp.org/~incal ^ permalink raw reply [flat|nested] 61+ messages in thread
* Re: [External] : Re: Lexical vs. dynamic: small examples? 2021-08-15 22:22 ` Emanuel Berg via Users list for the GNU Emacs text editor @ 2021-08-15 22:44 ` Stefan Monnier via Users list for the GNU Emacs text editor 2021-08-21 3:38 ` Emanuel Berg via Users list for the GNU Emacs text editor 0 siblings, 1 reply; 61+ messages in thread From: Stefan Monnier via Users list for the GNU Emacs text editor @ 2021-08-15 22:44 UTC (permalink / raw) To: help-gnu-emacs Emanuel Berg via Users list for the GNU Emacs text editor [2021-08-16 00:22:43] wrote: > Lars Ingebrigtsen wrote: >>> So the proposal/question is, instead one could have `let' >>> _always_ be lexical, and one "with-variables-as" which >>> would be what is now called "dynamic binding" with let. >> These are `lexical-let' and `dlet' (in Emacs 28). > Ha! Now you are telling... Note that `lexical-let` is an old thing of the deprecated `cl.el` library which let you have static scoping let-bindings before `lexical-binding` existed. When `lexical-binding` is not enabled it's still currently the only way I know to get a statically scoped let-binding, but when `lexical-binding` is enabled you can use: (defmacro slet (bindings &rest body) (unless lexical-binding (error "`slet' requires `lexical-binding' to be enabled")) `(funcall (lambda ,(mapcar #'car bindings) ,@body) ,@(mapcar #'cadr bindings))) instead, Stefan ^ permalink raw reply [flat|nested] 61+ messages in thread
* Re: [External] : Re: Lexical vs. dynamic: small examples? 2021-08-15 22:44 ` Stefan Monnier via Users list for the GNU Emacs text editor @ 2021-08-21 3:38 ` Emanuel Berg via Users list for the GNU Emacs text editor 2021-08-24 2:08 ` Stefan Monnier via Users list for the GNU Emacs text editor 0 siblings, 1 reply; 61+ messages in thread From: Emanuel Berg via Users list for the GNU Emacs text editor @ 2021-08-21 3:38 UTC (permalink / raw) To: help-gnu-emacs Stefan Monnier via Users list for the GNU Emacs text editor wrote: > When `lexical-binding` is not enabled it's still currently > the only way I know to get a statically scoped let-binding, > but when `lexical-binding` is enabled you can use: > > (defmacro slet (bindings &rest body) > (unless lexical-binding > (error "`slet' requires `lexical-binding' to be enabled")) > `(funcall > (lambda ,(mapcar #'car bindings) > ,@body) > ,@(mapcar #'cadr bindings))) "slet" for statically scoped `let'! But ... if `lexical-binding' has to be enabled anyway then one can just use `let' anyway? Good that there is `letd' tho, now static/lexical scope just has to be made t by default and we're all slet :) -- underground experts united https://dataswamp.org/~incal ^ permalink raw reply [flat|nested] 61+ messages in thread
* Re: [External] : Re: Lexical vs. dynamic: small examples? 2021-08-21 3:38 ` Emanuel Berg via Users list for the GNU Emacs text editor @ 2021-08-24 2:08 ` Stefan Monnier via Users list for the GNU Emacs text editor 2021-08-25 23:34 ` Emanuel Berg via Users list for the GNU Emacs text editor 0 siblings, 1 reply; 61+ messages in thread From: Stefan Monnier via Users list for the GNU Emacs text editor @ 2021-08-24 2:08 UTC (permalink / raw) To: help-gnu-emacs > "slet" for statically scoped `let'! > But ... if `lexical-binding' has to be enabled anyway then one > can just use `let' anyway? Not if the var has been declared as dynamically scoped. Stefan ^ permalink raw reply [flat|nested] 61+ messages in thread
* Re: [External] : Re: Lexical vs. dynamic: small examples? 2021-08-24 2:08 ` Stefan Monnier via Users list for the GNU Emacs text editor @ 2021-08-25 23:34 ` Emanuel Berg via Users list for the GNU Emacs text editor 2021-08-25 23:40 ` Emanuel Berg via Users list for the GNU Emacs text editor ` (2 more replies) 0 siblings, 3 replies; 61+ messages in thread From: Emanuel Berg via Users list for the GNU Emacs text editor @ 2021-08-25 23:34 UTC (permalink / raw) To: help-gnu-emacs Stefan Monnier via Users list for the GNU Emacs text editor wrote: >> "slet" for statically scoped `let'! But ... if >> `lexical-binding' has to be enabled anyway then one can >> just use `let' anyway? > > Not if the var has been declared as dynamically scoped. You are right! It is the `defvar' that does it! This means, I've been using `defvar' to shut up the byte-compiler about variables not known to be defined, and this has actually made them dynamic? I wonder if I should remove the defvar and have the byte-compiler complain all it wants (I thought defvar only meant one intended to use the variable). But weren't all globals dynamic, I heard? So why does it "work" with no defvar, just `setq'? BTW notice that "slet" produces a warning altho it is `let's behavior one should be wary of ... ;;; -*- lexical-binding: t -*- ;;; ;;; this file: ;;; http://user.it.uu.se/~embe8573/emacs-init/geh.el ;;; https://dataswamp.org/~incal/emacs-init/geh.el (defmacro slet (bindings &rest body) (unless lexical-binding (error "`slet' requires `lexical-binding' to be enabled") ) `(funcall (lambda ,(mapcar #'car bindings) ,@body) ,@(mapcar #'cadr bindings) )) (defvar a) (setq a 100) (defun fun () a) ;; geh.el:21:1: Warning: Lexical argument shadows the dynamic variable a (slet ((a 1)) (list a (fun)) ) ; (1 100) (let ((a 2)) (list a (fun))) ; (2 2) -- underground experts united https://dataswamp.org/~incal ^ permalink raw reply [flat|nested] 61+ messages in thread
* Re: [External] : Re: Lexical vs. dynamic: small examples? 2021-08-25 23:34 ` Emanuel Berg via Users list for the GNU Emacs text editor @ 2021-08-25 23:40 ` Emanuel Berg via Users list for the GNU Emacs text editor 2021-08-26 0:10 ` Emanuel Berg via Users list for the GNU Emacs text editor 2021-08-25 23:46 ` Emanuel Berg via Users list for the GNU Emacs text editor 2021-08-25 23:47 ` Stefan Monnier via Users list for the GNU Emacs text editor 2 siblings, 1 reply; 61+ messages in thread From: Emanuel Berg via Users list for the GNU Emacs text editor @ 2021-08-25 23:40 UTC (permalink / raw) To: help-gnu-emacs > So why does it "work" with no defvar, just `setq'? Indeed, it works with just `setq', and no `defvar'! Now the byte-compiler instead warns about a reference to a free variable. Maybe it shouldn't do that and instead warn when one uses `defvar'? ;;; -*- lexical-binding: t -*- ;;; ;;; this file: ;;; http://user.it.uu.se/~embe8573/emacs-init/geh.el ;;; https://dataswamp.org/~incal/emacs-init/geh.el (defmacro slet (bindings &rest body) (unless lexical-binding (error "`slet' requires `lexical-binding' to be enabled") ) `(funcall (lambda ,(mapcar #'car bindings) ,@body) ,@(mapcar #'cadr bindings) )) (setq b 200) (defun fun () b) ; geh.el:18:3: Warning: reference to free variable ‘b’ (slet ((b 1)) (list b (fun)) ) ; (1 200) (let ((b 2)) (list b (fun))) ; (2 200) -- underground experts united https://dataswamp.org/~incal ^ permalink raw reply [flat|nested] 61+ messages in thread
* Re: [External] : Re: Lexical vs. dynamic: small examples? 2021-08-25 23:40 ` Emanuel Berg via Users list for the GNU Emacs text editor @ 2021-08-26 0:10 ` Emanuel Berg via Users list for the GNU Emacs text editor 2021-08-26 0:44 ` Emanuel Berg via Users list for the GNU Emacs text editor 0 siblings, 1 reply; 61+ messages in thread From: Emanuel Berg via Users list for the GNU Emacs text editor @ 2021-08-26 0:10 UTC (permalink / raw) To: help-gnu-emacs > Now the byte-compiler instead warns about a reference to > a free variable. Maybe it shouldn't do that and instead warn > when one uses `defvar'? The byte-compiler also warns about the assignment to the same variable, this is the `setq' line. geh.el: In toplevel form: geh.el:15:7: Warning: assignment to free variable ‘b’ In fun: geh.el:18:3: Warning: reference to free variable ‘b’ Other byte-compiler questions are, why does it stop warning after a second compilation? Because there is no change to the source file, so no compilation happens? But doesn't that mean you can just compile away the shortcomings of the code? Also, why does the warnings appear so many times? The file (geh.el) isn't `require'd or anything from any other file. Just `load'ed, once. Yet both warnings appear 6 times! And all the cl warnings, from slime ... slime stuff is required from two files, `slime' but also `slime-presentations', `slime-autoloads', `slime-banner', and `slime-reply'. (I use a/the MELPA version, 2.26.1.) Anyway, that warning appear 12 times! See output after geh.el, and last the Makefile. ;;; -*- lexical-binding: t -*- ;;; ;;; this file: ;;; http://user.it.uu.se/~embe8573/emacs-init/geh.el ;;; https://dataswamp.org/~incal/emacs-init/geh.el (defmacro slet (bindings &rest body) (unless lexical-binding (error "`slet' requires `lexical-binding' to be enabled") ) `(funcall (lambda ,(mapcar #'car bindings) ,@body) ,@(mapcar #'cadr bindings) )) (setq b 200) (defun fun () b) ; geh.el:18:3: Warning: reference to free variable ‘b’ (slet ((b 1)) (list b (fun)) ) ; (1 200) (let ((b 2)) (list b (fun))) ; (2 200) (how-many "Warning: assignment to free variable ‘b’" (point) (point-max)) ; 6 (how-many "Warning: reference to free variable ‘b’" (point) (point-max)) ; 6 (how-many "Warning: Package cl is deprecated" (point) (point-max)) ; 12 erc/erc-kill.el: erc/erc-iterate.el: In toplevel form: geh.el:15:7: Warning: assignment to free variable ‘b’ In fun: geh.el:18:3: Warning: reference to free variable ‘b’ In toplevel form: geh.el:15:7: Warning: assignment to free variable ‘b’ In fun: geh.el:18:3: Warning: reference to free variable ‘b’ frame-size.el: erc/erc-spell.el: In toplevel form: geh.el:15:7: Warning: assignment to free variable ‘b’ In fun: geh.el:18:3: Warning: reference to free variable ‘b’ geh.el: get-search-string.el: In toplevel form: geh.el:15:7: Warning: assignment to free variable ‘b’ In fun: geh.el:18:3: Warning: reference to free variable ‘b’ In toplevel form: geh.el:15:7: Warning: assignment to free variable ‘b’ In fun: geh.el:18:3: Warning: reference to free variable ‘b’ In toplevel form: geh.el:15:7: Warning: assignment to free variable ‘b’ In fun: geh.el:18:3: Warning: reference to free variable ‘b’ gnus/mail.el: In toplevel form: ide/slime-incal.el:33:1: Warning: Package cl is deprecated ide/slime-incal.el: In toplevel form: ide/slime-incal.el:33:1: Warning: Package cl is deprecated global-keys.el: In toplevel form: ide/slime-incal.el:33:1: Warning: Package cl is deprecated face.el: ide/ide.el: In toplevel form: face.el:15:1: Warning: Package cl is deprecated In toplevel form: face.el:15:1: Warning: Package cl is deprecated sort-incal.el: street.el: In toplevel form: face.el:15:1: Warning: Package cl is deprecated In toplevel form: face.el:15:1: Warning: Package cl is deprecated string.el: In toplevel form: face.el:15:1: Warning: Package cl is deprecated navigate-fs-keys.el: In toplevel form: face.el:15:1: Warning: Package cl is deprecated super.el: scroll.el: In toplevel form: face.el:15:1: Warning: Package cl is deprecated In toplevel form: face.el:15:1: Warning: Package cl is deprecated string-minibuffer.el: In toplevel form: face.el:15:1: Warning: Package cl is deprecated # this file: # http://user.it.uu.se/~embe8573/emacs-init/Makefile # https://dataswamp.org/~incal/emacs-init/Makefile emacs=/usr/local/bin/emacs ema-path=~/.emacs.d/emacs-init ema-erc=\"${ema-path}/erc\" ema-gnus=\"${ema-path}/gnus\" ema-ide=\"${ema-path}/ide\" ema-init=\"${ema-path}\" ema-w3m=\"${ema-path}/w3m\" ema=${ema-erc} ${ema-gnus} ${ema-ide} ${ema-init} ${ema-w3m} elpa-path=~/.emacs.d/elpa markdown-mode=\"${elpa-path}/markdown-mode-20201220.253\" w3m=\"${elpa-path}/w3m-20210615.103\" elpa=${markdown-mode} ${w3m} slime=\"/usr/share/emacs/site-lisp/elpa-src/slime-2.26.1/\" packs=${ema} ${elpa} ${slime} byte-compile=$(emacs) \ --batch \ --eval "(setq load-path (append load-path '(${packs})))" \ -f batch-byte-compile sed-filter=2>&1 | sed '/^\(Loading\|Wrote\)/d' # errors and warnings only error-file=error.txt INIT_FILE=~/.emacs INIT_FILE_BC=$(INIT_FILE).elc ELS = $(shell zsh -c "ls -1 **/*.el") ELCS= $(ELS:.el=.elc) all: $(ELCS) $(INIT_FILE_BC) rm -f $(error-file) $(INIT_FILE_BC): $(INIT_FILE) $(byte-compile) $< $(sed-filter) %.elc: %.el $(byte-compile) $< $(sed-filter) > $(error-file) if [ -s $(error-file) ]; then echo -n "\n$<: "; cat $(error-file); fi rm -f $<~ clean: $(shell zsh -c "rm -rf **/*.elc(N)") rm -f $(INIT_FILE_BC) $(error-file) again: ${MAKE} clean ${MAKE} new: ${MAKE} again -- underground experts united https://dataswamp.org/~incal ^ permalink raw reply [flat|nested] 61+ messages in thread
* Re: [External] : Re: Lexical vs. dynamic: small examples? 2021-08-26 0:10 ` Emanuel Berg via Users list for the GNU Emacs text editor @ 2021-08-26 0:44 ` Emanuel Berg via Users list for the GNU Emacs text editor 2021-08-26 17:01 ` FW: " Drew Adams 0 siblings, 1 reply; 61+ messages in thread From: Emanuel Berg via Users list for the GNU Emacs text editor @ 2021-08-26 0:44 UTC (permalink / raw) To: help-gnu-emacs So the way it should be done is: Put ;;; -*- lexical-binding: t -*- in the beginning of the file. Use `defvar' and `setq' for global variables that then become special/dynamic. Use `let' for local variables that then become lexical/static (because of `lexical-binding'). And nothing unexpected ever happens, because for the global, special/dynamic variables one uses prefixes? -- underground experts united https://dataswamp.org/~incal ^ permalink raw reply [flat|nested] 61+ messages in thread
* FW: [External] : Re: Lexical vs. dynamic: small examples? 2021-08-26 0:44 ` Emanuel Berg via Users list for the GNU Emacs text editor @ 2021-08-26 17:01 ` Drew Adams 2021-08-26 23:05 ` Emanuel Berg via Users list for the GNU Emacs text editor 0 siblings, 1 reply; 61+ messages in thread From: Drew Adams @ 2021-08-26 17:01 UTC (permalink / raw) To: 'Help-Gnu-Emacs (help-gnu-emacs@gnu.org)' [-- Attachment #1: Type: text/plain, Size: 714 bytes --] > So the way it should be done is: > > Put ;;; -*- lexical-binding: t -*- in the beginning of > the file. > > Use `defvar' and `setq' for global variables that then become > special/dynamic. > > Use `let' for local variables that then become lexical/static > (because of `lexical-binding'). Except `let' binds dynamically bound (aka "special") vars dynamically. E.g., if you have a (defvar foo) declaration then a subsequent (let ((foo ...))...) binds `foo' dynamically. > And nothing unexpected ever happens, because for the global, > special/dynamic variables one uses prefixes? Does one? Maybe. But how do you think a prefix in the name changes something wrt the kind of binding? [-- Attachment #2: winmail.dat --] [-- Type: application/ms-tnef, Size: 14138 bytes --] ^ permalink raw reply [flat|nested] 61+ messages in thread
* Re: FW: [External] : Re: Lexical vs. dynamic: small examples? 2021-08-26 17:01 ` FW: " Drew Adams @ 2021-08-26 23:05 ` Emanuel Berg via Users list for the GNU Emacs text editor 0 siblings, 0 replies; 61+ messages in thread From: Emanuel Berg via Users list for the GNU Emacs text editor @ 2021-08-26 23:05 UTC (permalink / raw) To: help-gnu-emacs Drew Adams wrote: >> Use `let' for local variables that then become >> lexical/static (because of `lexical-binding'). > > Except `let' binds dynamically bound (aka "special") > vars dynamically. E.g., if you have a (defvar foo) > declaration then a subsequent (let ((foo ...))...) > binds `foo' dynamically. > >> And nothing unexpected ever happens, because for the >> global, special/dynamic variables one uses prefixes? > > Does one? Maybe. But how do you think a prefix in the name > changes something wrt the kind of binding? I don't know, maybe one isn't supposed to use prefixes in `let'? -- underground experts united https://dataswamp.org/~incal ^ permalink raw reply [flat|nested] 61+ messages in thread
* Re: [External] : Re: Lexical vs. dynamic: small examples? 2021-08-25 23:34 ` Emanuel Berg via Users list for the GNU Emacs text editor 2021-08-25 23:40 ` Emanuel Berg via Users list for the GNU Emacs text editor @ 2021-08-25 23:46 ` Emanuel Berg via Users list for the GNU Emacs text editor 2021-08-25 23:47 ` Stefan Monnier via Users list for the GNU Emacs text editor 2 siblings, 0 replies; 61+ messages in thread From: Emanuel Berg via Users list for the GNU Emacs text editor @ 2021-08-25 23:46 UTC (permalink / raw) To: help-gnu-emacs > (defmacro slet (bindings &rest body) > (unless lexical-binding > (error "`slet' requires `lexical-binding' to be enabled") ) > `(funcall > (lambda ,(mapcar #'car bindings) > ,@body) > ,@(mapcar #'cadr bindings) )) Can't we add "slet" to Emacs, then one would always get the intended static scope and it is even foolproof since it warns if `lexical-binding' isn't enabled. Don't forget the auto-indentation for `emacs-lisp-mode' ... -- underground experts united https://dataswamp.org/~incal ^ permalink raw reply [flat|nested] 61+ messages in thread
* Re: [External] : Re: Lexical vs. dynamic: small examples? 2021-08-25 23:34 ` Emanuel Berg via Users list for the GNU Emacs text editor 2021-08-25 23:40 ` Emanuel Berg via Users list for the GNU Emacs text editor 2021-08-25 23:46 ` Emanuel Berg via Users list for the GNU Emacs text editor @ 2021-08-25 23:47 ` Stefan Monnier via Users list for the GNU Emacs text editor 2021-08-26 0:57 ` Emanuel Berg via Users list for the GNU Emacs text editor ` (2 more replies) 2 siblings, 3 replies; 61+ messages in thread From: Stefan Monnier via Users list for the GNU Emacs text editor @ 2021-08-25 23:47 UTC (permalink / raw) To: help-gnu-emacs > This means, I've been using `defvar' to shut up the > byte-compiler about variables not known to be defined, and > this has actually made them dynamic? Of course. If the compiler says it's "not known to be defined" that means the var isn't bound lexically (either that, or there's a bug in the compiler), so it can only make sense if the var is global or dynamically scoped (and both are closely related). There exist global variables which shouldn't be dynamically scoped, but they're rare in ELisp, mostly because of our use of namespace prefixes. One example is the variable `pi` which holds the famous constant but we don't want (let ((pi (get-previous-interval x))) ...) to temporarily redefine `pi` to something unrelated. This example is obsolete, tho: you should use `float-pi` instead of `pi` to refer to the famous constant. Stefan ^ permalink raw reply [flat|nested] 61+ messages in thread
* Re: [External] : Re: Lexical vs. dynamic: small examples? 2021-08-25 23:47 ` Stefan Monnier via Users list for the GNU Emacs text editor @ 2021-08-26 0:57 ` Emanuel Berg via Users list for the GNU Emacs text editor 2021-08-28 1:36 ` Emanuel Berg via Users list for the GNU Emacs text editor 2021-08-28 1:41 ` Emanuel Berg via Users list for the GNU Emacs text editor 2 siblings, 0 replies; 61+ messages in thread From: Emanuel Berg via Users list for the GNU Emacs text editor @ 2021-08-26 0:57 UTC (permalink / raw) To: help-gnu-emacs Stefan Monnier via Users list for the GNU Emacs text editor wrote: > One example is the variable `pi` which holds the famous > constant but we don't want (let ((pi (get-previous-interval > x))) ...) to temporarily redefine `pi` to > something unrelated. > > This example is obsolete, tho: you should use `float-pi` > instead of `pi` to refer to the famous constant. Right, but `float-pi' is defined with `defconst'. Let's see what it says ... Define SYMBOL as a constant variable. This declares that neither programs nor users should ever change the value. This constancy is not actually enforced by Emacs Lisp, but SYMBOL is marked as a special variable so that it is never lexically bound. It looks like this in float-sup.el: (defconst float-pi (* 4 (atan 1)) "The value of Pi (3.1415926...).") (with-suppressed-warnings ((lexical pi)) (defconst pi float-pi "Obsolete since Emacs-23.3. Use `float-pi' instead.")) (internal-make-var-non-special 'pi) So `pi' is explicitely made non-dynamic with `internal-make-var-non-special'. -- underground experts united https://dataswamp.org/~incal ^ permalink raw reply [flat|nested] 61+ messages in thread
* Re: [External] : Re: Lexical vs. dynamic: small examples? 2021-08-25 23:47 ` Stefan Monnier via Users list for the GNU Emacs text editor 2021-08-26 0:57 ` Emanuel Berg via Users list for the GNU Emacs text editor @ 2021-08-28 1:36 ` Emanuel Berg via Users list for the GNU Emacs text editor 2021-08-28 1:41 ` Emanuel Berg via Users list for the GNU Emacs text editor 2 siblings, 0 replies; 61+ messages in thread From: Emanuel Berg via Users list for the GNU Emacs text editor @ 2021-08-28 1:36 UTC (permalink / raw) To: help-gnu-emacs Stefan Monnier via Users list for the GNU Emacs text editor wrote: > Of course. If the compiler says it's "not known to be > defined" that means the var isn't bound lexically (either > that, or there's a bug in the compiler), so it can only make > sense if the var is global or dynamically scoped (and both > are closely related). Check this out, here we seemingly define a global variable which isn't special/dynamic (because `special-variable-p' says it isn't) but it behaves like one anyway so I guess it is? Maybe it (the predicate) can only look at the definition and if it doesn't have an initial/default value it can't tell ... something? ;;; -*- lexical-binding: t -*- ;;; ;;; this file: ;;; https://dataswamp.org/~incal/emacs-init/scope.el ;;; ;;; g = global ;;; sd = special/dynamic ;;; ls = lexical/static ;;; v = variable (defvar gsd-v 1) ; 1 (special-variable-p 'gsd-v) ; t (defvar gls-v) (setq gls-v 2) ; 2 (special-variable-p 'gls-v) ; nil (defun fun-lol () (list gsd-v gls-v v) ) (setq lexical-binding nil) (let ((gsd-v 100) (gls-v 200) (v 300) ) (list (list gsd-v gls-v v) (fun-lol) )) ; ((100 200 300) (100 200 300)) (setq lexical-binding t) (let ((gsd-v 100) (gls-v 200) (v 300) ) (list (list gsd-v gls-v v) (fun-lol) )) ; DNC, lexical/static `let' binding v undefined in fun-lol (defun fun-lol-2 () (list gsd-v gls-v) ) (let ((gsd-v 100) (gls-v 200) (v 300) ) (list (list gsd-v gls-v v) (fun-lol-2) )) ; ((100 200 300) (100 200)) -- underground experts united https://dataswamp.org/~incal ^ permalink raw reply [flat|nested] 61+ messages in thread
* Re: [External] : Re: Lexical vs. dynamic: small examples? 2021-08-25 23:47 ` Stefan Monnier via Users list for the GNU Emacs text editor 2021-08-26 0:57 ` Emanuel Berg via Users list for the GNU Emacs text editor 2021-08-28 1:36 ` Emanuel Berg via Users list for the GNU Emacs text editor @ 2021-08-28 1:41 ` Emanuel Berg via Users list for the GNU Emacs text editor 2 siblings, 0 replies; 61+ messages in thread From: Emanuel Berg via Users list for the GNU Emacs text editor @ 2021-08-28 1:41 UTC (permalink / raw) To: help-gnu-emacs Stefan Monnier via Users list for the GNU Emacs text editor wrote: > One example is the variable `pi` which holds the famous > constant but we don't want (let ((pi (get-previous-interval > x))) ...) to temporarily redefine `pi` to > something unrelated. (defconst float-pi (* 4 (atan 1)) "The value of Pi (3.1415926...).") (with-suppressed-warnings ((lexical pi)) (defconst pi float-pi "Obsolete since Emacs-23.3. Use `float-pi' instead.")) (make-obsolete-variable 'pi 'float-pi "23.3") (internal-make-var-non-special 'pi) OT, can't (make-obsolete-variable 'pi 'float-pi "23.3") make that docstring ... obsolete? Or perhaps one still wants it so it'll be human-language readable in the code, not just the help/byte-compiler? -- underground experts united https://dataswamp.org/~incal ^ permalink raw reply [flat|nested] 61+ messages in thread
* Re: [External] : Re: Lexical vs. dynamic: small examples? 2021-08-15 22:02 ` Lars Ingebrigtsen 2021-08-15 22:22 ` Emanuel Berg via Users list for the GNU Emacs text editor @ 2021-08-15 22:44 ` Emanuel Berg via Users list for the GNU Emacs text editor 2021-08-15 22:58 ` Stefan Monnier via Users list for the GNU Emacs text editor 1 sibling, 1 reply; 61+ messages in thread From: Emanuel Berg via Users list for the GNU Emacs text editor @ 2021-08-15 22:44 UTC (permalink / raw) To: help-gnu-emacs Lars Ingebrigtsen wrote: > These are `lexical-let' and `dlet' Can't we have an official alias "llet" for `lexical-let'? (defalias 'llet #'lexical-let) (defalias 'llet* #'lexical-let*) It is much faster to type than lexical-let and smaller, also it would make it consistent with `dlet' and perhaps soften the psychological transition from `let' :) Ah... can't wait to remove all the ;;; -*- lexical-binding: t -*- from my code :) -- underground experts united https://dataswamp.org/~incal ^ permalink raw reply [flat|nested] 61+ messages in thread
* Re: [External] : Re: Lexical vs. dynamic: small examples? 2021-08-15 22:44 ` Emanuel Berg via Users list for the GNU Emacs text editor @ 2021-08-15 22:58 ` Stefan Monnier via Users list for the GNU Emacs text editor 2021-08-15 23:13 ` Emanuel Berg via Users list for the GNU Emacs text editor 0 siblings, 1 reply; 61+ messages in thread From: Stefan Monnier via Users list for the GNU Emacs text editor @ 2021-08-15 22:58 UTC (permalink / raw) To: help-gnu-emacs > Ah... can't wait to remove all the > > ;;; -*- lexical-binding: t -*- > > from my code :) That won't happen before all the files contain the above line, sadly. Stefan ^ permalink raw reply [flat|nested] 61+ messages in thread
* Re: [External] : Re: Lexical vs. dynamic: small examples? 2021-08-15 22:58 ` Stefan Monnier via Users list for the GNU Emacs text editor @ 2021-08-15 23:13 ` Emanuel Berg via Users list for the GNU Emacs text editor 2021-08-15 23:56 ` Stefan Monnier via Users list for the GNU Emacs text editor 0 siblings, 1 reply; 61+ messages in thread From: Emanuel Berg via Users list for the GNU Emacs text editor @ 2021-08-15 23:13 UTC (permalink / raw) To: help-gnu-emacs Stefan Monnier via Users list for the GNU Emacs text editor wrote: >> Ah... can't wait to remove all the >> >> ;;; -*- lexical-binding: t -*- >> >> from my code :) > > That won't happen before all the files contain the above > line, sadly. Can't it be done with `lexical-let'? It seems to work: ;;; this file: ;;; http://user.it.uu.se/~embe8573/emacs-init/geh-dyn.el ;;; https://dataswamp.org/~incal/emacs-init/geh-dyn.el (require 'cl-lib) (defun *a10 () (* a 2) ) (defun mult () (lexical-let ((a 10)) (*a10) )) ;; (mult) ; *a10: Symbol’s value as variable is void: a But sometimes it says (invalid-function (a 10)) - hm ... -- underground experts united https://dataswamp.org/~incal ^ permalink raw reply [flat|nested] 61+ messages in thread
* Re: [External] : Re: Lexical vs. dynamic: small examples? 2021-08-15 23:13 ` Emanuel Berg via Users list for the GNU Emacs text editor @ 2021-08-15 23:56 ` Stefan Monnier via Users list for the GNU Emacs text editor 2021-08-16 0:43 ` Emanuel Berg via Users list for the GNU Emacs text editor 0 siblings, 1 reply; 61+ messages in thread From: Stefan Monnier via Users list for the GNU Emacs text editor @ 2021-08-15 23:56 UTC (permalink / raw) To: help-gnu-emacs > Can't it be done with `lexical-let'? `lexical-let` is deprecated (and expands to ugly code, is less efficient than using `lexical-binding`, and makes debugging harder). Note that I also consider not using `lexical-binding` as deprecated (tho this is not yet the official position of Emacs maintainers). Stefan ^ permalink raw reply [flat|nested] 61+ messages in thread
* Re: [External] : Re: Lexical vs. dynamic: small examples? 2021-08-15 23:56 ` Stefan Monnier via Users list for the GNU Emacs text editor @ 2021-08-16 0:43 ` Emanuel Berg via Users list for the GNU Emacs text editor 0 siblings, 0 replies; 61+ messages in thread From: Emanuel Berg via Users list for the GNU Emacs text editor @ 2021-08-16 0:43 UTC (permalink / raw) To: help-gnu-emacs Stefan Monnier via Users list for the GNU Emacs text editor wrote: >> Can't it be done with `lexical-let'? > > `lexical-let` is deprecated (and expands to ugly code, is > less efficient than using `lexical-binding`, and makes > debugging harder). OK, gotcha. > Note that I also consider not using `lexical-binding` as > deprecated (tho this is not yet the official position of > Emacs maintainers). I know right? BTW I've realized static vs. dynamic scope are the best terms. The words are each others opposites but they are also the best in terms of technology. Static scope: (let ((x 1)) . <- that's right! no (when run-time-condition <- matter conditions or (take-a-long-detour) ) <- detours it's the . ) <- same scope Dynamic scope: (let ((x 1)) . <- oh, no! x's scope now depends (when run-time-condition <- on run-time particulars which (take-a-long-detour) ) <- determine if it extends or . ) <- not into the detour function "Lexical" is intuitive with respect to the static scope but it isn't as intuitive why the dynamic scope _isn't_ "lexical". One has to think of the above to get there. But if one has to think of the above, one might just stop at that and call it dynamic. "Special" is confusing, especially because global variables behaves intuitively and dynamic `let' don't - and they are all special! The static vs. dynamic position of definition, does that relate to how this is implemented (a new variable vs. a new value pushed to the stack?) - but, since it works for the best terms, i.e. static vs. dynamic scope, the more the merrier :) -- underground experts united https://dataswamp.org/~incal ^ permalink raw reply [flat|nested] 61+ messages in thread
* FW: [External] : Re: Lexical vs. dynamic: small examples? 2021-08-15 1:18 ` Emanuel Berg via Users list for the GNU Emacs text editor 2021-08-15 4:44 ` Emanuel Berg via Users list for the GNU Emacs text editor @ 2021-08-15 15:42 ` Drew Adams 1 sibling, 0 replies; 61+ messages in thread From: Drew Adams @ 2021-08-15 15:42 UTC (permalink / raw) To: 'Help-Gnu-Emacs (help-gnu-emacs@gnu.org)'; +Cc: Emanuel Berg [-- Attachment #1: Type: text/plain, Size: 1236 bytes --] [Was bitten by Reply All not including the list again...] > > "Dynamic scope" is a misnomer, BTW; it means only that - no > > particular scope and dynamic extent [...] `let' provides > > a lexical binding - the scope ends where the `let' > > ends, lexically. > > But with `let' doesn't the scope end where the let ends even > for dynamic binding? No. Dynamic bindings have indefinite scope - that is, no particular scope. The binding has dynamic _extent_ - it lasts _as long as_ (time) the code in the `let' body is executing (which can include nonlocal exits by that code (or code called by that code) - e.g. `throw'). For such a variable the `let' does not define a scope; it only determines which code realizes the binding's duration. Scope and extent (duration for referencing) are two different things. See the CLTL chapter I pointed to. > If it isn't only about let, what is it about more? `let' is not the only construct that can define a scope. For example, a function definition (a `defun' or a lambda) defines the scope of its formal parameters - they're lexically scoped. Again, I recommend that CLTL chapter. It's short, and it explains things well, including with examples. [-- Attachment #2: winmail.dat --] [-- Type: application/ms-tnef, Size: 13542 bytes --] ^ permalink raw reply [flat|nested] 61+ messages in thread
* Re: Lexical vs. dynamic: small examples?
@ 2022-01-09 17:40 Drew Adams
2022-01-10 13:10 ` Emanuel Berg via Users list for the GNU Emacs text editor
0 siblings, 1 reply; 61+ messages in thread
From: Drew Adams @ 2022-01-09 17:40 UTC (permalink / raw)
To: Emanuel Berg, 'Help-Gnu-Emacs (help-gnu-emacs@gnu.org)'
[-- Attachment #1: Type: text/plain, Size: 1776 bytes --]
> >> FWIW, I just wrote a tiny library, `dyna-show.el', that
> >> defines minor mode `dyna-show-mode', which highlights
> >> occurrences of "special" (aka dynamically
> >> scoped) variables.
> >>
> >> It just uses `special-variable-p', which is limited.
> >>
> >> From the attachment, you can see another limitation:
> >> occurrences of a function, e.g. `font-lock-mode', that has
> >> the same name as a dynamic variable are also highlighted.
> >
> > Thanks, it is very helpful for cosmetics of the code.
>
> But here it also has a functional value. Or to be even more
> precise, the functional value is also what is appealing, since
> I think it started in that end.
tl;dr:
1. It can be useful. 2. It's not foolproof.
___
I guess you're referring to this (from the
`dyna-show.el' Commentary)?
[I]f a function has the same name as a dynamic
variable, then its occurrences are also
highlighted, as if they were occurrences of
the variable.
For example `font-lock-mode' is a variable as
well as a function. Both kinds of occurrences
of that symbol are highlighted the same.
Whether this is considered a feature or a
limitation, the reason is that it requires no
analysis of the code (which would anyway be
problematic and limited) to determine how each
occurrence is used.
The Commentary calls it out as a limitation.
And the sentence above comes right after this
additional caveat:
The simple built-in test `special-variable-p'
is used. That test is not 100% reliable. It
doesn't respect vacuous `defvar' sexps, which
declare a variable to be special in a given
context, without assigning a value to the
variable. Instead, it uses `defvar',`defconst',
and `defcustom' sexps with a value arg present.
[-- Attachment #2: winmail.dat --]
[-- Type: application/ms-tnef, Size: 13769 bytes --]
^ permalink raw reply [flat|nested] 61+ messages in thread
* Re: Lexical vs. dynamic: small examples? 2022-01-09 17:40 Drew Adams @ 2022-01-10 13:10 ` Emanuel Berg via Users list for the GNU Emacs text editor 0 siblings, 0 replies; 61+ messages in thread From: Emanuel Berg via Users list for the GNU Emacs text editor @ 2022-01-10 13:10 UTC (permalink / raw) To: help-gnu-emacs Drew Adams wrote: >> But here it also has a functional value. Or to be even more >> precise, the functional value is also what is appealing, >> since I think it started in that end. > > tl;dr: > 1. It can be useful. 2. It's not foolproof. > ___ > > I guess you're referring to this (from the > `dyna-show.el' Commentary)? > > [I]f a function has the same name as a dynamic > variable, then its occurrences are also > highlighted, as if they were occurrences of > the variable. > > For example `font-lock-mode' is a variable as > well as a function. Both kinds of occurrences > of that symbol are highlighted the same. > > Whether this is considered a feature or a > limitation, the reason is that it requires no > analysis of the code (which would anyway be > problematic and limited) to determine how each > occurrence is used. > > The Commentary calls it out as a limitation. > And the sentence above comes right after this > additional caveat: > > The simple built-in test `special-variable-p' is used. > That test is not 100% reliable. It doesn't respect vacuous > `defvar' sexps, which declare a variable to be special in > a given context, without assigning a value to the > variable. Instead, it uses `defvar',`defconst', and > `defcustom' sexps with a value arg present. Well, yes, that's a good example, but actually the functional gain starts with the programmer thinking "hey, what should it be called?" - "obey tradition" (follow the convention) and even at that point the harsh reality of a programmer gets a little "bit" easier ;) -- underground experts united https://dataswamp.org/~incal ^ permalink raw reply [flat|nested] 61+ messages in thread
end of thread, other threads:[~2022-01-10 13:10 UTC | newest] Thread overview: 61+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2021-08-14 3:34 Lexical vs. dynamic: small examples? Eduardo Ochs 2021-08-14 3:56 ` Emanuel Berg via Users list for the GNU Emacs text editor 2021-08-14 4:12 ` Eduardo Ochs 2021-08-14 7:35 ` tomas 2021-08-14 16:00 ` Eduardo Ochs 2021-08-14 19:41 ` Emanuel Berg via Users list for the GNU Emacs text editor 2021-08-14 20:42 ` tomas 2021-08-14 19:31 ` Emanuel Berg via Users list for the GNU Emacs text editor 2021-08-14 20:31 ` tomas 2021-08-14 21:26 ` Emanuel Berg via Users list for the GNU Emacs text editor 2021-08-14 21:29 ` Emanuel Berg via Users list for the GNU Emacs text editor 2021-08-14 13:35 ` [External] : " Drew Adams 2021-08-14 16:15 ` Eduardo Ochs 2021-08-14 19:00 ` Gregory Heytings 2021-08-14 20:16 ` Emanuel Berg via Users list for the GNU Emacs text editor 2021-08-14 20:23 ` Gregory Heytings 2021-08-14 21:05 ` Emanuel Berg via Users list for the GNU Emacs text editor 2021-08-14 21:13 ` tomas 2021-08-14 21:28 ` Emanuel Berg via Users list for the GNU Emacs text editor 2021-08-14 20:41 ` tomas 2021-08-15 0:29 ` [External] : " Drew Adams 2021-08-15 0:52 ` Emanuel Berg via Users list for the GNU Emacs text editor 2021-08-15 1:04 ` Emanuel Berg via Users list for the GNU Emacs text editor 2021-08-15 1:18 ` Emanuel Berg via Users list for the GNU Emacs text editor 2021-08-15 4:44 ` Emanuel Berg via Users list for the GNU Emacs text editor 2021-08-15 5:02 ` Emanuel Berg via Users list for the GNU Emacs text editor 2021-08-15 15:49 ` Drew Adams 2021-08-15 18:49 ` Emanuel Berg via Users list for the GNU Emacs text editor 2021-08-15 21:55 ` Stefan Monnier via Users list for the GNU Emacs text editor 2021-08-15 22:04 ` Emanuel Berg via Users list for the GNU Emacs text editor 2021-08-15 21:57 ` Drew Adams 2021-08-15 22:20 ` Emanuel Berg via Users list for the GNU Emacs text editor 2021-08-15 22:54 ` Drew Adams 2021-08-15 23:16 ` Drew Adams 2022-01-09 7:08 ` Jean Louis 2022-01-09 15:03 ` Emanuel Berg via Users list for the GNU Emacs text editor 2021-08-15 23:42 ` Arthur Miller 2021-08-15 22:02 ` Lars Ingebrigtsen 2021-08-15 22:22 ` Emanuel Berg via Users list for the GNU Emacs text editor 2021-08-15 22:44 ` Stefan Monnier via Users list for the GNU Emacs text editor 2021-08-21 3:38 ` Emanuel Berg via Users list for the GNU Emacs text editor 2021-08-24 2:08 ` Stefan Monnier via Users list for the GNU Emacs text editor 2021-08-25 23:34 ` Emanuel Berg via Users list for the GNU Emacs text editor 2021-08-25 23:40 ` Emanuel Berg via Users list for the GNU Emacs text editor 2021-08-26 0:10 ` Emanuel Berg via Users list for the GNU Emacs text editor 2021-08-26 0:44 ` Emanuel Berg via Users list for the GNU Emacs text editor 2021-08-26 17:01 ` FW: " Drew Adams 2021-08-26 23:05 ` Emanuel Berg via Users list for the GNU Emacs text editor 2021-08-25 23:46 ` Emanuel Berg via Users list for the GNU Emacs text editor 2021-08-25 23:47 ` Stefan Monnier via Users list for the GNU Emacs text editor 2021-08-26 0:57 ` Emanuel Berg via Users list for the GNU Emacs text editor 2021-08-28 1:36 ` Emanuel Berg via Users list for the GNU Emacs text editor 2021-08-28 1:41 ` Emanuel Berg via Users list for the GNU Emacs text editor 2021-08-15 22:44 ` Emanuel Berg via Users list for the GNU Emacs text editor 2021-08-15 22:58 ` Stefan Monnier via Users list for the GNU Emacs text editor 2021-08-15 23:13 ` Emanuel Berg via Users list for the GNU Emacs text editor 2021-08-15 23:56 ` Stefan Monnier via Users list for the GNU Emacs text editor 2021-08-16 0:43 ` Emanuel Berg via Users list for the GNU Emacs text editor 2021-08-15 15:42 ` FW: " Drew Adams -- strict thread matches above, loose matches on Subject: below -- 2022-01-09 17:40 Drew Adams 2022-01-10 13:10 ` Emanuel Berg via Users list for the GNU Emacs text editor
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).