* Declaring a local dynamic variable? @ 2013-09-20 9:52 Joost Kremers 2013-09-20 12:30 ` Stefan Monnier ` (2 more replies) 0 siblings, 3 replies; 46+ messages in thread From: Joost Kremers @ 2013-09-20 9:52 UTC (permalink / raw) To: help-gnu-emacs Hi, If I purposefully use a local dynamic variable as in: (defun foo () (let* ((my-counter 0) (var (or (bar 'one) (bar 'two) (bar 'three)))) (do-something-with var) (issue-a-message-depending-on-the-value-of my-counter))) (defun bar (arg) (setq my-counter (1+ my-counter)) (do-something-with arg) (and-return-result)) the byte compiler will issue a warning about referring to a free variable in `bar'. What is the proper way of letting the byte compiler know that it shouldn't worry about this particular variable, without silencing it completely? I don't want to disable all warnings, or even just the warnings about free variables. Right now, I'm using a `(defvar my-counter)' inside the function definition of `bar', but that looks a bit strange. Is there a better or "more proper" way of doing this? TIA Joost -- Joost Kremers joostkremers@fastmail.fm Selbst in die Unterwelt dringt durch Spalten Licht EN:SiS(9) ^ permalink raw reply [flat|nested] 46+ messages in thread
* Re: Declaring a local dynamic variable? 2013-09-20 9:52 Declaring a local dynamic variable? Joost Kremers @ 2013-09-20 12:30 ` Stefan Monnier 2013-09-20 14:54 ` Andreas Röhler [not found] ` <mailman.2569.1379688787.10748.help-gnu-emacs@gnu.org> 2013-09-22 17:11 ` Pascal J. Bourguignon [not found] ` <mailman.2566.1379680283.10748.help-gnu-emacs@gnu.org> 2 siblings, 2 replies; 46+ messages in thread From: Stefan Monnier @ 2013-09-20 12:30 UTC (permalink / raw) To: help-gnu-emacs > If I purposefully use a local dynamic variable as in: Use (defvar my-counter) at the file's top-level to indicate that this variable is used in a way that relies on dynamic scoping. Stefan ^ permalink raw reply [flat|nested] 46+ messages in thread
* Re: Declaring a local dynamic variable? 2013-09-20 12:30 ` Stefan Monnier @ 2013-09-20 14:54 ` Andreas Röhler [not found] ` <mailman.2569.1379688787.10748.help-gnu-emacs@gnu.org> 1 sibling, 0 replies; 46+ messages in thread From: Andreas Röhler @ 2013-09-20 14:54 UTC (permalink / raw) To: help-gnu-emacs Am 20.09.2013 14:30, schrieb Stefan Monnier: >> If I purposefully use a local dynamic variable as in: > > Use (defvar my-counter) at the file's top-level to indicate that this > variable is used in a way that relies on dynamic scoping. > > > Stefan > > > A need to write code just to silence compiler warnings? Emacs could do better. ^ permalink raw reply [flat|nested] 46+ messages in thread
[parent not found: <mailman.2569.1379688787.10748.help-gnu-emacs@gnu.org>]
* Re: Declaring a local dynamic variable? [not found] ` <mailman.2569.1379688787.10748.help-gnu-emacs@gnu.org> @ 2013-09-20 15:10 ` Barry Margolin 2013-09-20 16:34 ` Andreas Röhler [not found] ` <mailman.2578.1379694764.10748.help-gnu-emacs@gnu.org> 0 siblings, 2 replies; 46+ messages in thread From: Barry Margolin @ 2013-09-20 15:10 UTC (permalink / raw) To: help-gnu-emacs [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #1: Type: text/plain, Size: 753 bytes --] In article <mailman.2569.1379688787.10748.help-gnu-emacs@gnu.org>, Andreas Röhler <andreas.roehler@easy-emacs.de> wrote: > Am 20.09.2013 14:30, schrieb Stefan Monnier: > >> If I purposefully use a local dynamic variable as in: > > > > Use (defvar my-counter) at the file's top-level to indicate that this > > variable is used in a way that relies on dynamic scoping. > > A need to write code just to silence compiler warnings? > Emacs could do better. Other than "code", what would you suggest? A commenting convention to suppress warnings? But comments are removed by the reader, before the compiler gets to process the code. -- Barry Margolin, barmar@alum.mit.edu Arlington, MA *** PLEASE post questions in newsgroups, not directly to me *** ^ permalink raw reply [flat|nested] 46+ messages in thread
* Re: Declaring a local dynamic variable? 2013-09-20 15:10 ` Barry Margolin @ 2013-09-20 16:34 ` Andreas Röhler [not found] ` <mailman.2578.1379694764.10748.help-gnu-emacs@gnu.org> 1 sibling, 0 replies; 46+ messages in thread From: Andreas Röhler @ 2013-09-20 16:34 UTC (permalink / raw) To: help-gnu-emacs Am 20.09.2013 17:10, schrieb Barry Margolin: > In article <mailman.2569.1379688787.10748.help-gnu-emacs@gnu.org>, > Andreas Röhler <andreas.roehler@easy-emacs.de> wrote: > >> Am 20.09.2013 14:30, schrieb Stefan Monnier: >>>> If I purposefully use a local dynamic variable as in: >>> >>> Use (defvar my-counter) at the file's top-level to indicate that this >>> variable is used in a way that relies on dynamic scoping. >> >> A need to write code just to silence compiler warnings? >> Emacs could do better. > > Other than "code", what would you suggest? In the precise case: just drop that warning. In a wider sense, IMO a modular approach is better. Restrict compiler warnings to obvious errors, don't mix style questions in. Encourage use of style-checkers instead. Cheers ^ permalink raw reply [flat|nested] 46+ messages in thread
[parent not found: <mailman.2578.1379694764.10748.help-gnu-emacs@gnu.org>]
* Re: Declaring a local dynamic variable? [not found] ` <mailman.2578.1379694764.10748.help-gnu-emacs@gnu.org> @ 2013-09-20 20:59 ` Barry Margolin 2013-09-21 5:49 ` Andreas Röhler ` (2 more replies) 0 siblings, 3 replies; 46+ messages in thread From: Barry Margolin @ 2013-09-20 20:59 UTC (permalink / raw) To: help-gnu-emacs [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #1: Type: text/plain, Size: 1147 bytes --] In article <mailman.2578.1379694764.10748.help-gnu-emacs@gnu.org>, Andreas Röhler <andreas.roehler@easy-emacs.de> wrote: > Am 20.09.2013 17:10, schrieb Barry Margolin: > > In article <mailman.2569.1379688787.10748.help-gnu-emacs@gnu.org>, > > Andreas Röhler <andreas.roehler@easy-emacs.de> wrote: > > > >> Am 20.09.2013 14:30, schrieb Stefan Monnier: > >>>> If I purposefully use a local dynamic variable as in: > >>> > >>> Use (defvar my-counter) at the file's top-level to indicate that this > >>> variable is used in a way that relies on dynamic scoping. > >> > >> A need to write code just to silence compiler warnings? > >> Emacs could do better. > > > > Other than "code", what would you suggest? > > In the precise case: just drop that warning. > > In a wider sense, IMO a modular approach is better. > Restrict compiler warnings to obvious errors, don't mix style questions in. This isn't a style warning. Often the reason is mistyping a local variable name. (let ((foobar ...)) ... (blah fobar) ...) -- Barry Margolin, barmar@alum.mit.edu Arlington, MA *** PLEASE post questions in newsgroups, not directly to me *** ^ permalink raw reply [flat|nested] 46+ messages in thread
* Re: Declaring a local dynamic variable? 2013-09-20 20:59 ` Barry Margolin @ 2013-09-21 5:49 ` Andreas Röhler 2013-09-23 16:19 ` Joost Kremers [not found] ` <mailman.2622.1379742443.10748.help-gnu-emacs@gnu.org> 2 siblings, 0 replies; 46+ messages in thread From: Andreas Röhler @ 2013-09-21 5:49 UTC (permalink / raw) To: help-gnu-emacs Am 20.09.2013 22:59, schrieb Barry Margolin: > In article <mailman.2578.1379694764.10748.help-gnu-emacs@gnu.org>, > Andreas Röhler <andreas.roehler@easy-emacs.de> wrote: > >> Am 20.09.2013 17:10, schrieb Barry Margolin: >>> In article <mailman.2569.1379688787.10748.help-gnu-emacs@gnu.org>, >>> Andreas Röhler <andreas.roehler@easy-emacs.de> wrote: >>> >>>> Am 20.09.2013 14:30, schrieb Stefan Monnier: >>>>>> If I purposefully use a local dynamic variable as in: >>>>> >>>>> Use (defvar my-counter) at the file's top-level to indicate that this >>>>> variable is used in a way that relies on dynamic scoping. >>>> >>>> A need to write code just to silence compiler warnings? >>>> Emacs could do better. >>> >>> Other than "code", what would you suggest? >> >> In the precise case: just drop that warning. >> >> In a wider sense, IMO a modular approach is better. >> Restrict compiler warnings to obvious errors, don't mix style questions in. > > This isn't a style warning. Often the reason is mistyping a local > variable name. > > (let ((foobar ...)) > ... > (blah fobar) > ...) > This is another case. IIUC there was nothing wrong with the OP's example. ^ permalink raw reply [flat|nested] 46+ messages in thread
* Re: Declaring a local dynamic variable? 2013-09-20 20:59 ` Barry Margolin 2013-09-21 5:49 ` Andreas Röhler @ 2013-09-23 16:19 ` Joost Kremers [not found] ` <mailman.2622.1379742443.10748.help-gnu-emacs@gnu.org> 2 siblings, 0 replies; 46+ messages in thread From: Joost Kremers @ 2013-09-23 16:19 UTC (permalink / raw) To: help-gnu-emacs Barry Margolin wrote: > In article <mailman.2578.1379694764.10748.help-gnu-emacs@gnu.org>, > Andreas Röhler <andreas.roehler@easy-emacs.de> wrote: >> In a wider sense, IMO a modular approach is better. >> Restrict compiler warnings to obvious errors, don't mix style questions in. > > This isn't a style warning. Often the reason is mistyping a local > variable name. Yup (at least in my case it is...) Which is why I don't want to turn off this particular warning. -- Joost Kremers joostkremers@fastmail.fm Selbst in die Unterwelt dringt durch Spalten Licht EN:SiS(9) ^ permalink raw reply [flat|nested] 46+ messages in thread
[parent not found: <mailman.2622.1379742443.10748.help-gnu-emacs@gnu.org>]
* Re: Declaring a local dynamic variable? [not found] ` <mailman.2622.1379742443.10748.help-gnu-emacs@gnu.org> @ 2013-09-21 11:31 ` Barry Margolin 2013-09-21 13:32 ` Andreas Röhler [not found] ` <mailman.2638.1379770251.10748.help-gnu-emacs@gnu.org> 2013-09-23 16:26 ` Joost Kremers 1 sibling, 2 replies; 46+ messages in thread From: Barry Margolin @ 2013-09-21 11:31 UTC (permalink / raw) To: help-gnu-emacs [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #1: Type: text/plain, Size: 1948 bytes --] In article <mailman.2622.1379742443.10748.help-gnu-emacs@gnu.org>, Andreas Röhler <andreas.roehler@easy-emacs.de> wrote: > Am 20.09.2013 22:59, schrieb Barry Margolin: > > In article <mailman.2578.1379694764.10748.help-gnu-emacs@gnu.org>, > > Andreas Röhler <andreas.roehler@easy-emacs.de> wrote: > > > >> Am 20.09.2013 17:10, schrieb Barry Margolin: > >>> In article <mailman.2569.1379688787.10748.help-gnu-emacs@gnu.org>, > >>> Andreas Röhler <andreas.roehler@easy-emacs.de> wrote: > >>> > >>>> Am 20.09.2013 14:30, schrieb Stefan Monnier: > >>>>>> If I purposefully use a local dynamic variable as in: > >>>>> > >>>>> Use (defvar my-counter) at the file's top-level to indicate that this > >>>>> variable is used in a way that relies on dynamic scoping. > >>>> > >>>> A need to write code just to silence compiler warnings? > >>>> Emacs could do better. > >>> > >>> Other than "code", what would you suggest? > >> > >> In the precise case: just drop that warning. > >> > >> In a wider sense, IMO a modular approach is better. > >> Restrict compiler warnings to obvious errors, don't mix style questions in. > > > > This isn't a style warning. Often the reason is mistyping a local > > variable name. > > > > (let ((foobar ...)) > > ... > > (blah fobar) > > ...) > > > > This is another case. IIUC there was nothing wrong with the OP's example. But how is the compiler supposed to know the difference? Either it always warns, and generate false positives when you compile the user of a variable before loading the defvar, or never warns and there are false negatives when the user makes a typo. In this case, false positives are the better option, since you can easily silence them by adding a defvar. If the warning were removed, there's no way to get the warning when you actually do make a typo. -- Barry Margolin, barmar@alum.mit.edu Arlington, MA *** PLEASE post questions in newsgroups, not directly to me *** ^ permalink raw reply [flat|nested] 46+ messages in thread
* Re: Declaring a local dynamic variable? 2013-09-21 11:31 ` Barry Margolin @ 2013-09-21 13:32 ` Andreas Röhler [not found] ` <mailman.2638.1379770251.10748.help-gnu-emacs@gnu.org> 1 sibling, 0 replies; 46+ messages in thread From: Andreas Röhler @ 2013-09-21 13:32 UTC (permalink / raw) To: help-gnu-emacs Am 21.09.2013 13:31, schrieb Barry Margolin: > In article <mailman.2622.1379742443.10748.help-gnu-emacs@gnu.org>, > Andreas Röhler <andreas.roehler@easy-emacs.de> wrote: > >> Am 20.09.2013 22:59, schrieb Barry Margolin: >>> In article <mailman.2578.1379694764.10748.help-gnu-emacs@gnu.org>, >>> Andreas Röhler <andreas.roehler@easy-emacs.de> wrote: >>> >>>> Am 20.09.2013 17:10, schrieb Barry Margolin: >>>>> In article <mailman.2569.1379688787.10748.help-gnu-emacs@gnu.org>, >>>>> Andreas Röhler <andreas.roehler@easy-emacs.de> wrote: >>>>> >>>>>> Am 20.09.2013 14:30, schrieb Stefan Monnier: >>>>>>>> If I purposefully use a local dynamic variable as in: >>>>>>> >>>>>>> Use (defvar my-counter) at the file's top-level to indicate that this >>>>>>> variable is used in a way that relies on dynamic scoping. >>>>>> >>>>>> A need to write code just to silence compiler warnings? >>>>>> Emacs could do better. >>>>> >>>>> Other than "code", what would you suggest? >>>> >>>> In the precise case: just drop that warning. >>>> >>>> In a wider sense, IMO a modular approach is better. >>>> Restrict compiler warnings to obvious errors, don't mix style questions in. >>> >>> This isn't a style warning. Often the reason is mistyping a local >>> variable name. >>> >>> (let ((foobar ...)) >>> ... >>> (blah fobar) >>> ...) >>> >> >> This is another case. IIUC there was nothing wrong with the OP's example. > > But how is the compiler supposed to know the difference? A code-checker might look up, if a variable is defined. If our eyes may notice the difference, why a checker should not? Either it > always warns, and generate false positives when you compile the user of > a variable before loading the defvar, or never warns and there are false > negatives when the user makes a typo. > > In this case, false positives are the better option, since you can > easily silence them by adding a defvar. If the warning were removed, > there's no way to get the warning when you actually do make a typo. > Unfortunatly it's not the only occassion. Compiler message is cluttered with false positives that way. ^ permalink raw reply [flat|nested] 46+ messages in thread
[parent not found: <mailman.2638.1379770251.10748.help-gnu-emacs@gnu.org>]
* Re: Declaring a local dynamic variable? [not found] ` <mailman.2638.1379770251.10748.help-gnu-emacs@gnu.org> @ 2013-09-22 3:49 ` Barry Margolin 0 siblings, 0 replies; 46+ messages in thread From: Barry Margolin @ 2013-09-22 3:49 UTC (permalink / raw) To: help-gnu-emacs [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #1: Type: text/plain, Size: 2112 bytes --] In article <mailman.2638.1379770251.10748.help-gnu-emacs@gnu.org>, Andreas Röhler <andreas.roehler@easy-emacs.de> wrote: > Am 21.09.2013 13:31, schrieb Barry Margolin: > > In article <mailman.2622.1379742443.10748.help-gnu-emacs@gnu.org>, > > Andreas Röhler <andreas.roehler@easy-emacs.de> wrote: > > > >> Am 20.09.2013 22:59, schrieb Barry Margolin: > >>> In article <mailman.2578.1379694764.10748.help-gnu-emacs@gnu.org>, > >>> Andreas Röhler <andreas.roehler@easy-emacs.de> wrote: > >>> > >>>> Am 20.09.2013 17:10, schrieb Barry Margolin: > >>>>> In article <mailman.2569.1379688787.10748.help-gnu-emacs@gnu.org>, > >>>>> Andreas Röhler <andreas.roehler@easy-emacs.de> wrote: > >>>>> > >>>>>> Am 20.09.2013 14:30, schrieb Stefan Monnier: > >>>>>>>> If I purposefully use a local dynamic variable as in: > >>>>>>> > >>>>>>> Use (defvar my-counter) at the file's top-level to indicate that this > >>>>>>> variable is used in a way that relies on dynamic scoping. > >>>>>> > >>>>>> A need to write code just to silence compiler warnings? > >>>>>> Emacs could do better. > >>>>> > >>>>> Other than "code", what would you suggest? > >>>> > >>>> In the precise case: just drop that warning. > >>>> > >>>> In a wider sense, IMO a modular approach is better. > >>>> Restrict compiler warnings to obvious errors, don't mix style questions > >>>> in. > >>> > >>> This isn't a style warning. Often the reason is mistyping a local > >>> variable name. > >>> > >>> (let ((foobar ...)) > >>> ... > >>> (blah fobar) > >>> ...) > >>> > >> > >> This is another case. IIUC there was nothing wrong with the OP's example. > > > > But how is the compiler supposed to know the difference? > > A code-checker might look up, if a variable is defined. > If our eyes may notice the difference, why a checker should not? Look up where? How does it know you're going to load the package that declares the variable later? The warning doesn't happen if you've already loaded the package. -- Barry Margolin, barmar@alum.mit.edu Arlington, MA *** PLEASE post questions in newsgroups, not directly to me *** ^ permalink raw reply [flat|nested] 46+ messages in thread
* Re: Declaring a local dynamic variable? [not found] ` <mailman.2622.1379742443.10748.help-gnu-emacs@gnu.org> 2013-09-21 11:31 ` Barry Margolin @ 2013-09-23 16:26 ` Joost Kremers 2013-09-23 21:17 ` Barry Margolin 1 sibling, 1 reply; 46+ messages in thread From: Joost Kremers @ 2013-09-23 16:26 UTC (permalink / raw) To: help-gnu-emacs Andreas Röhler wrote: > Am 20.09.2013 22:59, schrieb Barry Margolin: >> This isn't a style warning. Often the reason is mistyping a local >> variable name. >> >> (let ((foobar ...)) >> ... >> (blah fobar) >> ...) >> > > This is another case. IIUC there was nothing wrong with the OP's example. Well, it would be great if the byte compiler could distinguish between the two cases, but apparently it's not. So I guess the question comes down to how easy/difficult would it be to implement a compiler that can? And is it worth the resources to develop one, as opposed to using that time & effort for some other feature? I cannot comment on the former (I know nothing about compilers apart from how to invoke them) but my suspicion is that the answer to the latter would tend towards "no". ;-) -- Joost Kremers joostkremers@fastmail.fm Selbst in die Unterwelt dringt durch Spalten Licht EN:SiS(9) ^ permalink raw reply [flat|nested] 46+ messages in thread
* Re: Declaring a local dynamic variable? 2013-09-23 16:26 ` Joost Kremers @ 2013-09-23 21:17 ` Barry Margolin 2013-09-23 22:14 ` Joost Kremers 0 siblings, 1 reply; 46+ messages in thread From: Barry Margolin @ 2013-09-23 21:17 UTC (permalink / raw) To: help-gnu-emacs [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #1: Type: text/plain, Size: 904 bytes --] In article <slrnl40qtk.31s.joostkremers@j.kremers4.news.arnhem.chello.nl>, Joost Kremers <joostkremers@yahoo.com> wrote: > Andreas Röhler wrote: > > Am 20.09.2013 22:59, schrieb Barry Margolin: > >> This isn't a style warning. Often the reason is mistyping a local > >> variable name. > >> > >> (let ((foobar ...)) > >> ... > >> (blah fobar) > >> ...) > >> > > > > This is another case. IIUC there was nothing wrong with the OP's example. > > Well, it would be great if the byte compiler could distinguish between > the two cases, but apparently it's not. So I guess the question comes > down to how easy/difficult would it be to implement a compiler that can? On what basis would it distinguish them? Search all packages to see if any of them declare the variable? -- Barry Margolin, barmar@alum.mit.edu Arlington, MA *** PLEASE post questions in newsgroups, not directly to me *** ^ permalink raw reply [flat|nested] 46+ messages in thread
* Re: Declaring a local dynamic variable? 2013-09-23 21:17 ` Barry Margolin @ 2013-09-23 22:14 ` Joost Kremers 2013-09-24 0:03 ` Barry Margolin 0 siblings, 1 reply; 46+ messages in thread From: Joost Kremers @ 2013-09-23 22:14 UTC (permalink / raw) To: help-gnu-emacs Barry Margolin wrote: > In article > <slrnl40qtk.31s.joostkremers@j.kremers4.news.arnhem.chello.nl>, > Joost Kremers <joostkremers@yahoo.com> wrote: >> Well, it would be great if the byte compiler could distinguish between >> the two cases, but apparently it's not. So I guess the question comes >> down to how easy/difficult would it be to implement a compiler that can? > > On what basis would it distinguish them? Search all packages to see if > any of them declare the variable? I realise that's a rhetorical question, but that wouldn't be a very good idea. Suppose you mistype a local variable and some package happens to define a dynamic variable with the misspelled name... Personally, I'd prefer to declare such a variable explicitly, not only because of the compiler but also because it tells a human reading the code that they're looking at a dynamic variable. -- Joost Kremers joostkremers@fastmail.fm Selbst in die Unterwelt dringt durch Spalten Licht EN:SiS(9) ^ permalink raw reply [flat|nested] 46+ messages in thread
* Re: Declaring a local dynamic variable? 2013-09-23 22:14 ` Joost Kremers @ 2013-09-24 0:03 ` Barry Margolin 2013-09-25 8:58 ` Joost Kremers 0 siblings, 1 reply; 46+ messages in thread From: Barry Margolin @ 2013-09-24 0:03 UTC (permalink / raw) To: help-gnu-emacs In article <slrnl41f9g.31s.joostkremers@j.kremers4.news.arnhem.chello.nl>, Joost Kremers <joostkremers@yahoo.com> wrote: > Barry Margolin wrote: > > In article > > <slrnl40qtk.31s.joostkremers@j.kremers4.news.arnhem.chello.nl>, > > Joost Kremers <joostkremers@yahoo.com> wrote: > >> Well, it would be great if the byte compiler could distinguish between > >> the two cases, but apparently it's not. So I guess the question comes > >> down to how easy/difficult would it be to implement a compiler that can? > > > > On what basis would it distinguish them? Search all packages to see if > > any of them declare the variable? > > I realise that's a rhetorical question, but that wouldn't be a very good Maybe the second one is slightly rhetorical, but the first certainly wasn't. The difficulty isn't in implementation, it's in defining what you mean by "a compiler that can". You can't implement something without a specification of what it's supposed to do, and "do the right thing" is not really detailed enough. > idea. Suppose you mistype a local variable and some package happens to > define a dynamic variable with the misspelled name... That would be pretty unlikely, considering that package developers are strongly encouraged to follow naming conventions. All the global variables in a package should be prefixed with something identifying the package (some programmers copy CL-style package:XXX naming, some use package-XXX). On the other hand, most programmers tend to use relatively short names for local variables. The chance that a typo will happen to match one of those prefixed variables is -- Barry Margolin, barmar@alum.mit.edu Arlington, MA *** PLEASE post questions in newsgroups, not directly to me *** ^ permalink raw reply [flat|nested] 46+ messages in thread
* Re: Declaring a local dynamic variable? 2013-09-24 0:03 ` Barry Margolin @ 2013-09-25 8:58 ` Joost Kremers 0 siblings, 0 replies; 46+ messages in thread From: Joost Kremers @ 2013-09-25 8:58 UTC (permalink / raw) To: help-gnu-emacs Barry Margolin wrote: > In article > <slrnl41f9g.31s.joostkremers@j.kremers4.news.arnhem.chello.nl>, > Joost Kremers <joostkremers@yahoo.com> wrote: > >> Barry Margolin wrote: >> > In article >> > <slrnl40qtk.31s.joostkremers@j.kremers4.news.arnhem.chello.nl>, >> > Joost Kremers <joostkremers@yahoo.com> wrote: >> >> Well, it would be great if the byte compiler could distinguish between >> >> the two cases, but apparently it's not. So I guess the question comes >> >> down to how easy/difficult would it be to implement a compiler that can? >> > >> > On what basis would it distinguish them? Search all packages to see if >> > any of them declare the variable? >> >> I realise that's a rhetorical question, but that wouldn't be a very good > > Maybe the second one is slightly rhetorical, but the first certainly > wasn't. The difficulty isn't in implementation, it's in defining what > you mean by "a compiler that can". You can't implement something without > a specification of what it's supposed to do, and "do the right thing" is > not really detailed enough. That was basically what I was trying to say, though I may not have made myself clear. In order to implement a compiler that can distinguish between variable names that are used for dynamic bindings and variable names with typos, you first need to figure out how the two can be distuinguished without human intervention, and then decide how much of that you want to implement. -- Joost Kremers joostkremers@fastmail.fm Selbst in die Unterwelt dringt durch Spalten Licht EN:SiS(9) ^ permalink raw reply [flat|nested] 46+ messages in thread
* Re: Declaring a local dynamic variable? 2013-09-20 9:52 Declaring a local dynamic variable? Joost Kremers 2013-09-20 12:30 ` Stefan Monnier @ 2013-09-22 17:11 ` Pascal J. Bourguignon 2013-09-23 16:17 ` Joost Kremers ` (3 more replies) [not found] ` <mailman.2566.1379680283.10748.help-gnu-emacs@gnu.org> 2 siblings, 4 replies; 46+ messages in thread From: Pascal J. Bourguignon @ 2013-09-22 17:11 UTC (permalink / raw) To: help-gnu-emacs Joost Kremers <joostkremers@yahoo.com> writes: > Hi, > > If I purposefully use a local dynamic variable as in: > > (defun foo () > (let* ((my-counter 0) > (var (or (bar 'one) > (bar 'two) > (bar 'three)))) > (do-something-with var) > (issue-a-message-depending-on-the-value-of my-counter))) > > (defun bar (arg) > (setq my-counter (1+ my-counter)) > (do-something-with arg) > (and-return-result)) > > the byte compiler will issue a warning about referring to a free > variable in `bar'. What is the proper way of letting the byte compiler > know that it shouldn't worry about this particular variable, without > silencing it completely? I don't want to disable all warnings, or even > just the warnings about free variables. > > Right now, I'm using a `(defvar my-counter)' inside the function > definition of `bar', but that looks a bit strange. Is there a better or > "more proper" way of doing this? CL has the (declare (special var…)) declaration for that. (defun f () (declare (special var)) (print var)) (defun g () (let ((var 42)) (declare (special var)) (f))) (g) ; prints 42. (defun h () (let ((var 33)) ; lexical variable (g))) (h) ; prints 42 To implement that in emacs lisp, you could define defun, let, let* and locally in a separate package, oops, no package in emacs. To implement that in emacs lisp, you could define defun@, let@, let*@ and locally@ as macros that will check for the special declarations and define the variables as symbol-macrolets expanding to (symbol-value 'variable), and that save the old symbol-value and restore it. Something like: (defun split-declarations (body) (loop for b on body while (and (listp (car b)) (eq 'declare (caar b))) append (cdar b) into declarations finally (return (list declarations b)))) (assert (equal (split-declarations '((declare (special a b)) (declare (integer a) (character b)) (declare (special c)) (print a))) '(((special a b) (integer a) (character b) (special c)) ((print a))))) (defun split-bindings (bindings) (list (mapcar (lambda (b) (cond ((symbolp b) b) ((or (atom b) (cddr b)) (error "Invalid binding: %S -- a binding should be a symbol or a list of two elements, a symbol and an expression." b)) (t (first b)))) bindings) (mapcar (lambda (b) (if (atom b) nil (second b))) bindings))) (assert (equal (split-bindings '(a (b 42) (c d))) '((a b c) (nil 42 d)))) (defun split-special-variables (declarations) (loop for decl in declarations if (eq 'special (car decl)) append (cdr decl) into specials else collect decl into other-decls finally (return (list specials other-decls)))) (assert (equal (split-special-variables (first (split-declarations '((declare (special a b)) (declare (integer a) (character b)) (declare (special c)) (print a))))) '((a b c) ((integer a) (character b))))) (defvar *unbound* (list 'unbound)) (defun special-bind@ (var val expression) (let ((save (gensym))) `(let ((,save (if (boundp ',var) (symbol-value ',var) *unbound*))) (unwind-protect (symbol-macrolet ((,var (symbol-value ',var))) (setf (symbol-value ',var) ,val) ,expression) (if (eq ,save *unbound*) (makunbound ',var) (setf (symbol-value ',var) ,save)))))) (defun lexical-bind@ (var val expression) `(let ((,var ,val) ,expression))) (defun bind@ (specials vars vals expression) (if (null vars) expression (bind@ specials (cdr vars) (cdr vals) (if (member (car vars) specials) (special-bind@ (car vars) (car vals) expression) (lexical-bind@ (car vars) (car vals) expression))))) (defmacro let@ (bindings &rest body) (destructuring-bind (vars vals) (split-bindings bindings) (destructuring-bind (declarations body) (split-declarations body) (destructuring-bind (special-variables declarations) (split-special-variables declarations) (let ((temps (mapcar (lambda (var) (declare (ignore var)) (gensym)) vars))) `(let ,(mapcar* (function list) temps vals) ,(bind@ special-variables (nreverse vars) (nreverse temps) `(progn ,@body)))))))) (defun specially@ (vars expression) `(symbol-macrolet ,(mapcar (lambda (var) `(,var (symbol-value ',var))) vars) ,expression)) (defmacro locally@ (&rest body) (destructuring-bind (declarations body) (split-declarations body) (message "d=%S b=%S" declarations body) (destructuring-bind (special-variables declarations) (split-special-variables declarations) (message "s=%S d=%S" special-variables declarations) (specially@ special-variables (if declarations `(locally (declare ,@declarations) ,@body) `(progn ,@body)))))) (defun f () (locally@ (declare (special x)) (print x))) (defun g () (let@ ((x 42)) (declare (special x)) (f))) (g) prints: 42 --> 42 (defun h () (let@ ((var 33)) ; lexical variable (g))) (h) prints:42 --> nil ; where does this come from? Is there a bug in emacs-version "24.2.1"? For defun@, one would have to take care of special declarations for parameters, and splitting docstrings from declarations and body. -- __Pascal Bourguignon__ http://www.informatimago.com/ ^ permalink raw reply [flat|nested] 46+ messages in thread
* Re: Declaring a local dynamic variable? 2013-09-22 17:11 ` Pascal J. Bourguignon @ 2013-09-23 16:17 ` Joost Kremers 2013-09-24 21:40 ` Stefan Monnier ` (2 subsequent siblings) 3 siblings, 0 replies; 46+ messages in thread From: Joost Kremers @ 2013-09-23 16:17 UTC (permalink / raw) To: help-gnu-emacs Pascal J. Bourguignon wrote: > Joost Kremers <joostkremers@yahoo.com> writes: >> If I purposefully use a local dynamic variable as in: > > CL has the (declare (special var…)) declaration for that. Yeah, I was wondering if there was something similar for Elisp. > To implement that in emacs lisp, you could define defun, let, let* and > locally in a separate package, oops, no package in emacs. Something that will hopefully be remedied one day. :-) > To implement that in emacs lisp, you could define defun@, let@, > let*@ and locally@ as macros that will check for the special > declarations and define the variables as symbol-macrolets expanding to > (symbol-value 'variable), and that save the old symbol-value and restore > it. Something like: Erm, I believe you. :-) I'm afraid I don't have the time to go through your code and grok it fully, but I'm duly impressed. -- Joost Kremers joostkremers@fastmail.fm Selbst in die Unterwelt dringt durch Spalten Licht EN:SiS(9) ^ permalink raw reply [flat|nested] 46+ messages in thread
* Re: Declaring a local dynamic variable? 2013-09-22 17:11 ` Pascal J. Bourguignon 2013-09-23 16:17 ` Joost Kremers @ 2013-09-24 21:40 ` Stefan Monnier 2013-11-02 23:56 ` WJ 2013-11-03 1:42 ` WJ 3 siblings, 0 replies; 46+ messages in thread From: Stefan Monnier @ 2013-09-24 21:40 UTC (permalink / raw) To: help-gnu-emacs > CL has the (declare (special var…)) declaration for that. And cl.el does provide some support for it, indeed. > (defun f () > (declare (special var)) > (print var)) Since Elisp's `defun' macro also supports `declare', we could provide support for the above, tho you can just as well write it as (defun f () (defvar var) (print var)) > (let ((var 42)) > (declare (special var)) > (f))) Supporting for byte-compiled files would be fairly easy, but when interpreting code it it would be very costly, so Elisp does not support this. With Emacs-24.3's eager macro-expansion the cost would be a lot more reasonable, but I still don't find it worth the trouble. Instead you have to write: (defvar var) (let ((var 42)) (f))) -- Stefan ^ permalink raw reply [flat|nested] 46+ messages in thread
* Re: Declaring a local dynamic variable? 2013-09-22 17:11 ` Pascal J. Bourguignon 2013-09-23 16:17 ` Joost Kremers 2013-09-24 21:40 ` Stefan Monnier @ 2013-11-02 23:56 ` WJ 2013-11-03 1:42 ` WJ 3 siblings, 0 replies; 46+ messages in thread From: WJ @ 2013-11-02 23:56 UTC (permalink / raw) To: help-gnu-emacs Pascal J. Bourguignon wrote: > > (defun split-declarations (body) > (loop > for b on body > while (and (listp (car b)) (eq 'declare (caar b))) > append (cdar b) into declarations > finally (return (list declarations b)))) (defun split-declarations (body &optional decs) (while (and (listp (car body)) (eq 'declare (caar body))) (setq decs (nconc decs (cdr (pop body))))) (list decs body)) ^ permalink raw reply [flat|nested] 46+ messages in thread
* Re: Declaring a local dynamic variable? 2013-09-22 17:11 ` Pascal J. Bourguignon ` (2 preceding siblings ...) 2013-11-02 23:56 ` WJ @ 2013-11-03 1:42 ` WJ 3 siblings, 0 replies; 46+ messages in thread From: WJ @ 2013-11-03 1:42 UTC (permalink / raw) To: help-gnu-emacs Pascal J. Bourguignon wrote: > (defun split-special-variables (declarations) > (loop > for decl in declarations > if (eq 'special (car decl)) > append (cdr decl) into specials > else > collect decl into other-decls > finally (return (list specials other-decls)))) (defun split-special-variables (declarations) (let (specials others) (dolist (x declarations) (if (eq 'special (car x)) (setq specials (nconc specials (cdr x))) (push x others))) (list specials others))) ^ permalink raw reply [flat|nested] 46+ messages in thread
[parent not found: <mailman.2566.1379680283.10748.help-gnu-emacs@gnu.org>]
* Re: Declaring a local dynamic variable? [not found] ` <mailman.2566.1379680283.10748.help-gnu-emacs@gnu.org> @ 2013-09-23 16:11 ` Joost Kremers 2013-09-24 21:34 ` Stefan Monnier 0 siblings, 1 reply; 46+ messages in thread From: Joost Kremers @ 2013-09-23 16:11 UTC (permalink / raw) To: help-gnu-emacs Stefan Monnier wrote: >> If I purposefully use a local dynamic variable as in: > > Use (defvar my-counter) at the file's top-level to indicate that this > variable is used in a way that relies on dynamic scoping. Is that preferable to putting the defvar inside the function definition where the variable is used dynamically? -- Joost Kremers joostkremers@fastmail.fm Selbst in die Unterwelt dringt durch Spalten Licht EN:SiS(9) ^ permalink raw reply [flat|nested] 46+ messages in thread
* Re: Declaring a local dynamic variable? 2013-09-23 16:11 ` Joost Kremers @ 2013-09-24 21:34 ` Stefan Monnier 2013-09-25 5:52 ` Andreas Röhler 2013-09-25 8:43 ` Joost Kremers 0 siblings, 2 replies; 46+ messages in thread From: Stefan Monnier @ 2013-09-24 21:34 UTC (permalink / raw) To: help-gnu-emacs >>> If I purposefully use a local dynamic variable as in: >> Use (defvar my-counter) at the file's top-level to indicate that this >> variable is used in a way that relies on dynamic scoping. > Is that preferable to putting the defvar inside the function definition > where the variable is used dynamically? Depends, but usually I recommend you put the defvar at top-level, otherwise you have to put it at various places (everywhere it's let-bound and everywhere where it's referenced). Also, I strongly recommend those dynamically-scoped vars use a package prefix, just like global variables (since they are fundamentally global variables). Stefan ^ permalink raw reply [flat|nested] 46+ messages in thread
* Re: Declaring a local dynamic variable? 2013-09-24 21:34 ` Stefan Monnier @ 2013-09-25 5:52 ` Andreas Röhler 2013-09-25 7:24 ` Stefan Monnier 2013-09-25 8:43 ` Joost Kremers 1 sibling, 1 reply; 46+ messages in thread From: Andreas Röhler @ 2013-09-25 5:52 UTC (permalink / raw) To: help-gnu-emacs Am 24.09.2013 23:34, schrieb Stefan Monnier: > Also, I strongly recommend those dynamically-scoped vars use a package > prefix, just like global variables (since they are fundamentally global > variables). > Wherewith the bottom of things is reached. IMO proceeding that way takes the advantage of let-bound dynamic vars, being introduced locally as quick and reliable. Why not change to Java right away than? ^ permalink raw reply [flat|nested] 46+ messages in thread
* Re: Declaring a local dynamic variable? 2013-09-25 5:52 ` Andreas Röhler @ 2013-09-25 7:24 ` Stefan Monnier 0 siblings, 0 replies; 46+ messages in thread From: Stefan Monnier @ 2013-09-25 7:24 UTC (permalink / raw) To: help-gnu-emacs > IMO proceeding that way takes the advantage of let-bound dynamic vars, > being introduced locally as quick and reliable. ^^^^^^^^ Haha! Stefan ^ permalink raw reply [flat|nested] 46+ messages in thread
* Re: Declaring a local dynamic variable? 2013-09-24 21:34 ` Stefan Monnier 2013-09-25 5:52 ` Andreas Röhler @ 2013-09-25 8:43 ` Joost Kremers 2013-09-25 12:26 ` Stefan Monnier [not found] ` <mailman.2843.1380112007.10748.help-gnu-emacs@gnu.org> 1 sibling, 2 replies; 46+ messages in thread From: Joost Kremers @ 2013-09-25 8:43 UTC (permalink / raw) To: help-gnu-emacs Stefan Monnier wrote: > Also, I strongly recommend those dynamically-scoped vars use a package > prefix, Yeah, the byte compiler already told me that. > just like global variables (since they are fundamentally global > variables). So in essence Emacs doesn't really have local dynamic variables? Just local dynamic bindings? -- Joost Kremers joostkremers@fastmail.fm Selbst in die Unterwelt dringt durch Spalten Licht EN:SiS(9) ^ permalink raw reply [flat|nested] 46+ messages in thread
* Re: Declaring a local dynamic variable? 2013-09-25 8:43 ` Joost Kremers @ 2013-09-25 12:26 ` Stefan Monnier 2013-10-12 16:54 ` Andreas Röhler [not found] ` <mailman.3886.1381596756.10748.help-gnu-emacs@gnu.org> [not found] ` <mailman.2843.1380112007.10748.help-gnu-emacs@gnu.org> 1 sibling, 2 replies; 46+ messages in thread From: Stefan Monnier @ 2013-09-25 12:26 UTC (permalink / raw) To: help-gnu-emacs > So in essence Emacs doesn't really have local dynamic variables? Dynamic scoping is inherently global, whether in Elisp or in any other language. To make it "cleanly local" you need to rely on namespaces/modules to protect uses in one package from interfering from uses in other package. In Emacs, we use name prefixes as poor man's namespaces. Stefan ^ permalink raw reply [flat|nested] 46+ messages in thread
* Re: Declaring a local dynamic variable? 2013-09-25 12:26 ` Stefan Monnier @ 2013-10-12 16:54 ` Andreas Röhler [not found] ` <mailman.3886.1381596756.10748.help-gnu-emacs@gnu.org> 1 sibling, 0 replies; 46+ messages in thread From: Andreas Röhler @ 2013-10-12 16:54 UTC (permalink / raw) To: help-gnu-emacs Am 25.09.2013 14:26, schrieb Stefan Monnier: >> So in essence Emacs doesn't really have local dynamic variables? > > Dynamic scoping is inherently global, Reads like a mistake for me. What about saying scope and art-of-binding are unrelated? Please consider the following (defvar a nil) (setq a 2) (defun foo (&optional a) (let ((a (or a 0))) (message "%d" a) (bar))) (defun bar () (setq a 1)) (foo)-> 0 1 ;; setq a 1 worked, because of dynamic binding at a local var a-> 2 Global a is not affected, because of the let-binding, which is obviously not global. ^ permalink raw reply [flat|nested] 46+ messages in thread
[parent not found: <mailman.3886.1381596756.10748.help-gnu-emacs@gnu.org>]
* Re: Declaring a local dynamic variable? [not found] ` <mailman.3886.1381596756.10748.help-gnu-emacs@gnu.org> @ 2013-10-12 21:25 ` Kai Grossjohann 2013-10-13 8:12 ` Andreas Röhler 0 siblings, 1 reply; 46+ messages in thread From: Kai Grossjohann @ 2013-10-12 21:25 UTC (permalink / raw) To: help-gnu-emacs On Saturday, October 12, 2013 6:54:40 PM UTC+2, Andreas Röhler wrote: > Am 25.09.2013 14:26, schrieb Stefan Monnier: > > >> So in essence Emacs doesn't really have local dynamic variables? > > > Dynamic scoping is inherently global, > > Reads like a mistake for me. I think it makes sense. In a language that has lexical scoping, you can get the effect of dynamic scoping by changing the value of a global variable. (defvar x 5) bla bla (let ((x 6)) yadda yadda) mumble mumble The above code has the same effect as - create global variable x, initialize it to 5 - execute bla bla - change value of x to 6 - execute yadda yadda - change value of x back to 5 - execute mumble mumble But dynamically-scoped let has the advantage that it remembers the old value for you, and it catches all ways that the "yadda yadda" might exit. ^ permalink raw reply [flat|nested] 46+ messages in thread
* Re: Declaring a local dynamic variable? 2013-10-12 21:25 ` Kai Grossjohann @ 2013-10-13 8:12 ` Andreas Röhler 2013-10-13 13:37 ` Stefan Monnier 0 siblings, 1 reply; 46+ messages in thread From: Andreas Röhler @ 2013-10-13 8:12 UTC (permalink / raw) To: help-gnu-emacs Am 12.10.2013 23:25, schrieb Kai Grossjohann: > On Saturday, October 12, 2013 6:54:40 PM UTC+2, Andreas Röhler wrote: >> Am 25.09.2013 14:26, schrieb Stefan Monnier: >> >>>> So in essence Emacs doesn't really have local dynamic variables? >> >>> Dynamic scoping is inherently global, >> >> Reads like a mistake for me. > > I think it makes sense. In a language that has lexical scoping, you can get the effect of dynamic scoping by changing the value of a global variable. > > (defvar x 5) > bla bla > (let ((x 6)) > yadda yadda) > mumble mumble > > The above code has the same effect as > - create global variable x, initialize it to 5 > - execute bla bla > - change value of x to 6 No. Introduces a let-bound x, which is unrelated to global x dynamical-scoped let-bound behave different than lexical-scoped let-bound vars, that's at stake. If a global var of the same name exists or not is another issue. Therefor consider it a misuse and design-flaw to use "defvar" signaling dynamic-scope in let-bound vars. "defvar" initialised a global var. Never was related to stuff inside let. At least not at the Emacs Lisp symbol-level. > - execute yadda yadda > - change value of x back to 5 > - execute mumble mumble > > But dynamically-scoped let has the advantage that it remembers the old value for you, and it catches all ways that the "yadda yadda" might exit. > ^ permalink raw reply [flat|nested] 46+ messages in thread
* Re: Declaring a local dynamic variable? 2013-10-13 8:12 ` Andreas Röhler @ 2013-10-13 13:37 ` Stefan Monnier 2013-10-13 17:41 ` Andreas Röhler 0 siblings, 1 reply; 46+ messages in thread From: Stefan Monnier @ 2013-10-13 13:37 UTC (permalink / raw) To: help-gnu-emacs >> The above code has the same effect as >> - create global variable x, initialize it to 5 >> - execute bla bla >> - change value of x to 6 > No. Introduces a let-bound x, which is unrelated to global x You're confused. Take a look at how `let' works inside Emacs, for example. It does exactly what Kai suggests, i.e. the equivalent of: - stash value of `x' on a stack (called specpdl in Emacs's C code). - set `x' to the new value - run the let's body - go fetch the old value of `x' on the stack and restore it. The real story is more complicated because the old value stashed on the stack includes the information about whether `x' was already defined or not, and more importantly because variables can be buffer-local, so it needs also to remember which buffer's value was modified and only restore `x' for that buffer. Stefan ^ permalink raw reply [flat|nested] 46+ messages in thread
* Re: Declaring a local dynamic variable? 2013-10-13 13:37 ` Stefan Monnier @ 2013-10-13 17:41 ` Andreas Röhler 2013-10-13 19:56 ` Kai Großjohann 0 siblings, 1 reply; 46+ messages in thread From: Andreas Röhler @ 2013-10-13 17:41 UTC (permalink / raw) To: help-gnu-emacs Am 13.10.2013 15:37, schrieb Stefan Monnier: >>> The above code has the same effect as >>> - create global variable x, initialize it to 5 >>> - execute bla bla >>> - change value of x to 6 >> No. Introduces a let-bound x, which is unrelated to global x > > You're confused. Really? So that's what I get: (defvar x 5) x->5 (let ((x 6)) x) ->6 (#o6, #x6, ?\C-f) x->5 GNU Emacs 24.3.50.1 (i686-pc-linux-gnu, GTK+ Version 2.24.10) of 2013-08-28 [ ... ] > The real story is more complicated because the old value stashed on the > stack includes the information about whether `x' was already defined or > not, Sure it's more complicated. We are taking about the use of symbols at Emacs Lisp level, not about internals. BTW I'm not blaming anybody because something went wrong. Just saying: let's correct it. Best, Andreas and more importantly because variables can be buffer-local, so it > needs also to remember which buffer's value was modified and only restore > `x' for that buffer. > > > Stefan > > > ^ permalink raw reply [flat|nested] 46+ messages in thread
* Re: Declaring a local dynamic variable? 2013-10-13 17:41 ` Andreas Röhler @ 2013-10-13 19:56 ` Kai Großjohann 0 siblings, 0 replies; 46+ messages in thread From: Kai Großjohann @ 2013-10-13 19:56 UTC (permalink / raw) To: Andreas Röhler; +Cc: help-gnu-emacs Andreas Röhler wrote: > Am 13.10.2013 15:37, schrieb Stefan Monnier: >>>> The above code has the same effect as >>>> - create global variable x, initialize it to 5 >>>> - execute bla bla >>>> - change value of x to 6 >>> No. Introduces a let-bound x, which is unrelated to global x >> >> You're confused. > > Really? > > So that's what I get: > > (defvar x 5) > x->5 > > (let ((x 6)) > x) > > ->6 (#o6, #x6, ?\C-f) This observation can be explained in two ways: - Either you have a new variable x with a new value. (This is what you are talking about.) - Or you have a new value for the existing variable x. (This is what Stefan and I are talking about.) Let's say you have this code: (defvar x 5) (defun foo () (+ x 3)) It seems that we can say that the function foo accesses the global variable x. Now we write this: (let ((x 6)) (foo)) Under Stefan's and my explanation, we can still say that the function foo accesses the global variable x -- it just has a different value here. Under your explanation, we would need to say that foo doesn't access the global variable x anymore, instead it accesses a different variable x. Kai ^ permalink raw reply [flat|nested] 46+ messages in thread
[parent not found: <mailman.2843.1380112007.10748.help-gnu-emacs@gnu.org>]
* Re: Declaring a local dynamic variable? [not found] ` <mailman.2843.1380112007.10748.help-gnu-emacs@gnu.org> @ 2013-09-25 15:46 ` Barry Margolin 2013-09-25 18:53 ` Stefan Monnier [not found] ` <mailman.2873.1380135245.10748.help-gnu-emacs@gnu.org> 0 siblings, 2 replies; 46+ messages in thread From: Barry Margolin @ 2013-09-25 15:46 UTC (permalink / raw) To: help-gnu-emacs In article <mailman.2843.1380112007.10748.help-gnu-emacs@gnu.org>, Stefan Monnier <monnier@iro.umontreal.ca> wrote: > > So in essence Emacs doesn't really have local dynamic variables? > > Dynamic scoping is inherently global, whether in Elisp or in any other > language. Not in Common Lisp. (defun d1 () (let ((var 1)) (declare (special var)) (l1))) (defun l1 () (let ((var 2)) (print var) (d2))) (defun d2 () (declare (special var)) (print var)) D1 and D2 use the dynamic variable VAR, L1 uses the lexical variable VAR. -- Barry Margolin, barmar@alum.mit.edu Arlington, MA *** PLEASE post questions in newsgroups, not directly to me *** ^ permalink raw reply [flat|nested] 46+ messages in thread
* Re: Declaring a local dynamic variable? 2013-09-25 15:46 ` Barry Margolin @ 2013-09-25 18:53 ` Stefan Monnier 2013-09-27 9:53 ` Andreas Röhler [not found] ` <mailman.2982.1380275511.10748.help-gnu-emacs@gnu.org> [not found] ` <mailman.2873.1380135245.10748.help-gnu-emacs@gnu.org> 1 sibling, 2 replies; 46+ messages in thread From: Stefan Monnier @ 2013-09-25 18:53 UTC (permalink / raw) To: help-gnu-emacs >> > So in essence Emacs doesn't really have local dynamic variables? >> Dynamic scoping is inherently global, whether in Elisp or in any other >> language. > Not in Common Lisp. > (defun d1 () > (let ((var 1)) > (declare (special var)) > (l1))) > (defun l1 () > (let ((var 2)) > (print var) > (d2))) > (defun d2 () > (declare (special var)) > (print var)) > D1 and D2 use the dynamic variable VAR, L1 uses the lexical variable VAR. Same in Elisp. But if d1 and d2 are in two separate packages that know nothing about each other but who happen to call each other through some potentially twisted sequence of calls, they will still interfere, because there's only (globally) one dynamic variable by that name. Stefan ^ permalink raw reply [flat|nested] 46+ messages in thread
* Re: Declaring a local dynamic variable? 2013-09-25 18:53 ` Stefan Monnier @ 2013-09-27 9:53 ` Andreas Röhler 2013-09-27 13:15 ` Stefan Monnier [not found] ` <mailman.2982.1380275511.10748.help-gnu-emacs@gnu.org> 1 sibling, 1 reply; 46+ messages in thread From: Andreas Röhler @ 2013-09-27 9:53 UTC (permalink / raw) To: help-gnu-emacs Am 25.09.2013 20:53, schrieb Stefan Monnier: >>>> So in essence Emacs doesn't really have local dynamic variables? >>> Dynamic scoping is inherently global, whether in Elisp or in any other >>> language. > >> Not in Common Lisp. > >> (defun d1 () >> (let ((var 1)) >> (declare (special var)) >> (l1))) > >> (defun l1 () >> (let ((var 2)) >> (print var) >> (d2))) > >> (defun d2 () >> (declare (special var)) >> (print var)) > >> D1 and D2 use the dynamic variable VAR, L1 uses the lexical variable VAR. > > Same in Elisp. But if d1 and d2 are in two separate packages that know > nothing about each other but who happen to call each other through some > potentially twisted sequence of calls, they will still interfere, > because there's only (globally) one dynamic variable by that name. > Now if two separate packages define a lexical var with the very same, is such a confusion excluded? ^ permalink raw reply [flat|nested] 46+ messages in thread
* Re: Declaring a local dynamic variable? 2013-09-27 9:53 ` Andreas Röhler @ 2013-09-27 13:15 ` Stefan Monnier 0 siblings, 0 replies; 46+ messages in thread From: Stefan Monnier @ 2013-09-27 13:15 UTC (permalink / raw) To: help-gnu-emacs >> Same in Elisp. But if d1 and d2 are in two separate packages that know >> nothing about each other but who happen to call each other through some >> potentially twisted sequence of calls, they will still interfere, >> because there's only (globally) one dynamic variable by that name. > Now if two separate packages define a lexical var with the very same, > is such a confusion excluded? Of course. Stefan ^ permalink raw reply [flat|nested] 46+ messages in thread
[parent not found: <mailman.2982.1380275511.10748.help-gnu-emacs@gnu.org>]
* Re: Declaring a local dynamic variable? [not found] ` <mailman.2982.1380275511.10748.help-gnu-emacs@gnu.org> @ 2013-09-27 14:31 ` Barry Margolin 2013-09-27 18:48 ` Andreas Röhler [not found] ` <mailman.3016.1380307597.10748.help-gnu-emacs@gnu.org> 0 siblings, 2 replies; 46+ messages in thread From: Barry Margolin @ 2013-09-27 14:31 UTC (permalink / raw) To: help-gnu-emacs [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #1: Type: text/plain, Size: 1845 bytes --] In article <mailman.2982.1380275511.10748.help-gnu-emacs@gnu.org>, Andreas Röhler <andreas.roehler@easy-emacs.de> wrote: > Am 25.09.2013 20:53, schrieb Stefan Monnier: > >>>> So in essence Emacs doesn't really have local dynamic variables? > >>> Dynamic scoping is inherently global, whether in Elisp or in any other > >>> language. > > > >> Not in Common Lisp. > > > >> (defun d1 () > >> (let ((var 1)) > >> (declare (special var)) > >> (l1))) > > > >> (defun l1 () > >> (let ((var 2)) > >> (print var) > >> (d2))) > > > >> (defun d2 () > >> (declare (special var)) > >> (print var)) > > > >> D1 and D2 use the dynamic variable VAR, L1 uses the lexical variable VAR. > > > > Same in Elisp. But if d1 and d2 are in two separate packages that know > > nothing about each other but who happen to call each other through some > > potentially twisted sequence of calls, they will still interfere, > > because there's only (globally) one dynamic variable by that name. > > > > Now if two separate packages define a lexical var with the very same, is such > a confusion excluded? Yes. By definition, lexical variables are only visible in the lexical contour, not in other functions. The exception is if a macro expands into code that binds the variable: (defmacro pkg1-m (&body b) `(let ((var 'm)) ,@b)) (defun pkg2-f () (let ((var 'f)) (pkg1-m (print var)))) (pkg2-f) will print "m" rather than "f". This is generally referred to as the "hygiene" problem in macros. It's why macros should use gensym to create the local variables used in the expansion, or take the variable as a parameter. Dialects like Scheme have built-in mechanisms to create hygienic macros. -- Barry Margolin, barmar@alum.mit.edu Arlington, MA *** PLEASE post questions in newsgroups, not directly to me *** ^ permalink raw reply [flat|nested] 46+ messages in thread
* Re: Declaring a local dynamic variable? 2013-09-27 14:31 ` Barry Margolin @ 2013-09-27 18:48 ` Andreas Röhler [not found] ` <mailman.3016.1380307597.10748.help-gnu-emacs@gnu.org> 1 sibling, 0 replies; 46+ messages in thread From: Andreas Röhler @ 2013-09-27 18:48 UTC (permalink / raw) To: help-gnu-emacs@gnu.org List Am 27.09.2013 16:31, schrieb Barry Margolin: > In article <mailman.2982.1380275511.10748.help-gnu-emacs@gnu.org>, > Andreas Röhler <andreas.roehler@easy-emacs.de> wrote: > >> Am 25.09.2013 20:53, schrieb Stefan Monnier: >>>>>> So in essence Emacs doesn't really have local dynamic variables? >>>>> Dynamic scoping is inherently global, whether in Elisp or in any other >>>>> language. >>> >>>> Not in Common Lisp. >>> >>>> (defun d1 () >>>> (let ((var 1)) >>>> (declare (special var)) >>>> (l1))) >>> >>>> (defun l1 () >>>> (let ((var 2)) >>>> (print var) >>>> (d2))) >>> >>>> (defun d2 () >>>> (declare (special var)) >>>> (print var)) >>> >>>> D1 and D2 use the dynamic variable VAR, L1 uses the lexical variable VAR. >>> >>> Same in Elisp. But if d1 and d2 are in two separate packages that know >>> nothing about each other but who happen to call each other through some >>> potentially twisted sequence of calls, they will still interfere, >>> because there's only (globally) one dynamic variable by that name. >>> >> >> Now if two separate packages define a lexical var with the very same, is such >> a confusion excluded? > > Yes. By definition, lexical variables are only visible in the lexical > contour, not in other functions. I'm afraid it's not about definition, as let-bound variables should not be inherently global, Let's memorize Stefan's remark as a starting-point to work-on: " But if d1 and d2 are in two separate packages that know nothing about each other but who happen to call each other through some potentially twisted sequence of calls, they will still interfere, because there's only (globally) one dynamic variable by that name." Would like to see such a twisted sequence and what makes it's different from a common bug. > > The exception is if a macro expands into code that binds the variable: > > (defmacro pkg1-m (&body b) > `(let ((var 'm)) > ,@b)) > > (defun pkg2-f () > (let ((var 'f)) > (pkg1-m > (print var)))) > > (pkg2-f) will print "m" rather than "f". Mmm, maybe I don't understand, but that wouldn't surprise me, because pkg1-m re-binds it(?) > > This is generally referred to as the "hygiene" problem in macros. It's > why macros should use gensym to create the local variables used in the > expansion, or take the variable as a parameter. Dialects like Scheme > have built-in mechanisms to create hygienic macros. > ^ permalink raw reply [flat|nested] 46+ messages in thread
[parent not found: <mailman.3016.1380307597.10748.help-gnu-emacs@gnu.org>]
* Re: Declaring a local dynamic variable? [not found] ` <mailman.3016.1380307597.10748.help-gnu-emacs@gnu.org> @ 2013-09-27 20:18 ` Pascal J. Bourguignon 2013-09-27 23:57 ` Stefan Monnier 2013-09-28 6:20 ` Andreas Röhler 0 siblings, 2 replies; 46+ messages in thread From: Pascal J. Bourguignon @ 2013-09-27 20:18 UTC (permalink / raw) To: help-gnu-emacs Andreas Röhler <andreas.roehler@easy-emacs.de> writes: > Let's memorize Stefan's remark as a starting-point to work-on: > > " But if d1 and d2 are in two separate packages that know > nothing about each other but who happen to call each other through some > potentially twisted sequence of calls, they will still interfere, > because there's only (globally) one dynamic variable by that name." > > Would like to see such a twisted sequence and what makes it's different from a common bug. With (setq lexical-binding nil). Here is a case where it's a common bug: ;; -------- (defun p1-f () (let ((print-circle t)) (p2-g (function p1-h) '#1=(1 2 . #1#)))) (defun p1-h (data f) (print data) (funcall f)) ;; -------- (defun p2-g (p d) (let ((print-circle nil)) (funcall p '(1 2 3) (function p2-i)))) (defun p2-i (data) (print data)) ;; -------- Here is a case where it's not a common bug: ;; -------- (defun p1-f () (let ((be-careful t)) (p2-g (function p1-h) '#1=(1 2 . #1#)))) (defun p1-h (data f) (if be-careful (let ((print-circle t)) (print data)) (print data)) (funcall f)) ;; -------- (defun p2-g (p d) (let ((be-careful nil)) (funcall p '(1 2 3) (function p2-i)))) (defun p2-i (data) (if be-careful (let ((print-circle t)) (print data)) (print data))) ;; -------- The difference is that in the first case, there's a global definition for print-circle, while in the second case, the packages expect be-careful to be local special variables. You could use my macros and (declare (special be-careful)) in each package, and the bug would persist. However, it would NOT occur in Common Lisp, where you'd have (in-package "P1") and (in-package "P2") forms in front of each bodies of code, because you'd have actually TWO special symbols: p1::be-careful and p2::be-careful. The conclusion is that in emacs lisp you have to prefix ALL the symbols! Which clearly demonstrates a failure of the language. -- __Pascal Bourguignon__ http://www.informatimago.com/ ^ permalink raw reply [flat|nested] 46+ messages in thread
* Re: Declaring a local dynamic variable? 2013-09-27 20:18 ` Pascal J. Bourguignon @ 2013-09-27 23:57 ` Stefan Monnier 2013-09-28 6:20 ` Andreas Röhler 1 sibling, 0 replies; 46+ messages in thread From: Stefan Monnier @ 2013-09-27 23:57 UTC (permalink / raw) To: help-gnu-emacs > The conclusion is that in emacs lisp you have to prefix ALL the symbols! Not quite: only all the dynamically scoped symbols. Lexically scoped symbols do not suffer from this problem. Stefan ^ permalink raw reply [flat|nested] 46+ messages in thread
* Re: Declaring a local dynamic variable? 2013-09-27 20:18 ` Pascal J. Bourguignon 2013-09-27 23:57 ` Stefan Monnier @ 2013-09-28 6:20 ` Andreas Röhler 2013-09-28 6:24 ` W. Greenhouse 1 sibling, 1 reply; 46+ messages in thread From: Andreas Röhler @ 2013-09-28 6:20 UTC (permalink / raw) To: help-gnu-emacs Am 27.09.2013 22:18, schrieb Pascal J. Bourguignon: [ ... ] > > The conclusion is that in emacs lisp you have to prefix ALL the symbols! > Which clearly demonstrates a failure of the language. > Resp. of it's implementation. Why not uniquify --instead of prefixing-- under the hood? ^ permalink raw reply [flat|nested] 46+ messages in thread
* Re: Declaring a local dynamic variable? 2013-09-28 6:20 ` Andreas Röhler @ 2013-09-28 6:24 ` W. Greenhouse 2013-09-28 6:50 ` Andreas Röhler 0 siblings, 1 reply; 46+ messages in thread From: W. Greenhouse @ 2013-09-28 6:24 UTC (permalink / raw) To: help-gnu-emacs Andreas Röhler <andreas.roehler@easy-emacs.de> writes: > Am 27.09.2013 22:18, schrieb Pascal J. Bourguignon: > [ ... ] >> >> The conclusion is that in emacs lisp you have to prefix ALL the symbols! >> Which clearly demonstrates a failure of the language. >> > > Resp. of it's implementation. > > Why not uniquify --instead of prefixing-- under the hood? As has already been pointed out in this thread, Emacs does have (via cl-lib or more specifically cl-macs) a version of `declare' whose special-variable declarations are respected by the byte compiler. So it's a solved problem; I don't understand why Pascal and others are NIHing it and then complaining about the deficiencies of Emacs Lisp. The general usefulness of this functionality, however, does make me wonder why it's still stuck in the cl namespace. It seems like a prime candidate for promotion to subr or similar. -- Regards, WGG ^ permalink raw reply [flat|nested] 46+ messages in thread
* Re: Declaring a local dynamic variable? 2013-09-28 6:24 ` W. Greenhouse @ 2013-09-28 6:50 ` Andreas Röhler 2013-09-28 7:21 ` W. Greenhouse 0 siblings, 1 reply; 46+ messages in thread From: Andreas Röhler @ 2013-09-28 6:50 UTC (permalink / raw) To: help-gnu-emacs Am 28.09.2013 08:24, schrieb W. Greenhouse: > Andreas Röhler <andreas.roehler@easy-emacs.de> writes: > >> Am 27.09.2013 22:18, schrieb Pascal J. Bourguignon: >> [ ... ] >>> >>> The conclusion is that in emacs lisp you have to prefix ALL the symbols! >>> Which clearly demonstrates a failure of the language. >>> >> >> Resp. of it's implementation. >> >> Why not uniquify --instead of prefixing-- under the hood? > > As has already been pointed out in this thread, Emacs does have (via > cl-lib or more specifically cl-macs) a version of `declare' whose > special-variable declarations are respected by the byte compiler. So > it's a solved problem; I don't understand why Pascal and others are > NIHing it and then complaining about the deficiencies of Emacs Lisp. > > The general usefulness of this functionality, however, does make me > wonder why it's still stuck in the cl namespace. It seems like a prime > candidate for promotion to subr or similar. > BTW not sure if we are speaking at the same thing, resp. if this might be expressed by "lexical" or "dynamic" already. IMO it's convenient to use and change a let-bound var in downward functions, whithout the need to hand it over via arguments etc. Just a convenience, it saves keystrokes, a major reason for me to use Emacs. Maybe "let" should already provide what "declare" does? ^ permalink raw reply [flat|nested] 46+ messages in thread
* Re: Declaring a local dynamic variable? 2013-09-28 6:50 ` Andreas Röhler @ 2013-09-28 7:21 ` W. Greenhouse 0 siblings, 0 replies; 46+ messages in thread From: W. Greenhouse @ 2013-09-28 7:21 UTC (permalink / raw) To: help-gnu-emacs Andreas Röhler <andreas.roehler@easy-emacs.de> writes: [...] > BTW not sure if we are speaking at the same thing, resp. if this might > be expressed by "lexical" or "dynamic" already. > > IMO it's convenient to use and change a let-bound var in downward > functions, whithout the need to hand it over via arguments etc. Just > a convenience, it saves keystrokes, a major reason for me to use > Emacs. > > Maybe "let" should already provide what "declare" does? You're right, maybe we don't quite understand each other. To reiterate: As it stands now, the byte compiler throws a warning when it sees a function refer to a variable which is neither bound inside the function (e.g. by `let', by the function's arglist, etc.) nor defined globally. Variables bound by `let' do not throw the warning. And this is not a "dynamic" vs. "lexical" problem--the variables in question are already dynamic for sure, because, not being bound inside the text of their function, they can't possibly be lexically bound! This situation is analogous to the failed call to `getx' in the example under the second paragraph of (info "(elisp) Lexical Binding"). So the warning is there for good reason. When you're using dynamic binding in your library, the warning tells you that you possibly made a typo and should check to make sure you aren't setting the wrong thing. Where you're using lexical binding, it tells you that your function which refers to variable `foo' will certainly fail to pick up the lexically bound `foo' in the calling function. Either way, it is something you probably want to know about. You are of course able to use dynamic variables to pass state around between two functions, even in a library that uses lexical-binding. The compiler's just going to complain about you doing so with, e.g., `setq' without declaring the variable first. The point is also made in (info "(elisp) Dynamic Binding Tips") that, since such "utility" dynamic variables are accessible to all of Emacs, they should be usefully named to avoid collisions with similar functions, and maybe even have a docstring. Nudging the programmer to use `defvar' or `declare' for these dynamic "utility" variables therefore seems appropriate. -- Regards, WGG ^ permalink raw reply [flat|nested] 46+ messages in thread
[parent not found: <mailman.2873.1380135245.10748.help-gnu-emacs@gnu.org>]
* Re: Declaring a local dynamic variable? [not found] ` <mailman.2873.1380135245.10748.help-gnu-emacs@gnu.org> @ 2013-09-26 0:06 ` Barry Margolin 0 siblings, 0 replies; 46+ messages in thread From: Barry Margolin @ 2013-09-26 0:06 UTC (permalink / raw) To: help-gnu-emacs In article <mailman.2873.1380135245.10748.help-gnu-emacs@gnu.org>, Stefan Monnier <monnier@iro.umontreal.ca> wrote: > >> > So in essence Emacs doesn't really have local dynamic variables? > >> Dynamic scoping is inherently global, whether in Elisp or in any other > >> language. > > > Not in Common Lisp. > > > (defun d1 () > > (let ((var 1)) > > (declare (special var)) > > (l1))) > > > (defun l1 () > > (let ((var 2)) > > (print var) > > (d2))) > > > (defun d2 () > > (declare (special var)) > > (print var)) > > > D1 and D2 use the dynamic variable VAR, L1 uses the lexical variable VAR. > > Same in Elisp. But if d1 and d2 are in two separate packages that know > nothing about each other but who happen to call each other through some > potentially twisted sequence of calls, they will still interfere, > because there's only (globally) one dynamic variable by that name. Which, of course, is why this is a horrible programming style. I wasn't recommending this, just showing that a dynamic variable isn't totally global -- you can have scopes where the same variable name is used lexically. But it's a little safer than defvars -- the chance that unrelated packages will happen to have local special variables with the same name, and also call between these functions, is extremely remote, and certainly less likely than using a variable that happens to match a defvar. -- Barry Margolin, barmar@alum.mit.edu Arlington, MA *** PLEASE post questions in newsgroups, not directly to me *** ^ permalink raw reply [flat|nested] 46+ messages in thread
end of thread, other threads:[~2013-11-03 1:42 UTC | newest] Thread overview: 46+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2013-09-20 9:52 Declaring a local dynamic variable? Joost Kremers 2013-09-20 12:30 ` Stefan Monnier 2013-09-20 14:54 ` Andreas Röhler [not found] ` <mailman.2569.1379688787.10748.help-gnu-emacs@gnu.org> 2013-09-20 15:10 ` Barry Margolin 2013-09-20 16:34 ` Andreas Röhler [not found] ` <mailman.2578.1379694764.10748.help-gnu-emacs@gnu.org> 2013-09-20 20:59 ` Barry Margolin 2013-09-21 5:49 ` Andreas Röhler 2013-09-23 16:19 ` Joost Kremers [not found] ` <mailman.2622.1379742443.10748.help-gnu-emacs@gnu.org> 2013-09-21 11:31 ` Barry Margolin 2013-09-21 13:32 ` Andreas Röhler [not found] ` <mailman.2638.1379770251.10748.help-gnu-emacs@gnu.org> 2013-09-22 3:49 ` Barry Margolin 2013-09-23 16:26 ` Joost Kremers 2013-09-23 21:17 ` Barry Margolin 2013-09-23 22:14 ` Joost Kremers 2013-09-24 0:03 ` Barry Margolin 2013-09-25 8:58 ` Joost Kremers 2013-09-22 17:11 ` Pascal J. Bourguignon 2013-09-23 16:17 ` Joost Kremers 2013-09-24 21:40 ` Stefan Monnier 2013-11-02 23:56 ` WJ 2013-11-03 1:42 ` WJ [not found] ` <mailman.2566.1379680283.10748.help-gnu-emacs@gnu.org> 2013-09-23 16:11 ` Joost Kremers 2013-09-24 21:34 ` Stefan Monnier 2013-09-25 5:52 ` Andreas Röhler 2013-09-25 7:24 ` Stefan Monnier 2013-09-25 8:43 ` Joost Kremers 2013-09-25 12:26 ` Stefan Monnier 2013-10-12 16:54 ` Andreas Röhler [not found] ` <mailman.3886.1381596756.10748.help-gnu-emacs@gnu.org> 2013-10-12 21:25 ` Kai Grossjohann 2013-10-13 8:12 ` Andreas Röhler 2013-10-13 13:37 ` Stefan Monnier 2013-10-13 17:41 ` Andreas Röhler 2013-10-13 19:56 ` Kai Großjohann [not found] ` <mailman.2843.1380112007.10748.help-gnu-emacs@gnu.org> 2013-09-25 15:46 ` Barry Margolin 2013-09-25 18:53 ` Stefan Monnier 2013-09-27 9:53 ` Andreas Röhler 2013-09-27 13:15 ` Stefan Monnier [not found] ` <mailman.2982.1380275511.10748.help-gnu-emacs@gnu.org> 2013-09-27 14:31 ` Barry Margolin 2013-09-27 18:48 ` Andreas Röhler [not found] ` <mailman.3016.1380307597.10748.help-gnu-emacs@gnu.org> 2013-09-27 20:18 ` Pascal J. Bourguignon 2013-09-27 23:57 ` Stefan Monnier 2013-09-28 6:20 ` Andreas Röhler 2013-09-28 6:24 ` W. Greenhouse 2013-09-28 6:50 ` Andreas Röhler 2013-09-28 7:21 ` W. Greenhouse [not found] ` <mailman.2873.1380135245.10748.help-gnu-emacs@gnu.org> 2013-09-26 0:06 ` Barry Margolin
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).