Thread View: gmane.emacs.devel
35 messages
35 total messages
Started by Alan Mackenzie
Mon, 28 Aug 2023 19:37
Why shouldn't we have a #if .... #else .... #endif construct in Emacs Lisp?
Author: Alan Mackenzie
Date: Mon, 28 Aug 2023 19:37
Date: Mon, 28 Aug 2023 19:37
50 lines
1723 bytes
1723 bytes
Hello, Emacs. In C, we have the very useful conditional compilation directives introduced by #if or #ifdef, etc., which end at #end. In Emacs Lisp we have no such construct. This is a Bad Thing. More and more, especially recently, irritating warning messages are occurring for, for example, obsolete variables and functions inside conditionals which ensure they aren't used. For example: (when (< emacs-major-version 24) (defadvice .....)) produces the warning about defadvice being obsolete. (I haven't actually tested this example). What we really want here is for the defadvice only to be _compiled_ when (< emacs-major-version 24), rather than compiled unconditionally and not run. I propose a new function, hash-if, which would do what we want. The above example could then be written something like: (hash-if (< emacs-major-version 24) (defadvice .....) (advice-add .....)) .. This is not actually all that difficult to write. My first attempt uses a compiler-macro, and looks like this: (defun hash-if (condition if-part &rest else-part) "A compiler macro analogous to C's #if. CONDITION is evaluated at compile time. If it is non-nil, IF-PART gets compiled. Otherwise ELSE-PART (enclosed in a `progn') gets compiled." (declare (indent 2)) (error "hash-if has been called directly")) (put 'hash-if 'compiler-macro (lambda (form condition if-part &rest else-part) (if (eval condition lexical-binding) if-part (cons 'progn else-part)))) .. I propose adding it to subr.el, just before (defmacro when ....). What do people think about this? -- Alan Mackenzie (Nuremberg, Germany).
Re: Why shouldn't we have a #if .... #else .... #endif construct in Emacs Lisp?
Author: Alan Mackenzie
Date: Mon, 28 Aug 2023 20:06
Date: Mon, 28 Aug 2023 20:06
51 lines
1940 bytes
1940 bytes
Hello, Ulrich. On Mon, Aug 28, 2023 at 21:47:57 +0200, Ulrich Mueller wrote: > >>>>> On Mon, 28 Aug 2023, Alan Mackenzie wrote: > > In C, we have the very useful conditional compilation directives > > introduced by #if or #ifdef, etc., which end at #end. > > In Emacs Lisp we have no such construct. This is a Bad Thing. > > More and more, especially recently, irritating warning messages are > > occurring for, for example, obsolete variables and functions inside > > conditionals which ensure they aren't used. For example: > > (when (< emacs-major-version 24) > > (defadvice .....)) > > produces the warning about defadvice being obsolete. (I haven't actually > > tested this example). What we really want here is for the defadvice only > > to be _compiled_ when (< emacs-major-version 24), rather than compiled > > unconditionally and not run. > I believe (eval-when-compile (< emacs-major-version 24)) would work? I've twisted my head into knots in the past trying to work out how to use eval-when/and-compile for this purpose. The point is, I don't want the defadvice to be evaluated at compile time; I just want it to be compiled (or not). > > I propose a new function, hash-if, which would do what we want. The > > above example could then be written something like: > > (hash-if (< emacs-major-version 24) > > (defadvice .....) > > (advice-add .....)) > But the old Emacs version wouldn't have the function, so it couldn't be > used like this. What am I missing? That's a very good point. I would propose that we suggest to package maintainers that they include the entire source of hash-if inside a suitable conditional in their packages. It's only 13 lines of code, including a doc string. It would appear that the compiler-macro mechanism existed at the latest in Emacs 21.4. I don't know how well it worked in these earlier versions. -- Alan Mackenzie (Nuremberg, Germany).
Re: Why shouldn't we have a #if .... #else .... #endif construct in Emacs Lisp?
Author: Alan Mackenzie
Date: Mon, 28 Aug 2023 21:46
Date: Mon, 28 Aug 2023 21:46
36 lines
1289 bytes
1289 bytes
Hello, Ulrich. On Mon, Aug 28, 2023 at 23:01:53 +0200, Ulrich Mueller wrote: > >>>>> On Mon, 28 Aug 2023, Alan Mackenzie wrote: > >> > (when (< emacs-major-version 24) > >> > (defadvice .....)) > >> I believe (eval-when-compile (< emacs-major-version 24)) would work? > > I've twisted my head into knots in the past trying to work out how to > > use eval-when/and-compile for this purpose. The point is, I don't want > > the defadvice to be evaluated at compile time; I just want it to be > > compiled (or not). > Sorry, I should have been clearer. The full construct would look like > this: > (when (eval-when-compile (< emacs-major-version 24)) > (defadvice .....)) Ah! So the eval-when-compile gets compiled to a constant nil or t, and the byte compiler optimises the test of this out, either compiling or not compiling the (defadvice .....). Thanks! I hadn't been aware of that little detail. > So only the test would be evaluated at compile time, the defadvice > itself would be compiled normally (or not, if the test fails). However, when evaluating the containing defun/defmacro rather than byte compiling it, the irritating warning message will appear with the e-w-c strategem, but not with hash-if. ;-) -- Alan Mackenzie (Nuremberg, Germany).
Re: Why shouldn't we have a #if .... #else .... #endif construct in Emacs Lisp?
Author: Ulrich Mueller
Date: Mon, 28 Aug 2023 21:47
Date: Mon, 28 Aug 2023 21:47
31 lines
1168 bytes
1168 bytes
>>>>> On Mon, 28 Aug 2023, Alan Mackenzie wrote: > In C, we have the very useful conditional compilation directives > introduced by #if or #ifdef, etc., which end at #end. > In Emacs Lisp we have no such construct. This is a Bad Thing. > More and more, especially recently, irritating warning messages are > occurring for, for example, obsolete variables and functions inside > conditionals which ensure they aren't used. For example: > (when (< emacs-major-version 24) > (defadvice .....)) > produces the warning about defadvice being obsolete. (I haven't actually > tested this example). What we really want here is for the defadvice only > to be _compiled_ when (< emacs-major-version 24), rather than compiled > unconditionally and not run. I believe (eval-when-compile (< emacs-major-version 24)) would work? > I propose a new function, hash-if, which would do what we want. The > above example could then be written something like: > (hash-if (< emacs-major-version 24) > (defadvice .....) > (advice-add .....)) But the old Emacs version wouldn't have the function, so it couldn't be used like this. What am I missing?
Re: Why shouldn't we have a #if .... #else .... #endif construct in Emacs Lisp?
Author: Emanuel Berg
Date: Mon, 28 Aug 2023 21:53
Date: Mon, 28 Aug 2023 21:53
20 lines
482 bytes
482 bytes
Alan Mackenzie wrote: > In C, we have the very useful conditional compilation > directives introduced by #if or #ifdef, etc., which end at > #end. Those are directives to the C preprocessor and some people say it is a sign of weakness such a thing is even necessary to begin with. Let's see if they are right! What problem do you have? If we can solve it in Elisp, we cannot say those people saying that are wrong. -- underground experts united https://dataswamp.org/~incal
Re: Why shouldn't we have a #if .... #else .... #endif construct in Emacs Lisp?
Author: Ulrich Mueller
Date: Mon, 28 Aug 2023 23:01
Date: Mon, 28 Aug 2023 23:01
21 lines
725 bytes
725 bytes
>>>>> On Mon, 28 Aug 2023, Alan Mackenzie wrote: >> > (when (< emacs-major-version 24) >> > (defadvice .....)) >> I believe (eval-when-compile (< emacs-major-version 24)) would work? > I've twisted my head into knots in the past trying to work out how to > use eval-when/and-compile for this purpose. The point is, I don't want > the defadvice to be evaluated at compile time; I just want it to be > compiled (or not). Sorry, I should have been clearer. The full construct would look like this: (when (eval-when-compile (< emacs-major-version 24)) (defadvice .....)) So only the test would be evaluated at compile time, the defadvice itself would be compiled normally (or not, if the test fails).
Re: Why shouldn't we have a #if .... #else .... #endif construct in Emacs Lisp?
Author: Alan Mackenzie
Date: Tue, 29 Aug 2023 09:19
Date: Tue, 29 Aug 2023 09:19
40 lines
1126 bytes
1126 bytes
Hello, Emanuel. On Mon, Aug 28, 2023 at 21:53:04 +0200, Emanuel Berg wrote: > Alan Mackenzie wrote: > > In C, we have the very useful conditional compilation > > directives introduced by #if or #ifdef, etc., which end at > > #end. > Those are directives to the C preprocessor and some people say > it is a sign of weakness such a thing is even necessary to > begin with. I think these people tend to be those living in an ideal world rather than the real world. > Let's see if they are right! > What problem do you have? The one I outlined in my original post: the use of obsolete functions/variables inside conditionals which ensure they only get called/referenced in older versions of Emacs. These obsolete objects are getting needlessly compiled in the master branch, giving rise to lots of irritating warning messages. It's a problem which arises in packages rather than in the core. > If we can solve it in Elisp, we cannot say those people saying that > are wrong. My proposed solution is in Elisp. > -- > underground experts united > https://dataswamp.org/~incal -- Alan Mackenzie (Nuremberg, Germany).
Re: Why shouldn't we have a #if .... #else .... #endif construct in Emacs Lisp?
Author: Ihor Radchenko
Date: Tue, 29 Aug 2023 11:09
Date: Tue, 29 Aug 2023 11:09
15 lines
445 bytes
445 bytes
João TÔvora <joaotavora@gmail.com> writes: > FWIW, Common Lisp has reader macros to solve the problem: > http://clhs.lisp.se/Body/24_aba.htm Elisp also has reader macros ;) See lisp/emacs-lisp/backquote.el -- Ihor Radchenko // yantar92, Org mode contributor, Learn more about Org mode at <https://orgmode.org/>. Support Org development at <https://liberapay.com/org-mode>, or support my work at <https://liberapay.com/yantar92>
Re: Why shouldn't we have a #if .... #else .... #endif construct in Emacs Lisp?
Author: LdBeth
Date: Tue, 29 Aug 2023 11:28
Date: Tue, 29 Aug 2023 11:28
38 lines
1226 bytes
1226 bytes
>>>>> In <ZOz3lR_4Al88SEJ_@ACM> >>>>> Alan Mackenzie <acm@muc.de> wrote: acm> Hello, Emacs. acm> In Emacs Lisp we have no such construct. This is a Bad Thing. acm> More and more, especially recently, irritating warning messages are acm> occurring for, for example, obsolete variables and functions inside acm> conditionals which ensure they aren't used. For example: acm> (when (< emacs-major-version 24) acm> (defadvice .....)) acm> produces the warning about defadvice being obsolete. (I haven't actually acm> tested this example). What we really want here is for the defadvice only acm> to be _compiled_ when (< emacs-major-version 24), rather than compiled acm> unconditionally and not run. acm> I propose a new function, hash-if, which would do what we want. The acm> above example could then be written something like: acm> (hash-if (< emacs-major-version 24) acm> (defadvice .....) acm> (advice-add .....)) Have a look at `static.el' from APEL https://github.com/wanderlust/apel It provides `static-if' and other useful macros. (defmacro static-if (cond then &rest else) "Like `if', but evaluate COND at compile time." (if (eval cond) then `(progn ,@ else)))
Re: Why shouldn't we have a #if .... #else .... #endif construct in Emacs Lisp?
Author: =?UTF-8?B?Sm/Do2
Date: Tue, 29 Aug 2023 11:36
Date: Tue, 29 Aug 2023 11:36
67 lines
2503 bytes
2503 bytes
--00000000000071873606040d635c Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable On Tue, Aug 29, 2023, 03:21 Emanuel Berg <incal@dataswamp.org> wrote: > Alan Mackenzie wrote: > > > In C, we have the very useful conditional compilation > > directives introduced by #if or #ifdef, etc., which end at > > #end. > > Those are directives to the C preprocessor and some people say > it is a sign of weakness such a thing is even necessary to > begin with. > > Let's see if they are right! > > What problem do you have? If we can solve it in Elisp, we > cannot say those people saying that are wrong. > FWIW, Common Lisp has reader macros to solve the problem: http://clhs.lisp.se/Body/24_aba.htm If Elisp had a better, more programmable reader, this would be the way to solve it IMO João > --00000000000071873606040d635c Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable <div dir="auto"><div><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Tue, Aug 29, 2023, 03:21 Emanuel Berg <<a href="mailto:incal@dataswamp.org" target="_blank" rel="noreferrer">incal@dataswamp.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Alan Mackenzie wrote:<br> <br> > In C, we have the very useful conditional compilation<br> > directives introduced by #if or #ifdef, etc., which end at<br> > #end.<br> <br> Those are directives to the C preprocessor and some people say<br> it is a sign of weakness such a thing is even necessary to<br> begin with.<br> <br> Let's see if they are right!<br> <br> What problem do you have? If we can solve it in Elisp, we<br> cannot say those people saying that are wrong.<br></blockquote></div></div><div dir="auto"><br></div><div dir="auto">FWIW, Common Lisp has reader macros to solve the problem: <a href="http://clhs.lisp.se/Body/24_aba.htm" target="_blank" rel="noreferrer">http://clhs.lisp.se/Body/24_aba.htm</a></div><div dir="auto"><br></div><div dir="auto">If Elisp had a better, more programmable reader, this would be the way to solve it IMO</div><div dir="auto"><br></div><div dir="auto">João</div><div dir="auto"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"> </blockquote></div></div></div> --00000000000071873606040d635c--
Re: Why shouldn't we have a #if .... #else .... #endif construct in Emacs Lisp?
Author: =?UTF-8?B?Sm/Do2
Date: Tue, 29 Aug 2023 12:20
Date: Tue, 29 Aug 2023 12:20
19 lines
693 bytes
693 bytes
On Tue, Aug 29, 2023 at 12:09āÆPM Ihor Radchenko <yantar92@posteo.net> wrote: > > JoĆ£o TĆ”vora <joaotavora@gmail.com> writes: > > > FWIW, Common Lisp has reader macros to solve the problem: > > http://clhs.lisp.se/Body/24_aba.htm > > Elisp also has reader macros ;) > See lisp/emacs-lisp/backquote.el Of course it has many more even, but the problem is that such things are hardcoded in C even if part of the implementation then jumps to Lisp. See lread.c around line 4318 for how backquote is hardcoded. In Common Lisp there is a programmable mechanism for adding such macros entirely within the language. So don't be fooled, Elisp simply doesn't have that. JoĆ£o
Re: Why shouldn't we have a #if .... #else .... #endif construct in Emacs Lisp?
Author: Philip Kaluderci
Date: Tue, 29 Aug 2023 12:54
Date: Tue, 29 Aug 2023 12:54
60 lines
2199 bytes
2199 bytes
Alan Mackenzie <acm@muc.de> writes: > Hello, Emacs. > > In C, we have the very useful conditional compilation directives > introduced by #if or #ifdef, etc., which end at #end. > > In Emacs Lisp we have no such construct. This is a Bad Thing. > > More and more, especially recently, irritating warning messages are > occurring for, for example, obsolete variables and functions inside > conditionals which ensure they aren't used. For example: > > (when (< emacs-major-version 24) > (defadvice .....)) > > produces the warning about defadvice being obsolete. (I haven't actually > tested this example). What we really want here is for the defadvice only > to be _compiled_ when (< emacs-major-version 24), rather than compiled > unconditionally and not run. In this specific case, would it be possible to use the nadvice compatibility package on GNU ELPA? > I propose a new function, hash-if, which would do what we want. The > above example could then be written something like: > > (hash-if (< emacs-major-version 24) > (defadvice .....) > (advice-add .....)) > > .. This is not actually all that difficult to write. My first attempt > uses a compiler-macro, and looks like this: > > (defun hash-if (condition if-part &rest else-part) > "A compiler macro analogous to C's #if. > CONDITION is evaluated at compile time. If it is non-nil, > IF-PART gets compiled. Otherwise ELSE-PART (enclosed in a > `progn') gets compiled." > (declare (indent 2)) > (error "hash-if has been called directly")) > > (put 'hash-if 'compiler-macro > (lambda (form condition if-part &rest else-part) > (if (eval condition lexical-binding) > if-part > (cons 'progn else-part)))) Would something like work as well: --8<---------------cut here---------------start------------->8--- (defmacro cif (test then &rest else) "Evaluate TEST during macro-expansion and return THEN or ELSE." (if (eval test t) then else)) --8<---------------cut here---------------end--------------->8--- > .. I propose adding it to subr.el, just before (defmacro when ....). > > What do people think about this?
Re: Why shouldn't we have a #if .... #else .... #endif construct in Emacs Lisp?
Author: Alan Mackenzie
Date: Tue, 29 Aug 2023 13:23
Date: Tue, 29 Aug 2023 13:23
81 lines
2902 bytes
2902 bytes
Hello, Philip. On Tue, Aug 29, 2023 at 12:54:17 +0000, Philip Kaludercic wrote: > Alan Mackenzie <acm@muc.de> writes: > > Hello, Emacs. > > In C, we have the very useful conditional compilation directives > > introduced by #if or #ifdef, etc., which end at #end. > > In Emacs Lisp we have no such construct. This is a Bad Thing. > > More and more, especially recently, irritating warning messages are > > occurring for, for example, obsolete variables and functions inside > > conditionals which ensure they aren't used. For example: > > (when (< emacs-major-version 24) > > (defadvice .....)) > > produces the warning about defadvice being obsolete. (I haven't actually > > tested this example). What we really want here is for the defadvice only > > to be _compiled_ when (< emacs-major-version 24), rather than compiled > > unconditionally and not run. > In this specific case, would it be possible to use the nadvice > compatibility package on GNU ELPA? I suspect it would be, yes. > > I propose a new function, hash-if, which would do what we want. The > > above example could then be written something like: > > (hash-if (< emacs-major-version 24) > > (defadvice .....) > > (advice-add .....)) > > .. This is not actually all that difficult to write. My first attempt > > uses a compiler-macro, and looks like this: > > (defun hash-if (condition if-part &rest else-part) > > "A compiler macro analogous to C's #if. > > CONDITION is evaluated at compile time. If it is non-nil, > > IF-PART gets compiled. Otherwise ELSE-PART (enclosed in a > > `progn') gets compiled." > > (declare (indent 2)) > > (error "hash-if has been called directly")) > > (put 'hash-if 'compiler-macro > > (lambda (form condition if-part &rest else-part) > > (if (eval condition lexical-binding) > > if-part > > (cons 'progn else-part)))) > Would something like work as well: > --8<---------------cut here---------------start------------->8--- > (defmacro cif (test then &rest else) > "Evaluate TEST during macro-expansion and return THEN or ELSE." > (if (eval test t) then else)) > --8<---------------cut here---------------end--------------->8--- Hah! Trust me to build something twisted and complicated when there's a simple solution which will do just as well! I think the `else' needs a 'progn, though, like this: (if (eval test t) then (cons 'progn else)) , and the eval form probably wants to go into a condition-case for Emacsen lacking the second parameter. But I appreciate you put the code together quickly, rather than working out every last detail. Thanks! > > .. I propose adding it to subr.el, just before (defmacro when ....). > > What do people think about this? Yes, what do people think about the idea? -- Alan Mackenzie (Nuremberg, Germany).
Re: Why shouldn't we have a #if .... #else .... #endif construct in Emacs Lisp?
Author: Stefan Kangas
Date: Tue, 29 Aug 2023 22:09
Date: Tue, 29 Aug 2023 22:09
17 lines
396 bytes
396 bytes
Alan Mackenzie <acm@muc.de> writes: > What do people think about this? I have two questions: 1. Would it be hard to make the byte-compiler not warn in the situation you describe? 2. Isn't something like this enough to silence the byte-compiler? (defalias 'foo-defadvice (if (< emacs-major-version 24) 'defadvice (lambda () (message "foo")))) (foo-defadvice)
Re: Why shouldn't we have a #if .... #else .... #endif construct in Emacs Lisp?
Author: Alan Mackenzie
Date: Wed, 30 Aug 2023 10:31
Date: Wed, 30 Aug 2023 10:31
35 lines
1049 bytes
1049 bytes
Hello, Stefan. On Tue, Aug 29, 2023 at 22:09:25 +0200, Stefan Kangas wrote: > Alan Mackenzie <acm@muc.de> writes: > > What do people think about this? > I have two questions: > 1. Would it be hard to make the byte-compiler not warn in the > situation you describe? (That situation being where an obsolete function/variable is tested for, and is used or not used according to the result of the test.) It would not be too hard, and the scheme I'm proposing (with help from Philip K.) is one way of doing this. I'm sure there are other possible ways, too. > 2. Isn't something like this enough to silence the byte-compiler? > (defalias 'foo-defadvice > (if (< emacs-major-version 24) > 'defadvice > (lambda () (message "foo")))) > (foo-defadvice) It may be, but it's clumsy. We would need such an alias for _each_ function/variable which has been declared obsolete. In my proposed mechanism, by contrast, one would just need to replace an `if' form by a `hash-if'. -- Alan Mackenzie (Nuremberg, Germany).
Re: Why shouldn't we have a #if .... #else .... #endif construct in Emacs Lisp?
Author: Alan Mackenzie
Date: Wed, 30 Aug 2023 18:03
Date: Wed, 30 Aug 2023 18:03
63 lines
2667 bytes
2667 bytes
Hello, Stefan. On Wed, Aug 30, 2023 at 19:36:20 +0200, Stefan Kangas wrote: > Alan Mackenzie <acm@muc.de> writes: > > > 1. Would it be hard to make the byte-compiler not warn in the > > > situation you describe? > > > > (That situation being where an obsolete function/variable is tested for, > > and is used or not used according to the result of the test.) It would > > not be too hard, and the scheme I'm proposing (with help from Philip K.) > > is one way of doing this. > I'm asking because we already have special casing in place for > (featurep 'xemacs) -- we just constant fold it -- so I'm wondering if > it would make sense to do the same here. See bytecomp.el:5671. I looked at that, and came to the conclusion it doesn't make sense. The mechanics there would be to evaluate (if some-condition FOO BAR) at compilation time and replace it with either FOO or BAR. The problem is some-condition can vary at run time, for example by setting an option, so it would be more trouble than it's worth. > It's not the same situation exactly though, as we will often be able > to run bytecode from Emacs N+1 on Emacs N, whereas XEmacs/Emacs > byte-code compatibility is both long gone and in all likelihood not > coming back. Indeed, not. > > It may be, but it's clumsy. We would need such an alias for _each_ > > function/variable which has been declared obsolete. In my proposed > > mechanism, by contrast, one would just need to replace an `if' form by a > > `hash-if'. > Right. I guess this has been the state of the art in Emacs Lisp so > far, though. And then `hash-if' itself won't exist in Emacs 24 > either, of course, so depending on how ambitious people are with > backwards-compatibility they'll have to lug around compatibility > boiler-plate for that too. The current size of hash-if, including doc-string, is 10 lines. Add in an extra line for (if (not fboundp 'hash-if) ....), and we come to 11 lines. I think, given the heartaches and headaches suffered by package maintainers when variables/functions become obsolete or vanish, this would not be much of a hardship. > If we do go with a new macro, I'd propose naming it `static-if' (as in > APEL) instead of `hash-if', because the latter name seems to wrongly > suggest that it has to do with hashing. I looked at APEL, and its code was near identical to what I (with help from PK) wrote. I'd have nothing against the name static-if instead. As long as this doesn't raise copyright assignment problems, assuming the authors of APEL haven't assigned copyright to the FSF. > Our legacy is also older than even the C preprocessor. :-) -- Alan Mackenzie (Nuremberg, Germany).
Re: Why shouldn't we have a #if .... #else .... #endif construct in Emacs Lisp?
Author: Stefan Kangas
Date: Wed, 30 Aug 2023 19:36
Date: Wed, 30 Aug 2023 19:36
33 lines
1555 bytes
1555 bytes
Alan Mackenzie <acm@muc.de> writes: > > 1. Would it be hard to make the byte-compiler not warn in the > > situation you describe? > > (That situation being where an obsolete function/variable is tested for, > and is used or not used according to the result of the test.) It would > not be too hard, and the scheme I'm proposing (with help from Philip K.) > is one way of doing this. I'm asking because we already have special casing in place for (featurep 'xemacs) -- we just constant fold it -- so I'm wondering if it would make sense to do the same here. See bytecomp.el:5671. It's not the same situation exactly though, as we will often be able to run bytecode from Emacs N+1 on Emacs N, whereas XEmacs/Emacs byte-code compatibility is both long gone and in all likelihood not coming back. > It may be, but it's clumsy. We would need such an alias for _each_ > function/variable which has been declared obsolete. In my proposed > mechanism, by contrast, one would just need to replace an `if' form by a > `hash-if'. Right. I guess this has been the state of the art in Emacs Lisp so far, though. And then `hash-if' itself won't exist in Emacs 24 either, of course, so depending on how ambitious people are with backwards-compatibility they'll have to lug around compatibility boiler-plate for that too. If we do go with a new macro, I'd propose naming it `static-if' (as in APEL) instead of `hash-if', because the latter name seems to wrongly suggest that it has to do with hashing. Our legacy is also older than even the C preprocessor.
Re: Why shouldn't we have a #if .... #else .... #endif construct in Emacs Lisp?
Author: Stefan Kangas
Date: Wed, 30 Aug 2023 20:17
Date: Wed, 30 Aug 2023 20:17
12 lines
582 bytes
582 bytes
Alan Mackenzie <acm@muc.de> writes: > I looked at APEL, and its code was near identical to what I (with help > from PK) wrote. I'd have nothing against the name static-if instead. > As long as this doesn't raise copyright assignment problems, assuming > the authors of APEL haven't assigned copyright to the FSF. I think it's fine as far as copyright goes. You came up with your version independently, before even looking at their code. We even have a public record of that right here on this list. IANAL, but the name `static-if' in itself is also not copyrightable, AFAIU.
Re: Why shouldn't we have a #if .... #else .... #endif construct in Emacs Lisp?
Author: Sean Whitton
Date: Wed, 30 Aug 2023 21:48
Date: Wed, 30 Aug 2023 21:48
16 lines
569 bytes
569 bytes
Hello, On Tue 29 Aug 2023 at 12:20pm +01, João TÔvora wrote: > Of course it has many more even, but the problem is that such things > are hardcoded in C even if part of the implementation then jumps to Lisp. > See lread.c around line 4318 for how backquote is hardcoded. In Common > Lisp there is a programmable mechanism for adding such macros entirely > within the language. So don't be fooled, Elisp simply doesn't have that. It's a deliberate choice, right? As part of ideas about keeping elisp simpler than something like CL. -- Sean Whitton
Re: Why shouldn't we have a #if .... #else .... #endif construct in Emacs Lisp?
Author: =?UTF-8?B?Sm/Do2
Date: Wed, 30 Aug 2023 21:59
Date: Wed, 30 Aug 2023 21:59
23 lines
746 bytes
746 bytes
On Wed, Aug 30, 2023 at 9:48āÆPM Sean Whitton <spwhitton@spwhitton.name> wrote: > > Hello, > > On Tue 29 Aug 2023 at 12:20pm +01, JoĆ£o TĆ”vora wrote: > > > Of course it has many more even, but the problem is that such things > > are hardcoded in C even if part of the implementation then jumps to Lisp. > > See lread.c around line 4318 for how backquote is hardcoded. In Common > > Lisp there is a programmable mechanism for adding such macros entirely > > within the language. So don't be fooled, Elisp simply doesn't have that. > > It's a deliberate choice, right? As part of ideas about keeping elisp > simpler than something like CL. Yeah, you "keep something simple" then Greenspuns's 10th kicks in. JoĆ£o
Re: Why shouldn't we have a #if .... #else .... #endif construct in Emacs Lisp?
Author: Richard Stallman
Date: Wed, 30 Aug 2023 22:07
Date: Wed, 30 Aug 2023 22:07
35 lines
1273 bytes
1273 bytes
[[[ To any NSA and FBI agents reading my email: please consider ]]] [[[ whether defending the US Constitution against all enemies, ]]] [[[ foreign or domestic, requires you to follow Snowden's example. ]]] > > (when (eval-when-compile (< emacs-major-version 24)) > > (defadvice .....)) > However, when evaluating the containing defun/defmacro rather than byte > compiling it, the irritating warning message will appear with the e-w-c > strategem, but not with hash-if. ;-) How about making the byte compiler recognize the construct (if (< emacs-major-version NUMBER) ...) and do this optimization on it? I think that will DTRT when compiled and when interpreted, and it won't require changes in the code of the programs that use it. That will handle `when' and `unless', since they expand into `if'. It may be necessary to implement this in two places, one for inside of function bodies and one for top level (outside of function definitions). But the code for this should be so short that having two is hardly much loss. -- Dr Richard Stallman (https://stallman.org) Chief GNUisance of the GNU Project (https://gnu.org) Founder, Free Software Foundation (https://fsf.org) Internet Hall-of-Famer (https://internethalloffame.org)
Re: Why shouldn't we have a #if .... #else .... #endif construct in Emacs Lisp?
Author: Alan Mackenzie
Date: Thu, 31 Aug 2023 07:50
Date: Thu, 31 Aug 2023 07:50
60 lines
2520 bytes
2520 bytes
Hello, Richard. On Wed, Aug 30, 2023 at 22:07:04 -0400, Richard Stallman wrote: > [[[ To any NSA and FBI agents reading my email: please consider ]]] > [[[ whether defending the US Constitution against all enemies, ]]] > [[[ foreign or domestic, requires you to follow Snowden's example. ]]] > > > (when (eval-when-compile (< emacs-major-version 24)) > > > (defadvice .....)) > > However, when evaluating the containing defun/defmacro rather than byte > > compiling it, the irritating warning message will appear with the e-w-c > > strategem, but not with hash-if. ;-) > How about making the byte compiler recognize the construct > (if (< emacs-major-version NUMBER) ...) > and do this optimization on it? > I think that will DTRT when compiled and when interpreted, > and it won't require changes in the code of the programs that use it. The conditions we want to test are sometimes/frequently expressed in terms of the (non-)existence of variables, etc. It would be inconvenient for package maintainers to have to determine "critical" Emacs version numbers to use. Also, it is possible for the condition to be dependent upon a minor version number, maybe. Why do you think a more restricted test of the version number would be better than a more general test? The changes to the code to convert from `if' to `hash-if' (or `static-if' as has been proposed) are minor - they just need amending the if/when/unless forms to hash-if. Also, there will not be all that many of them. That way, we have more flexibility than testing just the major version number. > That will handle `when' and `unless', since they expand into `if'. > It may be necessary to implement this in two places, one for inside of > function bodies and one for top level (outside of function > definitions). But the code for this should be so short that having > two is hardly much loss. The macro hash-if itself is very short, the current version taking 13 lines (including doc string), including a condition-case checking for `eval' having only one parameter. The idea is that a package maintainer can copy this directly into her source code (inside an (if (not (fboundp 'hash-if)) ....)) so the mechanism will work also in older Emacsen. > -- > Dr Richard Stallman (https://stallman.org) > Chief GNUisance of the GNU Project (https://gnu.org) > Founder, Free Software Foundation (https://fsf.org) > Internet Hall-of-Famer (https://internethalloffame.org) -- Alan Mackenzie (Nuremberg, Germany).
Re: Why shouldn't we have a #if .... #else .... #endif construct in Emacs Lisp?
Author: Stefan Kangas
Date: Sat, 02 Sep 2023 12:37
Date: Sat, 02 Sep 2023 12:37
19 lines
716 bytes
716 bytes
Philip Kaludercic <philipk@posteo.net> writes: > Alan Mackenzie <acm@muc.de> writes: > >> +;; Note: `static-if' handles the version of `eval' without the &optional >> +;; parameter LEXICAL so that it can be copied unchanged for use in older >> +;; Emacsen. > > Is this really a concern for the version that would be added to Emacs itself? I think we can have our cake and eat it by adding the non-nil LEXICAL parameter and changing the comment to: ;; Remove the &optional parameter LEXICAL for `eval' if this needs ;; to work in Emacs version 24.3 or older. That way, there can be no absolutely confusion about when it would need to be removed, and packages that don't need to will use lexical-binding.
Re: Why shouldn't we have a #if .... #else .... #endif construct in Emacs Lisp?
Author: Alan Mackenzie
Date: Sat, 02 Sep 2023 15:06
Date: Sat, 02 Sep 2023 15:06
144 lines
6002 bytes
6002 bytes
Hello, Stefan. On Wed, Aug 30, 2023 at 20:17:48 +0200, Stefan Kangas wrote: > Alan Mackenzie <acm@muc.de> writes: > > I looked at APEL, and its code was near identical to what I (with help > > from PK) wrote. I'd have nothing against the name static-if instead. > > As long as this doesn't raise copyright assignment problems, assuming > > the authors of APEL haven't assigned copyright to the FSF. > I think it's fine as far as copyright goes. You came up with your > version independently, before even looking at their code. We even > have a public record of that right here on this list. IANAL, but the > name `static-if' in itself is also not copyrightable, AFAIU. OK, static-if it is. I think the code and documentation are ready to be committed. For anybody who wants one last check, here's the intended patch: diff --git a/doc/lispref/control.texi b/doc/lispref/control.texi index 3aee9dd80e4..41e5cb148e5 100644 --- a/doc/lispref/control.texi +++ b/doc/lispref/control.texi @@ -36,13 +36,14 @@ Control Structures structure constructs (@pxref{Macros}). @menu -* Sequencing:: Evaluation in textual order. -* Conditionals:: @code{if}, @code{cond}, @code{when}, @code{unless}. -* Combining Conditions:: @code{and}, @code{or}, @code{not}, and friends. +* Sequencing:: Evaluation in textual order. +* Conditionals:: @code{if}, @code{cond}, @code{when}, @code{unless}. +* Combining Conditions:: @code{and}, @code{or}, @code{not}, and friends. * Pattern-Matching Conditional:: How to use @code{pcase} and friends. -* Iteration:: @code{while} loops. -* Generators:: Generic sequences and coroutines. -* Nonlocal Exits:: Jumping out of a sequence. +* Iteration:: @code{while} loops. +* Generators:: Generic sequences and coroutines. +* Nonlocal Exits:: Jumping out of a sequence. +* Conditional Compilation:: A facility like C's #if. @end menu @node Sequencing @@ -2467,3 +2468,48 @@ Cleanups @code{ftp-setup-buffer} returns but before the variable @code{process} is set, the process will not be killed. There is no easy way to fix this bug, but at least it is very unlikely. + +@node Conditional Compilation +@section Conditional Compilation + + There will be times when you want certain code to be compiled only +when a certain condition holds. This is particularly the case when +maintaining Emacs packages; to keep the package compatible with older +versions of Emacs you may need to use a function or variable which has +become obsolete in the current version of Emacs. + + You could just use a conditional form to select the old or new form +at run time, but this tends to output annoying warning messages about +the obsolete function/variable. For such situations, the macro +@code{static-if} comes in handy. It is inspired by the conditional +compilation directives like @code{#if} in C like languages, and is +patterned after the special form @code{if} (@pxref{Conditionals}). + + To use this facility for an older version of Emacs, copy the source +for @code{static-if} from the Emacs source file @file{lisp/subr.el} +into your package. + +@defmac static-if condition then-form else-forms... +Test @var{condition} at macro-expansion time. If its value is +non-@code{nil}, expand the macro to @var{then-form}, otherwise expand +it to @var{else-forms} enclosed in a @code{progn}. @var{else-forms} +may be empty. + +Here is an example of its use from CC Mode, which prevents a +@code{defadvice} form being compiled in newer versions of Emacs: +@example +@group +(static-if (boundp 'comment-line-break-function) + (progn) + (defvar c-inside-line-break-advice nil) + (defadvice indent-new-comment-line (around c-line-break-advice + activate preactivate) + "Call `c-indent-new-comment-line' if in CC Mode." + (if (or c-inside-line-break-advice + (not c-buffer-is-cc-mode)) + ad-do-it + (let ((c-inside-line-break-advice t)) + (c-indent-new-comment-line (ad-get-arg 0)))))) +@end group +@end example +@end defmac diff --git a/etc/NEWS b/etc/NEWS index 5c11b6b9ac7..4e7e185c8bc 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -855,6 +855,10 @@ Use 'define-minor-mode' and 'define-globalized-minor-mode' instead. See the "(elisp) Porting Old Advice" node for help converting them to use 'advice-add' or 'define-advice' instead. ++++ +** There is now conditional compilation, based on the C language's #if. +To use this, see the new macro 'static-if'. + +++ ** Desktop notifications are now supported on the Haiku operating system. The new function 'haiku-notifications-notify' provides a subset of the diff --git a/lisp/subr.el b/lisp/subr.el index 47fcbc2f317..1a7d8aadd46 100644 --- a/lisp/subr.el +++ b/lisp/subr.el @@ -277,6 +277,23 @@ pop (macroexp-let2 macroexp-copyable-p x getter `(prog1 ,x ,(funcall setter `(cdr ,x)))))))) +;; Note: `static-if' handles the version of `eval' without the &optional +;; parameter LEXICAL so that it can be copied unchanged for use in older +;; Emacsen. +(defmacro static-if (condition then-form &rest else-forms) + "A conditional compilation macro analogous to C's #if. +Evaluate CONDITION at macro-expansion time. If it is non-nil, +expand the macro to THEN-FORM. Otherwise expand it to ELSE-FORMS +enclosed in a `progn' form. ELSE-FORMS may be empty." + (declare (indent 2) + (debug (sexp sexp &rest sexp))) + (if (condition-case err + (eval condition lexical-binding) + ((wrong-number-of-arguments void-variable) (eval condition)) + ((debug error) (signal (car err) (cdr err)))) + then-form + (cons 'progn else-forms))) + (defmacro when (cond &rest body) "If COND yields non-nil, do BODY, else return nil. When COND yields non-nil, eval BODY forms sequentially and return -- Alan Mackenzie (Nuremberg, Germany).
Re: Why shouldn't we have a #if .... #else .... #endif construct in Emacs Lisp?
Author: Eli Zaretskii
Date: Sat, 02 Sep 2023 18:17
Date: Sat, 02 Sep 2023 18:17
56 lines
2500 bytes
2500 bytes
> Date: Sat, 2 Sep 2023 15:06:46 +0000 > Cc: emacs-devel@gnu.org, > Mattias EngdegƄrd <mattiase@acm.org> > From: Alan Mackenzie <acm@muc.de> > > +@node Conditional Compilation > +@section Conditional Compilation > + > + There will be times when you want certain code to be compiled only > +when a certain condition holds. This is particularly the case when > +maintaining Emacs packages; to keep the package compatible with older > +versions of Emacs you may need to use a function or variable which has > +become obsolete in the current version of Emacs. > + > + You could just use a conditional form to select the old or new form > +at run time, but this tends to output annoying warning messages about > +the obsolete function/variable. For such situations, the macro > +@code{static-if} comes in handy. It is inspired by the conditional > +compilation directives like @code{#if} in C like languages, and is > +patterned after the special form @code{if} (@pxref{Conditionals}). > + > + To use this facility for an older version of Emacs, copy the source > +for @code{static-if} from the Emacs source file @file{lisp/subr.el} > +into your package. Thanks, but I think the references to #if make the documentation less helpful than it could be. This manual is for Lisp programmers, and those are not necessarily familiar with C and its preprocessor directives. So I think it would be better if you removed the references to cpp. If you think removing that would make the documentation less self-explanatory, I suggest to add explanations that are based on Lisp and on typical situations while writing Lisp programs, not on cpp. > --- a/etc/NEWS > +++ b/etc/NEWS > @@ -855,6 +855,10 @@ Use 'define-minor-mode' and 'define-globalized-minor-mode' instead. > See the "(elisp) Porting Old Advice" node for help converting them > to use 'advice-add' or 'define-advice' instead. > > ++++ > +** There is now conditional compilation, based on the C language's #if. > +To use this, see the new macro 'static-if'. Same here. Here, it is actually worse: "based on C language's #if" could be misinterpreted as meaning the implementation is based on #if in some way. I would suggest the following text in NEWS: ** New macro 'static-if' for conditional byte-compilation of code. This macro hides a form from the byte-compiler based on a compile-time condition. This is handy for avoiding byte-compilation warnings about code that will never actually run under some conditions. Thanks.
Re: Why shouldn't we have a #if .... #else .... #endif construct in Emacs Lisp?
Author: Stefan Monnier v
Date: Sat, 02 Sep 2023 19:09
Date: Sat, 02 Sep 2023 19:09
25 lines
892 bytes
892 bytes
> --8<---------------cut here---------------start------------->8--- > (defmacro cif (test then &rest else) > "Evaluate TEST during macro-expansion and return THEN or ELSE." > (if (eval test t) then else)) > --8<---------------cut here---------------end--------------->8--- FWIW I've used such macros in packages under the name `<PKG>--if-when-compile`. Also, FWIW, I've used the following variant to let the compile-time check be reconsidered at runtime: (defmacro TeX--if-macro-fboundp (name then &rest else) "..." (declare (indent 2) (debug (symbolp form &rest form))) (if (fboundp name) ;If macro exists at compile-time, just use it. then `(if (fboundp ',name) ;Else, check if it exists at run-time. (eval ',then) ;If it does, then run the then code. ,@else))) -- Stefan
Re: Why shouldn't we have a #if .... #else .... #endif construct in Emacs Lisp?
Author: Stefan Monnier v
Date: Sat, 02 Sep 2023 19:12
Date: Sat, 02 Sep 2023 19:12
27 lines
897 bytes
897 bytes
>> > In C, we have the very useful conditional compilation >> > directives introduced by #if or #ifdef, etc., which end at >> > #end. >> >> Those are directives to the C preprocessor and some people say >> it is a sign of weakness such a thing is even necessary to >> begin with. >> >> Let's see if they are right! >> >> What problem do you have? If we can solve it in Elisp, we >> cannot say those people saying that are wrong. >> > > FWIW, Common Lisp has reader macros to solve the problem: > http://clhs.lisp.se/Body/24_aba.htm I don't see why reader macros would be needed here. Reader macros are useful to introduce funny new shorthands or to avoid *reading* a chunk of code (e.g. because it uses some unsupported funny syntax) but in the present case we can read both branches of the `if` just fine, we just want to throw away one of the two before we macro-expand it. Stefan
Re: Why shouldn't we have a #if .... #else .... #endif construct in Emacs Lisp?
Author: Philip Kaluderci
Date: Sat, 02 Sep 2023 19:20
Date: Sat, 02 Sep 2023 19:20
23 lines
929 bytes
929 bytes
Alan Mackenzie <acm@muc.de> writes: > +;; Note: `static-if' handles the version of `eval' without the &optional > +;; parameter LEXICAL so that it can be copied unchanged for use in older > +;; Emacsen. Is this really a concern for the version that would be added to Emacs itself? > +(defmacro static-if (condition then-form &rest else-forms) > + "A conditional compilation macro analogous to C's #if. > +Evaluate CONDITION at macro-expansion time. If it is non-nil, > +expand the macro to THEN-FORM. Otherwise expand it to ELSE-FORMS > +enclosed in a `progn' form. ELSE-FORMS may be empty." > + (declare (indent 2) > + (debug (sexp sexp &rest sexp))) > + (if (condition-case err > + (eval condition lexical-binding) > + ((wrong-number-of-arguments void-variable) (eval condition)) > + ((debug error) (signal (car err) (cdr err)))) > + then-form > + (cons 'progn else-forms)))
Re: Why shouldn't we have a #if .... #else .... #endif construct in Emacs Lisp?
Author: Alan Mackenzie
Date: Sat, 02 Sep 2023 19:43
Date: Sat, 02 Sep 2023 19:43
91 lines
3856 bytes
3856 bytes
Hello, Eli. Thanks for the feedback. On Sat, Sep 02, 2023 at 18:17:51 +0300, Eli Zaretskii wrote: > > Date: Sat, 2 Sep 2023 15:06:46 +0000 > > Cc: emacs-devel@gnu.org, > > Mattias EngdegƄrd <mattiase@acm.org> > > From: Alan Mackenzie <acm@muc.de> > > +@node Conditional Compilation > > +@section Conditional Compilation > > + > > + There will be times when you want certain code to be compiled only > > +when a certain condition holds. This is particularly the case when > > +maintaining Emacs packages; to keep the package compatible with older > > +versions of Emacs you may need to use a function or variable which has > > +become obsolete in the current version of Emacs. > > + > > + You could just use a conditional form to select the old or new form > > +at run time, but this tends to output annoying warning messages about > > +the obsolete function/variable. For such situations, the macro > > +@code{static-if} comes in handy. It is inspired by the conditional > > +compilation directives like @code{#if} in C like languages, and is > > +patterned after the special form @code{if} (@pxref{Conditionals}). > > + > > + To use this facility for an older version of Emacs, copy the source > > +for @code{static-if} from the Emacs source file @file{lisp/subr.el} > > +into your package. > Thanks, but I think the references to #if make the documentation less > helpful than it could be. This manual is for Lisp programmers, and > those are not necessarily familiar with C and its preprocessor > directives. So I think it would be better if you removed the > references to cpp. If you think removing that would make the > documentation less self-explanatory, I suggest to add explanations > that are based on Lisp and on typical situations while writing Lisp > programs, not on cpp. OK, I've removed the bit "It is inspired by .... C like languages" leaving just "It is patterned after the special form @code{if} ..." of the sentence. I thought the comparison with C might be helpful for a lot of users, but I can see how it might be confusing instead. > > --- a/etc/NEWS > > +++ b/etc/NEWS > > @@ -855,6 +855,10 @@ Use 'define-minor-mode' and 'define-globalized-minor-mode' instead. > > See the "(elisp) Porting Old Advice" node for help converting them > > to use 'advice-add' or 'define-advice' instead. > > > > ++++ > > +** There is now conditional compilation, based on the C language's #if. > > +To use this, see the new macro 'static-if'. > Same here. Here, it is actually worse: "based on C language's #if" > could be misinterpreted as meaning the implementation is based on #if > in some way. I would suggest the following text in NEWS: > ** New macro 'static-if' for conditional byte-compilation of code. > This macro hides a form from the byte-compiler based on a > compile-time condition. This is handy for avoiding byte-compilation > warnings about code that will never actually run under some > conditions. static-if actually works for interpreted compilation as well as byte compilation, so I've removed two "byte-"s from your text, leaving: +++ ** New macro 'static-if' for conditional compilation of code. This macro hides a form from the compiler based on a compile-time condition. This is handy for avoiding byte-compilation warnings about code that will never actually run under some conditions. I think it's now ready to commit, except .... I've had some private email which suggested that perhaps static-if should not include the condition-case which copes with an ancient eval from before lexical binding. I can see some merit in the argument (lexical binding happened in 24.1, I think), but on the other hand, that extreme backwards compatibility doesn't really cost us anything (static-if is just 13 lines of code). What do you think? > Thanks. -- Alan Mackenzie (Nuremberg, Germany).
Re: Why shouldn't we have a #if .... #else .... #endif construct in Emacs Lisp?
Author: Alan Mackenzie
Date: Sat, 02 Sep 2023 19:58
Date: Sat, 02 Sep 2023 19:58
34 lines
1309 bytes
1309 bytes
Hello, Philip. On Sat, Sep 02, 2023 at 19:20:29 +0000, Philip Kaludercic wrote: > Alan Mackenzie <acm@muc.de> writes: > > +;; Note: `static-if' handles the version of `eval' without the &optional > > +;; parameter LEXICAL so that it can be copied unchanged for use in older > > +;; Emacsen. > Is this really a concern for the version that would be added to Emacs > itself? The idea was that there would be just one version, and a package maintainer could copy the 13 lines to the beginning of her package inside something like (when (not (fboundp 'static-if)) ....), but otherwise unchanged. > > +(defmacro static-if (condition then-form &rest else-forms) > > + "A conditional compilation macro analogous to C's #if. > > +Evaluate CONDITION at macro-expansion time. If it is non-nil, > > +expand the macro to THEN-FORM. Otherwise expand it to ELSE-FORMS > > +enclosed in a `progn' form. ELSE-FORMS may be empty." > > + (declare (indent 2) > > + (debug (sexp sexp &rest sexp))) > > + (if (condition-case err > > + (eval condition lexical-binding) > > + ((wrong-number-of-arguments void-variable) (eval condition)) > > + ((debug error) (signal (car err) (cdr err)))) > > + then-form > > + (cons 'progn else-forms))) -- Alan Mackenzie (Nuremberg, Germany).
Re: Why shouldn't we have a #if .... #else .... #endif construct in Emacs Lisp?
Author: Emanuel Berg
Date: Sun, 03 Sep 2023 02:18
Date: Sun, 03 Sep 2023 02:18
42 lines
1406 bytes
1406 bytes
Stefan Monnier via "Emacs development discussions." wrote: >>>> In C, we have the very useful conditional compilation >>>> directives introduced by #if or #ifdef, etc., which end >>>> at #end. >>> >>> Those are directives to the C preprocessor and some people >>> say it is a sign of weakness such a thing is even >>> necessary to begin with. >>> >>> Let's see if they are right! >>> >>> What problem do you have? If we can solve it in Elisp, we >>> cannot say those people saying that are wrong. >> >> FWIW, Common Lisp has reader macros to solve the problem: >> http://clhs.lisp.se/Body/24_aba.htm > > I don't see why reader macros would be needed here. > Reader macros are useful to introduce funny new shorthands > or to avoid *reading* a chunk of code (e.g. because it uses > some unsupported funny syntax) but in the present case we > can read both branches of the `if` just fine, we just want > to throw away one of the two before we macro-expand it. In general, Lisp macros seem much more powerful and versatile than the C preprocessor, and they are part of the language as well. But let's say preprocessor directives are part of the C language as well then even tho it doesn't feel like it, really. The question is then, is there anything you can do with the C preprocessor which you _cannot_ do in Lisp - with or without macros? -- underground experts united https://dataswamp.org/~incal
Re: Why shouldn't we have a #if .... #else .... #endif construct in Emacs Lisp?
Author: Eli Zaretskii
Date: Sun, 03 Sep 2023 07:42
Date: Sun, 03 Sep 2023 07:42
47 lines
2124 bytes
2124 bytes
> Date: Sat, 2 Sep 2023 19:43:29 +0000 > Cc: stefankangas@gmail.com, emacs-devel@gnu.org, mattiase@acm.org > From: Alan Mackenzie <acm@muc.de> > > > > ++++ > > > +** There is now conditional compilation, based on the C language's #if. > > > +To use this, see the new macro 'static-if'. > > > Same here. Here, it is actually worse: "based on C language's #if" > > could be misinterpreted as meaning the implementation is based on #if > > in some way. I would suggest the following text in NEWS: > > > ** New macro 'static-if' for conditional byte-compilation of code. > > This macro hides a form from the byte-compiler based on a > > compile-time condition. This is handy for avoiding byte-compilation > > warnings about code that will never actually run under some > > conditions. > > static-if actually works for interpreted compilation as well as byte > compilation, so I've removed two "byte-"s from your text, leaving: > > +++ > ** New macro 'static-if' for conditional compilation of code. > This macro hides a form from the compiler based on a compile-time > condition. This is handy for avoiding byte-compilation warnings about > code that will never actually run under some conditions. What is "interpreted compilation" in Emacs? I'm aware of only two compilers in Emacs: the byte compiler and the native compiler. So when you talk about "the compiler" above, what does that allude to? > I think it's now ready to commit, except .... > > I've had some private email which suggested that perhaps static-if > should not include the condition-case which copes with an ancient eval > from before lexical binding. I can see some merit in the argument > (lexical binding happened in 24.1, I think), but on the other hand, that > extreme backwards compatibility doesn't really cost us anything > (static-if is just 13 lines of code). > > What do you think? I don't think I understand the issue: it was discussed in private email , and you didn't tell enough for me to understand and form an opinion. What do you mean by "condition-case which copes with an ancient eval from before lexical binding"?
Re: Why shouldn't we have a #if .... #else .... #endif construct in Emacs Lisp?
Author: Alan Mackenzie
Date: Sun, 03 Sep 2023 10:48
Date: Sun, 03 Sep 2023 10:48
77 lines
3356 bytes
3356 bytes
Hello, Eli. On Sun, Sep 03, 2023 at 07:42:13 +0300, Eli Zaretskii wrote: > > Date: Sat, 2 Sep 2023 19:43:29 +0000 > > Cc: stefankangas@gmail.com, emacs-devel@gnu.org, mattiase@acm.org > > From: Alan Mackenzie <acm@muc.de> > > > > ++++ > > > > +** There is now conditional compilation, based on the C language's #if. > > > > +To use this, see the new macro 'static-if'. > > > Same here. Here, it is actually worse: "based on C language's #if" > > > could be misinterpreted as meaning the implementation is based on #if > > > in some way. I would suggest the following text in NEWS: > > > ** New macro 'static-if' for conditional byte-compilation of code. > > > This macro hides a form from the byte-compiler based on a > > > compile-time condition. This is handy for avoiding byte-compilation > > > warnings about code that will never actually run under some > > > conditions. > > static-if actually works for interpreted compilation as well as byte > > compilation, so I've removed two "byte-"s from your text, leaving: > > +++ > > ** New macro 'static-if' for conditional compilation of code. > > This macro hides a form from the compiler based on a compile-time > > condition. This is handy for avoiding byte-compilation warnings about > > code that will never actually run under some conditions. > What is "interpreted compilation" in Emacs? I'm aware of only two > compilers in Emacs: the byte compiler and the native compiler. So > when you talk about "the compiler" above, what does that allude to? I mean the defmacro and defun macros, particularly when invoked by C-M-x, etc. Do we have a generic term for these, regardless of whether they are called interpretatively or in the context of byte/native compilation? > > I think it's now ready to commit, except .... > > I've had some private email which suggested that perhaps static-if > > should not include the condition-case which copes with an ancient eval > > from before lexical binding. I can see some merit in the argument > > (lexical binding happened in 24.1, I think), but on the other hand, that > > extreme backwards compatibility doesn't really cost us anything > > (static-if is just 13 lines of code). > > What do you think? > I don't think I understand the issue: it was discussed in private > email , and you didn't tell enough for me to understand and form an > opinion. What do you mean by "condition-case which copes with an > ancient eval from before lexical binding"? Sorry. The idea is that package maintainers can copy the source of static-if directly into their packages so as to be able to use it in older Emacsen. In the code for static-if, there's a call to eval with two arguments, CONDITION and lexical-binding. In (very) old versions of Emacs, eval would only accept one argument, the form. So in such an old Emacs, static-if will throw a wrong-number-of-args (or void-variable) error. I have proposed catching this error with a condition-case and in the handler, calling eval again with just one argument. The other party in the email has opined that static-if should not contain this condition-case mechanism, and anybody writing for such an old Emacs should make their own adjustments. Perhaps it's too small a point to be worth bothering about, but I thought I'd ask your view anyway. -- Alan Mackenzie (Nuremberg, Germany).
Re: Why shouldn't we have a #if .... #else .... #endif construct in Emacs Lisp?
Author: =?UTF-8?B?Sm/Do2
Date: Sun, 03 Sep 2023 13:27
Date: Sun, 03 Sep 2023 13:27
66 lines
3146 bytes
3146 bytes
--0000000000004541320604738587 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable On Sun, Sep 3, 2023, 00:15 Stefan Monnier via Emacs development discussions. <emacs-devel@gnu.org> wrote: > > > > FWIW, Common Lisp has reader macros to solve the problem: > > http://clhs.lisp.se/Body/24_aba.htm > > I don't see why reader macros would be needed here. > I didn't say they are "needed" to solve it. I merely said they would. And they do, quite effectively in Common Lisp, precisely for the C-like use cases presented here as paradigmatic. But as always there are multiple ways to skin a cat. CL's is particularly good IMO, and much more versatile than what is being proposed here. It skins this and more cats. For example it doesn't require changing the indentation of the form being ifdef'ed out. And the property of making some code invisible to the reader is great for adding/removing arguments conditionally in calls based on read-time knowledge. Anyway, I'm taking about a particular type of reader macro called "feature expressions" and that's what I linked to. João --0000000000004541320604738587 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable <div dir="auto"><div><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Sun, Sep 3, 2023, 00:15 Stefan Monnier via Emacs development discussions. <<a href="mailto:emacs-devel@gnu.org" rel="noreferrer noreferrer noreferrer noreferrer" target="_blank">emacs-devel@gnu.org</a>> wrote:</div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"> ><br> > FWIW, Common Lisp has reader macros to solve the problem:<br> > <a href="http://clhs.lisp.se/Body/24_aba.htm" rel="noreferrer noreferrer noreferrer noreferrer noreferrer noreferrer" target="_blank">http://clhs.lisp.se/Body/24_aba.htm</a><br> <br> I don't see why reader macros would be needed here.  <br></blockquote></div></div><div dir="auto"><br></div><div dir="auto">I didn't say they are "needed" to solve it. I merely said they would. And they do, quite effectively in Common Lisp, precisely for the C-like use cases presented here as paradigmatic.</div><div dir="auto"><br></div><div dir="auto">But as always there are multiple ways to skin a cat. </div><div dir="auto"><br></div><div dir="auto">CL's is particularly good IMO, and much more versatile than what is being proposed here. It skins this and more cats. For example it doesn't require changing the indentation of the form being ifdef'ed out. And the property of making some code invisible to the reader is great for adding/removing arguments conditionally in calls based on read-time knowledge. </div><div dir="auto"><br></div><div dir="auto">Anyway, I'm taking about a particular type of reader macro called "feature expressions" and that's what I linked to.</div><div dir="auto"><br></div><div dir="auto">João</div></div> --0000000000004541320604738587--
Re: Why shouldn't we have a #if .... #else .... #endif construct in Emacs Lisp?
Author: Eli Zaretskii
Date: Sun, 03 Sep 2023 14:02
Date: Sun, 03 Sep 2023 14:02
56 lines
2573 bytes
2573 bytes
> Date: Sun, 3 Sep 2023 10:48:50 +0000 > Cc: stefankangas@gmail.com, emacs-devel@gnu.org, mattiase@acm.org > From: Alan Mackenzie <acm@muc.de> > > > > static-if actually works for interpreted compilation as well as byte > > > compilation, so I've removed two "byte-"s from your text, leaving: > > > > +++ > > > ** New macro 'static-if' for conditional compilation of code. > > > This macro hides a form from the compiler based on a compile-time > > > condition. This is handy for avoiding byte-compilation warnings about > > > code that will never actually run under some conditions. > > > What is "interpreted compilation" in Emacs? I'm aware of only two > > compilers in Emacs: the byte compiler and the native compiler. So > > when you talk about "the compiler" above, what does that allude to? > > I mean the defmacro and defun macros, particularly when invoked by C-M-x, > etc. Do we have a generic term for these, regardless of whether they are > called interpretatively or in the context of byte/native compilation? "Evaluation"? > > > I've had some private email which suggested that perhaps static-if > > > should not include the condition-case which copes with an ancient eval > > > from before lexical binding. I can see some merit in the argument > > > (lexical binding happened in 24.1, I think), but on the other hand, that > > > extreme backwards compatibility doesn't really cost us anything > > > (static-if is just 13 lines of code). > > > > What do you think? > > > I don't think I understand the issue: it was discussed in private > > email , and you didn't tell enough for me to understand and form an > > opinion. What do you mean by "condition-case which copes with an > > ancient eval from before lexical binding"? > > Sorry. The idea is that package maintainers can copy the source of > static-if directly into their packages so as to be able to use it in > older Emacsen. > > In the code for static-if, there's a call to eval with two > arguments, CONDITION and lexical-binding. In (very) old versions of > Emacs, eval would only accept one argument, the form. So in such an old > Emacs, static-if will throw a wrong-number-of-args (or void-variable) > error. > > I have proposed catching this error with a condition-case and in the > handler, calling eval again with just one argument. > > The other party in the email has opined that static-if should not contain > this condition-case mechanism, and anybody writing for such an old Emacs > should make their own adjustments. I tend to agree with "the other party", FWIW.
Thread Navigation
This is a paginated view of messages in the thread with full content displayed inline.
Messages are displayed in chronological order, with the original post highlighted in green.
Use pagination controls to navigate through all messages in large threads.
Back to All Threads