* The poor state of documentation of pcase like things. @ 2015-12-16 20:26 Alan Mackenzie 2015-12-16 20:53 ` Kaushal Modi ` (3 more replies) 0 siblings, 4 replies; 375+ messages in thread From: Alan Mackenzie @ 2015-12-16 20:26 UTC (permalink / raw) To: emacs-devel Hello, Emacs. Months after recognising that the documentation of pcase like things is in need of vast improvement, we haven't advanced significantly. We appear to have the following functions/macros: pcase, pcase-let, pcase-let*, pcase-codegen, pcase-defmacro, pcase-dolist, pcase-exhaustive, and pcase-lambda. NONE OF THESE, with the exception of pcase itself, IS EVEN MENTIONED IN THE ELISP MANUAL. NONE OF THESE, with the exception of pcase itself, HAS A MEANINGFUL DOC STRING. Some of these doc strings are patronising indeed. They all seem to say, implicitly, "the author's time is far too valuable to waste in writing meaningful documentation". Particularly egregious is the doc string for pcase-exhaustive: "The exhaustive version of `pcase' (which see).". Uhh???? Needless to say, the doc string of pcase makes no mention of "exhaustive". Let us analyse the documentation of the one macro which is documented to any meaningful extent, pcase itself: The article in the Elisp manual for pcase starts well, documenting the basic form and outlining the basic semantics, but then starts rambling on like a tutorial, rather than filling in the semantic details. Here is a partial list of what is missing from that manual page: (i) A @dfn{U-PATTERN}. (ii) A @dfn{Q-PATTERN}. These two things are described only in terms of their structure, not what they are conceptually. What do "U" and "Q" stand for? What is the semantic significance of a Q-PATTERN? (iii) A statement that ` is not ` and , is not ,. (iv) A rigorous specification of what ` and , (and ,@?) mean in pcase patterns. (v) A rigorous specification of when variables get bound, and what they get bound to. (vi) A rigorous specification of when a value matches a pattern. Now, let's have a look a pcase's doc string. It doesn't say what pcase does: "perform ML-style pattern matching" is meaningless to anybody who doesn't know ML-style pattern matching. What it should say is that the value is used to select (at most) one of the CASES, and the forms in that CASE are evaluated - or something like that. It would appear that Lisp programmers are expected to absorb the semantics (and sometimes even the syntax) of pcase-* by osmosis: studying and imitating examples. This is a Bad Thing. Most (?all) of the rest of Emacs Lisp is effectively and rigorously documented. For example, both the Elisp manual entry and the doc string for cond are effective. There are people on this list who are using pcase like things, and so clearly understand their syntax and semantics. Could these people PLEASE document these things, and do so before the release of Emacs 25.1. Preferably well before. -- Alan Mackenzie (Nuremberg, Germany). ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: The poor state of documentation of pcase like things. 2015-12-16 20:26 The poor state of documentation of pcase like things Alan Mackenzie @ 2015-12-16 20:53 ` Kaushal Modi 2015-12-17 16:34 ` John Wiegley 2015-12-18 0:42 ` John Wiegley 2015-12-16 21:01 ` Drew Adams ` (2 subsequent siblings) 3 siblings, 2 replies; 375+ messages in thread From: Kaushal Modi @ 2015-12-16 20:53 UTC (permalink / raw) To: Alan Mackenzie; +Cc: Emacs developers +1 I would welcome a short tutorial on how (and why) to use pcase. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: The poor state of documentation of pcase like things. 2015-12-16 20:53 ` Kaushal Modi @ 2015-12-17 16:34 ` John Wiegley 2015-12-17 19:22 ` Kaushal Modi ` (3 more replies) 2015-12-18 0:42 ` John Wiegley 1 sibling, 4 replies; 375+ messages in thread From: John Wiegley @ 2015-12-17 16:34 UTC (permalink / raw) To: Kaushal Modi; +Cc: Alan Mackenzie, Emacs developers >>>>> Kaushal Modi <kaushal.modi@gmail.com> writes: > I would welcome a short tutorial on how (and why) to use pcase. There are several examples shown here: http://www.emacswiki.org/emacs/PatternMatching pcase makes a lot more sense if you're used to pattern matching in functional languages, where you describe a pattern (not unlike destructuring-bind) whose "shape" is intended to match the set of shapes you want to successful match against. Since pattern matching like this isn't something I had ever encountered outside of FP, I agree that a tutorial is in order. I'm willing to volunteer for this. -- John Wiegley GPG fingerprint = 4710 CF98 AF9B 327B B80F http://newartisans.com 60E1 46C4 BD1A 7AC1 4BA2 ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: The poor state of documentation of pcase like things. 2015-12-17 16:34 ` John Wiegley @ 2015-12-17 19:22 ` Kaushal Modi 2015-12-17 21:16 ` Phillip Lord ` (2 subsequent siblings) 3 siblings, 0 replies; 375+ messages in thread From: Kaushal Modi @ 2015-12-17 19:22 UTC (permalink / raw) To: Kaushal Modi, Alan Mackenzie, Emacs developers > There are several examples shown here: > > http://www.emacswiki.org/emacs/PatternMatching > Thanks John. I have no experience with functional programming and so I did not understand the "shape" explanation. But now that I got some clue as to what to look for online, I will do some digging. I will start with the emacswiki page you pointed. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: The poor state of documentation of pcase like things. 2015-12-17 16:34 ` John Wiegley 2015-12-17 19:22 ` Kaushal Modi @ 2015-12-17 21:16 ` Phillip Lord 2015-12-17 21:56 ` Drew Adams 2015-12-18 7:15 ` Eli Zaretskii 2015-12-17 21:26 ` Alan Mackenzie 2015-12-19 15:31 ` Michael Heerdegen 3 siblings, 2 replies; 375+ messages in thread From: Phillip Lord @ 2015-12-17 21:16 UTC (permalink / raw) To: Kaushal Modi; +Cc: Alan Mackenzie, Emacs developers John Wiegley <jwiegley@gmail.com> writes: >>>>>> Kaushal Modi <kaushal.modi@gmail.com> writes: > >> I would welcome a short tutorial on how (and why) to use pcase. > > There are several examples shown here: > > http://www.emacswiki.org/emacs/PatternMatching > > pcase makes a lot more sense if you're used to pattern matching in functional > languages, where you describe a pattern (not unlike destructuring-bind) whose > "shape" is intended to match the set of shapes you want to successful match > against. > > Since pattern matching like this isn't something I had ever encountered > outside of FP, I agree that a tutorial is in order. I'm willing to volunteer > for this. I'll have a go at the docstrings. I only found out about pcase recently. It's a very useful tool, and it deserves more use. Could I suggest it be promoted in the manual a little. Currently, it's a subnode of "conditionals", but pattern match is really a form of control flow in its own right. Phil ^ permalink raw reply [flat|nested] 375+ messages in thread
* RE: The poor state of documentation of pcase like things. 2015-12-17 21:16 ` Phillip Lord @ 2015-12-17 21:56 ` Drew Adams 2015-12-17 22:22 ` Phillip Lord 2015-12-18 7:15 ` Eli Zaretskii 1 sibling, 1 reply; 375+ messages in thread From: Drew Adams @ 2015-12-17 21:56 UTC (permalink / raw) To: phillip.lord, Kaushal Modi; +Cc: Alan Mackenzie, Emacs developers > pattern match is really a form of control flow in its own right. OT, but no, pattern matching per se has nothing to do with control flow. You can *combine* pattern matching with control flow (as `pcase' does, testing the results of pattern-match binding to control the flow). But pattern matching itself does not imply any effect on control flow. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: The poor state of documentation of pcase like things. 2015-12-17 21:56 ` Drew Adams @ 2015-12-17 22:22 ` Phillip Lord 0 siblings, 0 replies; 375+ messages in thread From: Phillip Lord @ 2015-12-17 22:22 UTC (permalink / raw) To: Drew Adams; +Cc: Alan Mackenzie, Emacs developers, Kaushal Modi Drew Adams <drew.adams@oracle.com> writes: >> pattern match is really a form of control flow in its own right. > > OT, but no, pattern matching per se has nothing to do with control flow. > > You can *combine* pattern matching with control flow (as `pcase' does, > testing the results of pattern-match binding to control the flow). But > pattern matching itself does not imply any effect on control flow. You are right. Currently, only pcase is documented though, hence my (badly worded) statement. Possibly the solution is to introduce a generic "pattern matching" node, and then have much shorter descriptions for pcase in control flow, and the other functions elsewhere. Phil ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: The poor state of documentation of pcase like things. 2015-12-17 21:16 ` Phillip Lord 2015-12-17 21:56 ` Drew Adams @ 2015-12-18 7:15 ` Eli Zaretskii 2015-12-18 9:12 ` Rasmus ` (3 more replies) 1 sibling, 4 replies; 375+ messages in thread From: Eli Zaretskii @ 2015-12-18 7:15 UTC (permalink / raw) To: Phillip Lord; +Cc: acm, emacs-devel, kaushal.modi > From: phillip.lord@russet.org.uk (Phillip Lord) > Date: Thu, 17 Dec 2015 21:16:56 +0000 > Cc: Alan Mackenzie <acm@muc.de>, Emacs developers <emacs-devel@gnu.org> > > Could I suggest [pcase] be promoted in the manual a > little. Currently, it's a subnode of "conditionals", but pattern > match is really a form of control flow in its own right. If that's your itch, feel free to scratch it. IMO, that's largely a waste of your time and energy: the manual is rarely if ever read in its entirety, or even in large portions. Most of its uses is to quickly find the subject whose description you need, hopefully by using the Info-index command ("i TOPIC RET"), and read that and perhaps some of the cross-references there. With this use case, the level on which a description is found is irrelevant. Btw, the importance is in the eyes of the beholder. You look at that through the glasses of someone who hacks Emacs core. Try to take the POV of a casual Lisper who just wants to put some advanced customizations in her ~/.emacs, for example. IOW, advanced features and subjects are frequently very important to power users, but much less so to "mere mortals". The manual is supposed to serve both types of audience. Bottom line: what we do need is make the description clear and complete. Where it appears is orders of magnitude less important. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: The poor state of documentation of pcase like things. 2015-12-18 7:15 ` Eli Zaretskii @ 2015-12-18 9:12 ` Rasmus 2015-12-18 9:21 ` Eli Zaretskii 2015-12-18 10:30 ` Phillip Lord ` (2 subsequent siblings) 3 siblings, 1 reply; 375+ messages in thread From: Rasmus @ 2015-12-18 9:12 UTC (permalink / raw) To: emacs-devel Eli Zaretskii <eliz@gnu.org> writes: >> Could I suggest [pcase] be promoted in the manual a >> little. Currently, it's a subnode of "conditionals", but pattern >> match is really a form of control flow in its own right. > > If that's your itch, feel free to scratch it. > > IMO, that's largely a waste of your time and energy: the manual is > rarely if ever read in its entirety, or even in large portions. Most > of its uses is to quickly find the subject whose description you need, > hopefully by using the Info-index command ("i TOPIC RET"), and read > that and perhaps some of the cross-references there. With this use > case, the level on which a description is found is irrelevant. But by lifting it, it would appear more prominently in the TOC. This might cause interest on its own (I’m thinking about the pdf/tex version here). Rasmus -- I hear there's rumors on the, uh, Internets. . . ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: The poor state of documentation of pcase like things. 2015-12-18 9:12 ` Rasmus @ 2015-12-18 9:21 ` Eli Zaretskii 2015-12-18 9:57 ` Rasmus ` (2 more replies) 0 siblings, 3 replies; 375+ messages in thread From: Eli Zaretskii @ 2015-12-18 9:21 UTC (permalink / raw) To: Rasmus; +Cc: emacs-devel > From: Rasmus <rasmus@gmx.us> > Date: Fri, 18 Dec 2015 10:12:00 +0100 > > > IMO, that's largely a waste of your time and energy: the manual is > > rarely if ever read in its entirety, or even in large portions. Most > > of its uses is to quickly find the subject whose description you need, > > hopefully by using the Info-index command ("i TOPIC RET"), and read > > that and perhaps some of the cross-references there. With this use > > case, the level on which a description is found is irrelevant. > > But by lifting it, it would appear more prominently in the TOC. Only in the printed book, maybe. The TOC of the Info manual is flat: all the nodes appear on the same level. Are printed or PDF manuals being used a lot these days, in preference to the Info manual? Besides, did you ever see anyone read the TOC of a large manual? I didn't. I guess someone might do that, but I cannot imagine this being a frequent use case. Once again, I won't object to such a change, I just think there are lots and lots of much more important things that can and should be done in Emacs development, even in the documentation area. I'd love to see the available scarce resource we have applied in those more important areas, if possible. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: The poor state of documentation of pcase like things. 2015-12-18 9:21 ` Eli Zaretskii @ 2015-12-18 9:57 ` Rasmus 2015-12-18 10:13 ` David Kastrup 2015-12-18 12:23 ` Marcin Borkowski 2 siblings, 0 replies; 375+ messages in thread From: Rasmus @ 2015-12-18 9:57 UTC (permalink / raw) To: eliz; +Cc: emacs-devel Hi, Eli Zaretskii <eliz@gnu.org> writes: >> But by lifting it, it would appear more prominently in the TOC. > > Only in the printed book, maybe. The TOC of the Info manual is flat: > all the nodes appear on the same level. Are printed or PDF manuals > being used a lot these days, in preference to the Info manual? I very much like the pdf manuals. They are the prettiest. I also use the Info and html versions, depending on mode. > Besides, did you ever see anyone read the TOC of a large manual? I > didn't. I guess someone might do that, but I cannot imagine this > being a frequent use case. I do. I cannot speak for other people. > Once again, I won't object to such a change, I just think there are > lots and lots of much more important things that can and should be > done in Emacs development, even in the documentation area. I'd love > to see the available scarce resource we have applied in those more > important areas, if possible. I believe you. Rasmus -- Hvor meget poesi tror De kommer ud af et glas isvand? ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: The poor state of documentation of pcase like things. 2015-12-18 9:21 ` Eli Zaretskii 2015-12-18 9:57 ` Rasmus @ 2015-12-18 10:13 ` David Kastrup 2015-12-18 10:47 ` Eli Zaretskii 2015-12-18 12:23 ` Marcin Borkowski 2 siblings, 1 reply; 375+ messages in thread From: David Kastrup @ 2015-12-18 10:13 UTC (permalink / raw) To: Eli Zaretskii; +Cc: Rasmus, emacs-devel Eli Zaretskii <eliz@gnu.org> writes: >> From: Rasmus <rasmus@gmx.us> >> Date: Fri, 18 Dec 2015 10:12:00 +0100 >> >> > IMO, that's largely a waste of your time and energy: the manual is >> > rarely if ever read in its entirety, or even in large portions. Most >> > of its uses is to quickly find the subject whose description you need, >> > hopefully by using the Info-index command ("i TOPIC RET"), and read >> > that and perhaps some of the cross-references there. With this use >> > case, the level on which a description is found is irrelevant. >> >> But by lifting it, it would appear more prominently in the TOC. > > Only in the printed book, maybe. The TOC of the Info manual is flat: > all the nodes appear on the same level. Are we talking about the same Info manual here? That of Emacs? That with the — The Detailed Node Listing — ——————————— Here are some other nodes which are really subnodes of the ones already listed, mentioned here so you can get to them in one step: section? -- David Kastrup ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: The poor state of documentation of pcase like things. 2015-12-18 10:13 ` David Kastrup @ 2015-12-18 10:47 ` Eli Zaretskii 2015-12-18 16:44 ` Phillip Lord 0 siblings, 1 reply; 375+ messages in thread From: Eli Zaretskii @ 2015-12-18 10:47 UTC (permalink / raw) To: David Kastrup; +Cc: rasmus, emacs-devel > From: David Kastrup <dak@gnu.org> > Cc: Rasmus <rasmus@gmx.us>, emacs-devel@gnu.org > Date: Fri, 18 Dec 2015 11:13:18 +0100 > > >> But by lifting it, it would appear more prominently in the TOC. > > > > Only in the printed book, maybe. The TOC of the Info manual is flat: > > all the nodes appear on the same level. > > Are we talking about the same Info manual here? That of Emacs? That > with the > > > — The Detailed Node Listing — > ——————————— > > Here are some other nodes which are really subnodes of the ones > already listed, mentioned here so you can get to them in one step: > > section? Yes, and it's flat. Or maybe we are not using the same English language, and your meaning of "flat" is different from mine. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: The poor state of documentation of pcase like things. 2015-12-18 10:47 ` Eli Zaretskii @ 2015-12-18 16:44 ` Phillip Lord 2015-12-18 17:17 ` Eli Zaretskii 0 siblings, 1 reply; 375+ messages in thread From: Phillip Lord @ 2015-12-18 16:44 UTC (permalink / raw) To: Eli Zaretskii; +Cc: David Kastrup, rasmus, emacs-devel Eli Zaretskii <eliz@gnu.org> writes: >> >> — The Detailed Node Listing — >> ——————————— >> >> Here are some other nodes which are really subnodes of the ones >> already listed, mentioned here so you can get to them in one step: >> >> section? > > Yes, and it's flat. > > Or maybe we are not using the same English language, and your meaning > of "flat" is different from mine. In the sense that "Conditionals" appears in the detailed node listing, but that "Pattern Matching" does not. Phil ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: The poor state of documentation of pcase like things. 2015-12-18 16:44 ` Phillip Lord @ 2015-12-18 17:17 ` Eli Zaretskii 2015-12-18 17:24 ` David Kastrup 2015-12-19 11:23 ` Eli Zaretskii 0 siblings, 2 replies; 375+ messages in thread From: Eli Zaretskii @ 2015-12-18 17:17 UTC (permalink / raw) To: Phillip Lord; +Cc: dak, rasmus, emacs-devel > From: phillip.lord@russet.org.uk (Phillip Lord) > Cc: David Kastrup <dak@gnu.org>, <rasmus@gmx.us>, <emacs-devel@gnu.org> > Date: Fri, 18 Dec 2015 16:44:56 +0000 > > Eli Zaretskii <eliz@gnu.org> writes: > >> > >> — The Detailed Node Listing — > >> ——————————— > >> > >> Here are some other nodes which are really subnodes of the ones > >> already listed, mentioned here so you can get to them in one step: > >> > >> section? > > > > Yes, and it's flat. > > > > Or maybe we are not using the same English language, and your meaning > > of "flat" is different from mine. > > In the sense that "Conditionals" appears in the detailed node listing, > but that "Pattern Matching" does not. That's simply a bug in the manual. If no one beats me to it, I will fix it soon. (Usually, the menu in the Top node gets fixed when all the documentation issues are done, so technically it's too soon to ask for that menu to be in perfect order.) ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: The poor state of documentation of pcase like things. 2015-12-18 17:17 ` Eli Zaretskii @ 2015-12-18 17:24 ` David Kastrup 2015-12-18 18:47 ` Eli Zaretskii 2015-12-19 11:23 ` Eli Zaretskii 1 sibling, 1 reply; 375+ messages in thread From: David Kastrup @ 2015-12-18 17:24 UTC (permalink / raw) To: Eli Zaretskii; +Cc: emacs-devel, rasmus, Phillip Lord Eli Zaretskii <eliz@gnu.org> writes: >> From: phillip.lord@russet.org.uk (Phillip Lord) >> Cc: David Kastrup <dak@gnu.org>, <rasmus@gmx.us>, <emacs-devel@gnu.org> >> Date: Fri, 18 Dec 2015 16:44:56 +0000 >> >> Eli Zaretskii <eliz@gnu.org> writes: >> >> >> >> — The Detailed Node Listing — >> >> ——————————— >> >> >> >> Here are some other nodes which are really subnodes of the ones >> >> already listed, mentioned here so you can get to them in one step: >> >> >> >> section? >> > >> > Yes, and it's flat. >> > >> > Or maybe we are not using the same English language, and your meaning >> > of "flat" is different from mine. >> >> In the sense that "Conditionals" appears in the detailed node listing, >> but that "Pattern Matching" does not. > > That's simply a bug in the manual. If no one beats me to it, I will > fix it soon. As much fun as proving me wrong must be, that seems excessive. I'm likely not alone in the belief that the "Detailed Node Listing" is an intentional addition rather than the outcome of a bug. -- David Kastrup ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: The poor state of documentation of pcase like things. 2015-12-18 17:24 ` David Kastrup @ 2015-12-18 18:47 ` Eli Zaretskii 0 siblings, 0 replies; 375+ messages in thread From: Eli Zaretskii @ 2015-12-18 18:47 UTC (permalink / raw) To: David Kastrup; +Cc: emacs-devel, rasmus, phillip.lord > From: David Kastrup <dak@gnu.org> > Cc: phillip.lord@russet.org.uk (Phillip Lord), rasmus@gmx.us, emacs-devel@gnu.org > Date: Fri, 18 Dec 2015 18:24:40 +0100 > > > That's simply a bug in the manual. If no one beats me to it, I will > > fix it soon. > > As much fun as proving me wrong must be, that seems excessive. I'm > likely not alone in the belief that the "Detailed Node Listing" is an > intentional addition rather than the outcome of a bug. Way over my head. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: The poor state of documentation of pcase like things. 2015-12-18 17:17 ` Eli Zaretskii 2015-12-18 17:24 ` David Kastrup @ 2015-12-19 11:23 ` Eli Zaretskii 2015-12-19 11:39 ` David Kastrup 1 sibling, 1 reply; 375+ messages in thread From: Eli Zaretskii @ 2015-12-19 11:23 UTC (permalink / raw) To: phillip.lord; +Cc: dak, rasmus, emacs-devel > Date: Fri, 18 Dec 2015 19:17:32 +0200 > From: Eli Zaretskii <eliz@gnu.org> > Cc: dak@gnu.org, rasmus@gmx.us, emacs-devel@gnu.org > > > From: phillip.lord@russet.org.uk (Phillip Lord) > > Cc: David Kastrup <dak@gnu.org>, <rasmus@gmx.us>, <emacs-devel@gnu.org> > > Date: Fri, 18 Dec 2015 16:44:56 +0000 > > > > Eli Zaretskii <eliz@gnu.org> writes: > > >> > > >> — The Detailed Node Listing — > > >> ——————————— > > >> > > >> Here are some other nodes which are really subnodes of the ones > > >> already listed, mentioned here so you can get to them in one step: > > >> > > >> section? > > > > > > Yes, and it's flat. > > > > > > Or maybe we are not using the same English language, and your meaning > > > of "flat" is different from mine. > > > > In the sense that "Conditionals" appears in the detailed node listing, > > but that "Pattern Matching" does not. > > That's simply a bug in the manual. If no one beats me to it, I will > fix it soon. Done. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: The poor state of documentation of pcase like things. 2015-12-19 11:23 ` Eli Zaretskii @ 2015-12-19 11:39 ` David Kastrup 2015-12-19 12:15 ` Eli Zaretskii 0 siblings, 1 reply; 375+ messages in thread From: David Kastrup @ 2015-12-19 11:39 UTC (permalink / raw) To: Eli Zaretskii; +Cc: emacs-devel, rasmus, phillip.lord Eli Zaretskii <eliz@gnu.org> writes: >> Date: Fri, 18 Dec 2015 19:17:32 +0200 >> From: Eli Zaretskii <eliz@gnu.org> >> Cc: dak@gnu.org, rasmus@gmx.us, emacs-devel@gnu.org >> >> > From: phillip.lord@russet.org.uk (Phillip Lord) >> > Cc: David Kastrup <dak@gnu.org>, <rasmus@gmx.us>, <emacs-devel@gnu.org> >> > Date: Fri, 18 Dec 2015 16:44:56 +0000 >> > >> > Eli Zaretskii <eliz@gnu.org> writes: >> > >> >> > >> — The Detailed Node Listing — >> > >> ——————————— >> > >> >> > >> Here are some other nodes which are really subnodes of the ones >> > >> already listed, mentioned here so you can get to them in one step: >> > >> >> > >> section? >> > > >> > > Yes, and it's flat. >> > > >> > > Or maybe we are not using the same English language, and your meaning >> > > of "flat" is different from mine. >> > >> > In the sense that "Conditionals" appears in the detailed node listing, >> > but that "Pattern Matching" does not. >> >> That's simply a bug in the manual. If no one beats me to it, I will >> fix it soon. > > Done. The Detailed Node listing now reads Control Structures * Sequencing:: Evaluation in textual order. * Conditionals:: @code{if}, @code{cond}, @code{when}, @code{unless}. * Combining Conditions:: @code{and}, @code{or}, @code{not}. * Iteration:: @code{while} loops. * Generators:: Generic sequences and coroutines. * Nonlocal Exits:: Jumping out of a sequence. Conditionals * Pattern matching case statement:: How to use @code{pcase}. Nonlocal Exits * Catch and Throw:: Nonlocal exits for the program's own purposes. * Examples of Catch:: Showing how such nonlocal exits can be written. * Errors:: How errors are signaled and handled. * Cleanups:: Arranging to run a cleanup form if an Note that "Conditionals" now appears twice: as a proper node name and as a newly added section containing only "pcase" and nothing else. -- David Kastrup ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: The poor state of documentation of pcase like things. 2015-12-19 11:39 ` David Kastrup @ 2015-12-19 12:15 ` Eli Zaretskii 2015-12-19 20:35 ` Phillip Lord 0 siblings, 1 reply; 375+ messages in thread From: Eli Zaretskii @ 2015-12-19 12:15 UTC (permalink / raw) To: David Kastrup; +Cc: emacs-devel, rasmus, phillip.lord > From: David Kastrup <dak@gnu.org> > Cc: phillip.lord@russet.org.uk, rasmus@gmx.us, emacs-devel@gnu.org > Date: Sat, 19 Dec 2015 12:39:22 +0100 > > The Detailed Node listing now reads > > Control Structures > > * Sequencing:: Evaluation in textual order. > * Conditionals:: @code{if}, @code{cond}, @code{when}, @code{unless}. > * Combining Conditions:: @code{and}, @code{or}, @code{not}. > * Iteration:: @code{while} loops. > * Generators:: Generic sequences and coroutines. > * Nonlocal Exits:: Jumping out of a sequence. > > Conditionals > > * Pattern matching case statement:: How to use @code{pcase}. > > Nonlocal Exits > > * Catch and Throw:: Nonlocal exits for the program's own purposes. > * Examples of Catch:: Showing how such nonlocal exits can be written. > * Errors:: How errors are signaled and handled. > * Cleanups:: Arranging to run a cleanup form if an > > Note that "Conditionals" now appears twice: as a proper node name and as > a newly added section containing only "pcase" and nothing else. Yes, and that is a problem because...? ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: The poor state of documentation of pcase like things. 2015-12-19 12:15 ` Eli Zaretskii @ 2015-12-19 20:35 ` Phillip Lord 2015-12-19 20:58 ` Eli Zaretskii 0 siblings, 1 reply; 375+ messages in thread From: Phillip Lord @ 2015-12-19 20:35 UTC (permalink / raw) To: Eli Zaretskii; +Cc: David Kastrup, rasmus, emacs-devel Eli Zaretskii <eliz@gnu.org> writes: >> >> Conditionals >> >> * Pattern matching case statement:: How to use @code{pcase}. >> >> Nonlocal Exits >> >> * Catch and Throw:: Nonlocal exits for the program's own purposes. >> * Examples of Catch:: Showing how such nonlocal exits can be written. >> * Errors:: How errors are signaled and handled. >> * Cleanups:: Arranging to run a cleanup form if an >> >> Note that "Conditionals" now appears twice: as a proper node name and as >> a newly added section containing only "pcase" and nothing else. > > Yes, and that is a problem because...? I would think that it would make more sense to have "Pattern Matching" at top-level. pcase is conditional, but neither pcase-let nor pcase-lambda really is. The "conditional" can have a short section saying "pcase is like case but with pattern matching", as can the "let" and "lambda" documentation. Phil ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: The poor state of documentation of pcase like things. 2015-12-19 20:35 ` Phillip Lord @ 2015-12-19 20:58 ` Eli Zaretskii 2015-12-19 22:23 ` Phillip Lord 0 siblings, 1 reply; 375+ messages in thread From: Eli Zaretskii @ 2015-12-19 20:58 UTC (permalink / raw) To: Phillip Lord; +Cc: dak, rasmus, emacs-devel > From: phillip.lord@russet.org.uk (Phillip Lord) > Cc: David Kastrup <dak@gnu.org>, <emacs-devel@gnu.org>, <rasmus@gmx.us> > Date: Sat, 19 Dec 2015 20:35:14 +0000 > > Eli Zaretskii <eliz@gnu.org> writes: > > >> > >> Conditionals > >> > >> * Pattern matching case statement:: How to use @code{pcase}. > >> > >> Nonlocal Exits > >> > >> * Catch and Throw:: Nonlocal exits for the program's own purposes. > >> * Examples of Catch:: Showing how such nonlocal exits can be written. > >> * Errors:: How errors are signaled and handled. > >> * Cleanups:: Arranging to run a cleanup form if an > >> > >> Note that "Conditionals" now appears twice: as a proper node name and as > >> a newly added section containing only "pcase" and nothing else. > > > > Yes, and that is a problem because...? > > I would think that it would make more sense to have "Pattern Matching" > at top-level. pcase is conditional, but neither pcase-let nor > pcase-lambda really is. The "conditional" can have a short section > saying "pcase is like case but with pattern matching", as can the "let" > and "lambda" documentation. Sorry, I'm not following. If we think the second instance of "Conditionals" is not the best text, we can change it at will. Only the first one must me identical to the node name. The second one is "Conditionals" because it was produced by a program and I left it unchanged, but it can be changed if we want to. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: The poor state of documentation of pcase like things. 2015-12-19 20:58 ` Eli Zaretskii @ 2015-12-19 22:23 ` Phillip Lord 2015-12-20 3:38 ` Eli Zaretskii 2015-12-20 14:16 ` Michael Heerdegen 0 siblings, 2 replies; 375+ messages in thread From: Phillip Lord @ 2015-12-19 22:23 UTC (permalink / raw) To: Eli Zaretskii; +Cc: dak, rasmus, emacs-devel Eli Zaretskii <eliz@gnu.org> writes: >> From: phillip.lord@russet.org.uk (Phillip Lord) >> Cc: David Kastrup <dak@gnu.org>, <emacs-devel@gnu.org>, <rasmus@gmx.us> >> Date: Sat, 19 Dec 2015 20:35:14 +0000 >> >> Eli Zaretskii <eliz@gnu.org> writes: >> >> >> >> >> Conditionals >> >> >> >> * Pattern matching case statement:: How to use @code{pcase}. >> >> >> >> Nonlocal Exits >> >> >> >> * Catch and Throw:: Nonlocal exits for the program's own purposes. >> >> * Examples of Catch:: Showing how such nonlocal exits can be written. >> >> * Errors:: How errors are signaled and handled. >> >> * Cleanups:: Arranging to run a cleanup form if an >> >> >> >> Note that "Conditionals" now appears twice: as a proper node name and as >> >> a newly added section containing only "pcase" and nothing else. >> > >> > Yes, and that is a problem because...? >> >> I would think that it would make more sense to have "Pattern Matching" >> at top-level. pcase is conditional, but neither pcase-let nor >> pcase-lambda really is. The "conditional" can have a short section >> saying "pcase is like case but with pattern matching", as can the "let" >> and "lambda" documentation. > > Sorry, I'm not following. If we think the second instance of > "Conditionals" is not the best text, we can change it at will. Only > the first one must me identical to the node name. The second one is > "Conditionals" because it was produced by a program and I left it > unchanged, but it can be changed if we want to. Simple change would be from: Conditionals * Pattern matching case statement:: How to use @code{pcase}. to Pattern Matching * Conditional:: How to use @code{pcase} In the grand scheme I would aim for this.... Control Structures * Sequencing:: Evaluation in textual order. * Conditionals:: ‘if’, ‘cond’, ‘when’, ‘unless’. * Combining Conditions:: ‘and’, ‘or’, ‘not’. ....etc Pattern Matching (this would contain a generalised introduction and tutorial, based around pcase) * List Clauses:: Destructuring Lists * Predicates:: Matching with predicate functions * Booleans:: and and or * Guards:: I don't quite understand guards * Conditionals:: pcase * Binding:: pcase-let * Lambda:: pcase-lambda * New Patterns:: pcase-macro, with description of seq and map support. Nonlocal Exits * Catch and Throw:: Nonlocal exits for the program’s own purposes. * Examples of Catch:: Showing how such nonlocal exits can be written. * Errors:: How errors are signaled and handled. * Cleanups:: Arranging to run a cleanup form if an Some of these detailed nodes might be too much -- pcase will inevitably get heavily described in the introduction to pattern matching, while "predicates, booleans and guards" could be described in one place. Phil ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: The poor state of documentation of pcase like things. 2015-12-19 22:23 ` Phillip Lord @ 2015-12-20 3:38 ` Eli Zaretskii 2015-12-20 22:54 ` Phillip Lord 2015-12-20 14:16 ` Michael Heerdegen 1 sibling, 1 reply; 375+ messages in thread From: Eli Zaretskii @ 2015-12-20 3:38 UTC (permalink / raw) To: Phillip Lord; +Cc: dak, rasmus, emacs-devel > From: phillip.lord@russet.org.uk (Phillip Lord) > Cc: <dak@gnu.org>, <rasmus@gmx.us>, <emacs-devel@gnu.org> > Date: Sat, 19 Dec 2015 22:23:54 +0000 > > > Sorry, I'm not following. If we think the second instance of > > "Conditionals" is not the best text, we can change it at will. Only > > the first one must me identical to the node name. The second one is > > "Conditionals" because it was produced by a program and I left it > > unchanged, but it can be changed if we want to. > > Simple change would be from: > > Conditionals > > * Pattern matching case statement:: How to use @code{pcase}. > > > to > > Pattern Matching > > * Conditional:: How to use @code{pcase} The last line can't be done, unless the node names are changed as well. Right now the pcase description is in the child node of "Conditionals" whose name is "Pattern matching case statement". Also, I think having 2 nodes named "Conditionals" and "Conditional" will be too confusing. > Pattern Matching > > (this would contain a generalised introduction and tutorial, based > around pcase) > > * List Clauses:: Destructuring Lists > * Predicates:: Matching with predicate functions > * Booleans:: and and or > * Guards:: I don't quite understand guards > * Conditionals:: pcase > * Binding:: pcase-let > * Lambda:: pcase-lambda These would be too short to justify a separate node, IMO. > * New Patterns:: pcase-macro, with description of seq and map support. We avoid using "new" in manuals, because they are that only for one release. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: The poor state of documentation of pcase like things. 2015-12-20 3:38 ` Eli Zaretskii @ 2015-12-20 22:54 ` Phillip Lord 0 siblings, 0 replies; 375+ messages in thread From: Phillip Lord @ 2015-12-20 22:54 UTC (permalink / raw) To: Eli Zaretskii; +Cc: dak, rasmus, emacs-devel Eli Zaretskii <eliz@gnu.org> writes: >> >> Simple change would be from: >> >> Conditionals >> >> * Pattern matching case statement:: How to use @code{pcase}. >> >> >> to >> >> Pattern Matching >> >> * Conditional:: How to use @code{pcase} > > The last line can't be done, unless the node names are changed as > well. Right now the pcase description is in the child node of > "Conditionals" whose name is "Pattern matching case statement". > > Also, I think having 2 nodes named "Conditionals" and "Conditional" > will be too confusing. Agreed. Hostage to fortune, if another pattern matching conditional is invented. "Pattern Matching" and "pcase" would work. >> Pattern Matching >> >> (this would contain a generalised introduction and tutorial, based >> around pcase) >> >> * List Clauses:: Destructuring Lists >> * Predicates:: Matching with predicate functions >> * Booleans:: and and or >> * Guards:: I don't quite understand guards >> * Conditionals:: pcase >> * Binding:: pcase-let >> * Lambda:: pcase-lambda > > These would be too short to justify a separate node, IMO. They might be, yes. I'd write it and see. With examples for each, they might get long enough. > >> * New Patterns:: pcase-macro, with description of seq and map support. > > We avoid using "new" in manuals, because they are that only for one > release. Sorry, poor working "Creating New Patterns" -- or perhaps "extending pattern matching". Phil ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: The poor state of documentation of pcase like things. 2015-12-19 22:23 ` Phillip Lord 2015-12-20 3:38 ` Eli Zaretskii @ 2015-12-20 14:16 ` Michael Heerdegen 1 sibling, 0 replies; 375+ messages in thread From: Michael Heerdegen @ 2015-12-20 14:16 UTC (permalink / raw) To: emacs-devel phillip.lord@russet.org.uk (Phillip Lord) writes: > * Booleans:: and and or I would want to avoid the name "Boolean", since we don't speak about Boolean values. > * Guards:: I don't quite understand guards What's the problem? (And I think they belong to the same section as predicates.) I think the following holds: (guard EXPR) == (pred (lambda (_arg) EXPR)) Michael. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: The poor state of documentation of pcase like things. 2015-12-18 9:21 ` Eli Zaretskii 2015-12-18 9:57 ` Rasmus 2015-12-18 10:13 ` David Kastrup @ 2015-12-18 12:23 ` Marcin Borkowski 2 siblings, 0 replies; 375+ messages in thread From: Marcin Borkowski @ 2015-12-18 12:23 UTC (permalink / raw) To: Eli Zaretskii; +Cc: Rasmus, emacs-devel On 2015-12-18, at 10:21, Eli Zaretskii <eliz@gnu.org> wrote: >> From: Rasmus <rasmus@gmx.us> >> Date: Fri, 18 Dec 2015 10:12:00 +0100 >> >> But by lifting it, it would appear more prominently in the TOC. > > Only in the printed book, maybe. The TOC of the Info manual is flat: > all the nodes appear on the same level. Are printed or PDF manuals > being used a lot these days, in preference to the Info manual? Yes - a pdf (or html) on an ebook reader. -- Marcin Borkowski http://octd.wmi.amu.edu.pl/en/Marcin_Borkowski Faculty of Mathematics and Computer Science Adam Mickiewicz University ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: The poor state of documentation of pcase like things. 2015-12-18 7:15 ` Eli Zaretskii 2015-12-18 9:12 ` Rasmus @ 2015-12-18 10:30 ` Phillip Lord 2015-12-18 12:21 ` Marcin Borkowski 2015-12-22 5:20 ` John Wiegley 3 siblings, 0 replies; 375+ messages in thread From: Phillip Lord @ 2015-12-18 10:30 UTC (permalink / raw) To: Eli Zaretskii; +Cc: acm, kaushal.modi, emacs-devel Eli Zaretskii <eliz@gnu.org> writes: >> From: phillip.lord@russet.org.uk (Phillip Lord) >> Date: Thu, 17 Dec 2015 21:16:56 +0000 >> Cc: Alan Mackenzie <acm@muc.de>, Emacs developers <emacs-devel@gnu.org> >> >> Could I suggest [pcase] be promoted in the manual a >> little. Currently, it's a subnode of "conditionals", but pattern >> match is really a form of control flow in its own right. > > If that's your itch, feel free to scratch it. I was suggesting it for John as he was going to write a tutorial. > IMO, that's largely a waste of your time and energy: the manual is > rarely if ever read in its entirety, or even in large portions. Most > of its uses is to quickly find the subject whose description you need, > hopefully by using the Info-index command ("i TOPIC RET"), and read > that and perhaps some of the cross-references there. With this use > case, the level on which a description is found is irrelevant. It's true. But you have to know to search for something in the first place. Also, I might well have searched for "destructuring" -- which now hits the seq.el documentation (implemented with pcase, but not linking to it). Phil ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: The poor state of documentation of pcase like things. 2015-12-18 7:15 ` Eli Zaretskii 2015-12-18 9:12 ` Rasmus 2015-12-18 10:30 ` Phillip Lord @ 2015-12-18 12:21 ` Marcin Borkowski 2015-12-22 5:20 ` John Wiegley 3 siblings, 0 replies; 375+ messages in thread From: Marcin Borkowski @ 2015-12-18 12:21 UTC (permalink / raw) To: Eli Zaretskii; +Cc: kaushal.modi, acm, emacs-devel, Phillip Lord On 2015-12-18, at 08:15, Eli Zaretskii <eliz@gnu.org> wrote: >> From: phillip.lord@russet.org.uk (Phillip Lord) >> Date: Thu, 17 Dec 2015 21:16:56 +0000 >> Cc: Alan Mackenzie <acm@muc.de>, Emacs developers <emacs-devel@gnu.org> >> >> Could I suggest [pcase] be promoted in the manual a >> little. Currently, it's a subnode of "conditionals", but pattern >> match is really a form of control flow in its own right. > > If that's your itch, feel free to scratch it. > > IMO, that's largely a waste of your time and energy: the manual is > rarely if ever read in its entirety, or even in large portions. Most Well, I did read most of it some time ago (15 years?). Then, I mainly relied on NEWS, `C-s' and `i' in the manual. I'd love to read the whole manual again some day - I like it - but it's soo time-consuming... > of its uses is to quickly find the subject whose description you need, > hopefully by using the Info-index command ("i TOPIC RET"), and read > that and perhaps some of the cross-references there. With this use > case, the level on which a description is found is irrelevant. > > Btw, the importance is in the eyes of the beholder. You look at that > through the glasses of someone who hacks Emacs core. Try to take the > POV of a casual Lisper who just wants to put some advanced > customizations in her ~/.emacs, for example. IOW, advanced features > and subjects are frequently very important to power users, but much > less so to "mere mortals". The manual is supposed to serve both types > of audience. > > Bottom line: what we do need is make the description clear and > complete. Where it appears is orders of magnitude less important. Agreed. -- Marcin Borkowski http://octd.wmi.amu.edu.pl/en/Marcin_Borkowski Faculty of Mathematics and Computer Science Adam Mickiewicz University ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: The poor state of documentation of pcase like things. 2015-12-18 7:15 ` Eli Zaretskii ` (2 preceding siblings ...) 2015-12-18 12:21 ` Marcin Borkowski @ 2015-12-22 5:20 ` John Wiegley 3 siblings, 0 replies; 375+ messages in thread From: John Wiegley @ 2015-12-22 5:20 UTC (permalink / raw) To: Eli Zaretskii; +Cc: kaushal.modi, acm, emacs-devel, Phillip Lord >>>>> Eli Zaretskii <eliz@gnu.org> writes: > Bottom line: what we do need is make the description clear and > complete. Where it appears is orders of magnitude less important. This is quite true. The sort of user who wishes to understand `pcase' will find the documentation for it, wherever it is the table of contents. -- John Wiegley GPG fingerprint = 4710 CF98 AF9B 327B B80F http://newartisans.com 60E1 46C4 BD1A 7AC1 4BA2 ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: The poor state of documentation of pcase like things. 2015-12-17 16:34 ` John Wiegley 2015-12-17 19:22 ` Kaushal Modi 2015-12-17 21:16 ` Phillip Lord @ 2015-12-17 21:26 ` Alan Mackenzie 2015-12-17 23:34 ` John Wiegley 2015-12-18 7:16 ` Eli Zaretskii 2015-12-19 15:31 ` Michael Heerdegen 3 siblings, 2 replies; 375+ messages in thread From: Alan Mackenzie @ 2015-12-17 21:26 UTC (permalink / raw) To: Kaushal Modi, Emacs developers Hello, John. On Thu, Dec 17, 2015 at 08:34:27AM -0800, John Wiegley wrote: > >>>>> Kaushal Modi <kaushal.modi@gmail.com> writes: > > I would welcome a short tutorial on how (and why) to use pcase. > There are several examples shown here: > http://www.emacswiki.org/emacs/PatternMatching > pcase makes a lot more sense if you're used to pattern matching in functional > languages, where you describe a pattern (not unlike destructuring-bind) whose > "shape" is intended to match the set of shapes you want to successful match > against. > Since pattern matching like this isn't something I had ever encountered > outside of FP, I agree that a tutorial is in order. I'm willing to volunteer > for this. An external tutorial is all well and good, and very useful. But it is drifting off topic ever so slightly. That topic is the state of the the documentation about pcase etc., _inside_ Emacs, in its doc strings and the Elisp manual. Can we take it that that documentation will be fixed before the release of 25.1? > -- > John Wiegley GPG fingerprint = 4710 CF98 AF9B 327B B80F > http://newartisans.com 60E1 46C4 BD1A 7AC1 4BA2 -- Alan Mackenzie (Nuremberg, Germany). ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: The poor state of documentation of pcase like things. 2015-12-17 21:26 ` Alan Mackenzie @ 2015-12-17 23:34 ` John Wiegley 2015-12-18 7:16 ` Eli Zaretskii 1 sibling, 0 replies; 375+ messages in thread From: John Wiegley @ 2015-12-17 23:34 UTC (permalink / raw) To: Alan Mackenzie; +Cc: Emacs developers, Kaushal Modi >>>>> Alan Mackenzie <acm@muc.de> writes: > An external tutorial is all well and good, and very useful. But it is > drifting off topic ever so slightly. I was hoping the tutorial would become part of the Elisp manual. And I agree that we should lift "Pattern Matching" to a higher-level topic. -- John Wiegley GPG fingerprint = 4710 CF98 AF9B 327B B80F http://newartisans.com 60E1 46C4 BD1A 7AC1 4BA2 ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: The poor state of documentation of pcase like things. 2015-12-17 21:26 ` Alan Mackenzie 2015-12-17 23:34 ` John Wiegley @ 2015-12-18 7:16 ` Eli Zaretskii 1 sibling, 0 replies; 375+ messages in thread From: Eli Zaretskii @ 2015-12-18 7:16 UTC (permalink / raw) To: Alan Mackenzie; +Cc: emacs-devel, kaushal.modi > Date: Thu, 17 Dec 2015 21:26:33 +0000 > From: Alan Mackenzie <acm@muc.de> > > Can we take it that that documentation will be fixed before the > release of 25.1? It goes without saying. I wish more people got involved in this activity, instead of hacking on master, though. It would help releasing Emacs 25.1 earlier. TIA ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: The poor state of documentation of pcase like things. 2015-12-17 16:34 ` John Wiegley ` (2 preceding siblings ...) 2015-12-17 21:26 ` Alan Mackenzie @ 2015-12-19 15:31 ` Michael Heerdegen 2015-12-22 5:25 ` John Wiegley 3 siblings, 1 reply; 375+ messages in thread From: Michael Heerdegen @ 2015-12-19 15:31 UTC (permalink / raw) To: Kaushal Modi; +Cc: Alan Mackenzie, Emacs developers [-- Attachment #1: Type: text/plain, Size: 377 bytes --] John Wiegley <jwiegley@gmail.com> writes: > Since pattern matching like this isn't something I had ever encountered > outside of FP, I agree that a tutorial is in order. I'm willing to > volunteer > for this. I had already posted a tutorial here some time ago. Sorry, my fault, I did not yet find the time to further improve it and work in the comments. Here it is again: [-- Attachment #2: pcase-guide.el --] [-- Type: application/emacs-lisp, Size: 12100 bytes --] [-- Attachment #3: Type: text/plain, Size: 219 bytes --] I'm very much willing to help with a different tutorial, prove-read your stuff and improved docs etc. but don't have so much time before Christmas. Do we have the time to do this after Christmas? Regards, Michael. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: The poor state of documentation of pcase like things. 2015-12-19 15:31 ` Michael Heerdegen @ 2015-12-22 5:25 ` John Wiegley 2015-12-22 13:16 ` Michael Heerdegen 0 siblings, 1 reply; 375+ messages in thread From: John Wiegley @ 2015-12-22 5:25 UTC (permalink / raw) To: Michael Heerdegen; +Cc: Alan Mackenzie, Emacs developers, Kaushal Modi >>>>> Michael Heerdegen <michael_heerdegen@web.de> writes: > I'm very much willing to help with a different tutorial, prove-read your > stuff and improved docs etc. but don't have so much time before Christmas. > Do we have the time to do this after Christmas? Yes, I certainly do! A collaboration on this is most welcome. -- John Wiegley GPG fingerprint = 4710 CF98 AF9B 327B B80F http://newartisans.com 60E1 46C4 BD1A 7AC1 4BA2 ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: The poor state of documentation of pcase like things. 2015-12-22 5:25 ` John Wiegley @ 2015-12-22 13:16 ` Michael Heerdegen 0 siblings, 0 replies; 375+ messages in thread From: Michael Heerdegen @ 2015-12-22 13:16 UTC (permalink / raw) To: Kaushal Modi; +Cc: Alan Mackenzie, Emacs developers John Wiegley <jwiegley@gmail.com> writes: > > Do we have the time to do this after Christmas? > > Yes, I certainly do! A collaboration on this is most welcome. Great! Then let's work on this then. Regards, Michael. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: The poor state of documentation of pcase like things. 2015-12-16 20:53 ` Kaushal Modi 2015-12-17 16:34 ` John Wiegley @ 2015-12-18 0:42 ` John Wiegley 2015-12-18 4:07 ` Richard Stallman ` (3 more replies) 1 sibling, 4 replies; 375+ messages in thread From: John Wiegley @ 2015-12-18 0:42 UTC (permalink / raw) To: Kaushal Modi; +Cc: Alan Mackenzie, Emacs developers [-- Attachment #1: Type: text/plain, Size: 10003 bytes --] >>>>> Kaushal Modi <kaushal.modi@gmail.com> writes: > I would welcome a short tutorial on how (and why) to use pcase. The following is a brief pcase tutorial. I welcome any edits and comments. Also, I wonder if anyone would be willing to hammer this into a form better suited to the Emacs Lisp manual. I'm not familiar enough with the "language" of that document at the moment to emulate it, though I could do some reading next week if no one else is interested in word-smithing. John Pattern Matching with pcase All data fits into some kind of pattern. The most explicit pattern is a description of the data itself. Let's consider the following value as a running example: '(1 2 (4 . 5) "Hello") # Exact matches Explicitly stated, this is a list of four elements, where the first two elements are the integers 1 and 2, the third is a cons consisting of a car of 4 and a cdr of 5, and the fourth is the string "Hello". This states an explicit pattern that we can match against using an equality test: (equal value '(1 2 (4 . 5) "Hello")) # Pattern matches Where patterns become useful is when we want to generalize a bit. Let's say we want to do a similar equality test, but we don't care what the final string's contents are, only that it's a string. Even though it's simply state, this becomes quite difficult using an equality test: (and (equal (subseq value 0 3) '(1 2 (4 .5))) (stringp (nth 3 value))) What we would prefer is a more direct language for encoding our description of the *family of values we'd like to match against*. The way we said in English was: the first three elements exactly so, and the last element, any string. This is how we'd phrase that using `pcase': (pcase value (`(1 2 (4 . 5) ,(pred stringp)) (message "It matched!"))) Think of `pcase' as a form of `cond', where instead of evaluating each test for non-nil, it compares a series of *patterns* against the value under consideration (often called the "scrutinee" in the literature). There can be many patterns, and the first one wins, as with cond. # Capturing matches But `pcase' can go one step further: Not only can we compare a candidate value against a family of possible values described by their pattern, we can also "capture" sub-values from that pattern for later use. Continuing from the last example, let's say we want to print the string that match, even though we didn't care about the contents of the string for the sake of the match: (pcase value (`(1 2 (4 . 5) ,(and (pred stringp) foo)) (message "It matched, and the string was %s" foo))) Whenever a naked symbol like `foo' occurs as a UPattern (see next section), the part of the value being matched at that position is bound to a local variable of the same name. # QPatterns and UPatterns To master `pcase', there are two types of patterns you must know: UPatterns and QPatterns. UPatterns are the "logical" aspect of pattern matching, where we describe the kind of data we'd like to match against, and other special actions to take when it matches; and QPatterns are the "literal" aspect, stating the exact form of a particular match. QPatterns are by far the easiest to think about. To match against any atom, string, or list of the same, the corresponding QPattern is that exact value. So the QPattern "foo" matches the string "foo", 1 matches the atom 1, etc. `pcase' matches against a list of UPatterns, so to use a QPattern, we must backquote it: (pcase value (`1 (message "Matched a 1")) (`2 (message "Matched a 2")) (`"Hello" (message "Matched the string Hello"))) The only special QPattern is the anti-quoting pattern, `,foo`, which allows you to use UPatterns within QPatterns! The analogy to macro expansion is direct, so you can think of them similarly. For example: (pcase value (`(1 2 ,(or `3 `4)) (message "Matched either the list (1 2 3) or (1 2 4)"))) # More on UPatterns There are many special UPatterns, and their variety makes this the hardest aspect to master. Let's consider them one by one. ## Underscore `_' To match against anything whatsoever, no matter its type or value, use underscore. Thus to match against a list containing anything at all at its head, we'd use: (pcase value (`(_ 1 2) (message "Matched a list of anything followed by (2 3)"))) ## Self-quoting If an atom is self-quoting, we don't need to use backquotes to match against it. This means that the QPattern `1 is identical to the UPattern 1: (pcase value (1 (message "Matched a 1")) (2 (message "Matched a 2")) ("Hello" (message "Matched the string Hello"))) ## Symbol When performing a match, if a symbol occurs within a UPattern, it binds whatever was found at that position to a local symbol of the same name. Some examples will help to make this clearer: (pcase value (`(1 2 ,foo 3) (message "Matched 1, 2, something now bound to foo, and 3")) (foo (message "Match anything at all, and bind it to foo!")) (`(,the-car . ,the-cdr)) (message "Match any cons cell, binding the car and cdr locally")) The reason for doing this is two-fold: Either to refer to a previous match later in the pattern (where it is compared using `eq'), or to make use of a matched value within the related code block: (pcase value (`(1 2 ,foo ,foo 3) (message "Matched (1 2 %s %s 3)" foo))) ## `(or UPAT ...)` and `(and UPAT ...) We can express boolean logic within a pattern match using the `or` and `and` Patterns: (pcase value (`(1 2 ,(or 3 4) ,(and (pred stringp) (pred (string> "aaa")) (pred (lambda (x) (> (length x) 10))))) (message "Matched 1, 2, 3 or 4, and a long string " "that is lexically greater than 'aaa'"))) ## `pred' predicates Arbitrary predicates can be applied to matched elements, where the predicate will be passed the object that matched. As in the previous example, lambdas can be used to form arbitrarily complex predicates, with their own logic. ## guard expressions At any point within a match, you may assert that something is true by inserting a guard. This might consult some other variable to confirm the validity of a pattern at a given time, or it might reference a local symbol that was earlier bound by the match itself, as described above: (pcase value (`(1 2 ,foo ,(guard (and (not (numberp foo)) (/= foo 10))) (message "Matched 1, 2, anything, and then anything again, " "but only if the first anything wasn't the number 10")))) Note that in this example, the guard occurs at a match position, so even though the guard doesn't refer to what is being matched, if it passes, then whatever occurs at that position (the fourth element of the list), would be an unnamed successful matched. This is rather bad form, so we can be more explicit about the logic here: (pcase value (`(1 2 ,(and foo (guard (and (not (numberp foo)) (/= foo 10)))) _) (message "Matched 1, 2, anything, and then anything again, " "but only if the first anything wasn't the number 10")))) This means the same, but associates the guard with the value it tests, and makes it clear that we don't care what the fourth element is, only that it exists. ## Pattern let bindings Within a pattern we can match sub-patterns, using a special form of let that has a meaning specific to `pcase': (pcase value (`(1 2 ,(and foo (let 3 foo))) (message "A weird way of matching (1 2 3)"))) This example is a bit contrived, but it allows us to build up complex guard patterns that might match against values captured elsewhere in the surrounding code: (pcase value1 (`(1 2 ,foo) (pcase value2 (`(1 2 ,(and (let (or 3 4) foo) bar)) (message "A nested pcase depends on the results of the first"))))) Here the third value of `value2' -- which must be a list of exactly three elements, starting with 1 and 2 -- is being bound to the local variable `bar', but only if foo was a 3 or 4. There are many other ways this logic could be expressed, but this gives you a test of how flexibly you can introduce arbitrary pattern matching of other values within any UPattern. # `pcase-let' and `pcase-let*' That's all there is to know about `pcase'! The other two utilities you might like to use are `pcase-let` and `pcase-let*`, which do similar things to their UPattern counter-part `let', but as regular Lisp forms: (pcase-let ((`(1 2 ,foo) value1) (`(3 4 ,bar) value2)) (message "value1 is a list of (1 2 %s); value2 ends with %s" foo bar)) Note that `pcase-let' does not fail, and always executes the correspond forms unless there is a type error. That is, `value1' above is not required to fit the form of the match exactly. Rather, every binding that can paired is bound to its corresponding element, but every binding that cannot is bound to nil: (pcase-let ((`(1 2 ,foo) '(10))) (message "foo = %s" foo)) => prints "foo = nil" (pcase-let ((`(1 2 ,foo) 10)) (message "foo = %s" foo)) => Lisp error, 10 is not a list (pcase-let ((`(1 2 ,foo) '(3 4 10))) (message "foo = %s" foo)) => prints "foo = 10" Thus, `pcase-let' could be thought of as a more expressive form of `destructuring-bind'. The `pcase-let*' variant, like `let*', allows you to reference bound local symbols from prior matches. (pcase-let* ((`(1 2 ,foo) '(1 2 3)) (`(3 4 ,bar) (list 3 4 foo))) (message "foo = %s, bar = %s" foo bar)) => foo = 3, bar = 3 However, if you name a symbol with same name in a later UPattern, it is not used as an `eq' test, but rather shadows that symbol: (pcase-let* ((`(1 2 ,foo) '(1 2 3)) (`(3 4 ,foo) '(3 4 5))) (message "1 2 %s" foo)) This prints out "1 2 5", rather current match. [-- Attachment #2: signature.asc --] [-- Type: application/pgp-signature, Size: 629 bytes --] ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: The poor state of documentation of pcase like things. 2015-12-18 0:42 ` John Wiegley @ 2015-12-18 4:07 ` Richard Stallman 2015-12-18 10:39 ` Phillip Lord 2015-12-18 8:55 ` Eli Zaretskii ` (2 subsequent siblings) 3 siblings, 1 reply; 375+ messages in thread From: Richard Stallman @ 2015-12-18 4:07 UTC (permalink / raw) To: John Wiegley; +Cc: acm, emacs-devel, kaushal.modi [[[ 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. ]]] > There are many special UPatterns, and their variety makes this the hardest > aspect to master. Let's consider them one by one. > ## Underscore `_' > To match against anything whatsoever, no matter its type or value, use > underscore. Thus to match against a list containing anything at all at its > head, we'd use: > (pcase value > (`(_ 1 2) > (message "Matched a list of anything followed by (2 3)"))) I don't follow this part. (_ 1 2) seems to be a QPattern. Is that right? So how is it that an element can be a UPattern? It would help if some of the examples used symbols inside a QPattern, without comma, so we can see what that does. -- Dr Richard Stallman President, Free Software Foundation (gnu.org, fsf.org) Internet Hall-of-Famer (internethalloffame.org) Skype: No way! See stallman.org/skype.html. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: The poor state of documentation of pcase like things. 2015-12-18 4:07 ` Richard Stallman @ 2015-12-18 10:39 ` Phillip Lord 2015-12-19 15:14 ` Michael Heerdegen 0 siblings, 1 reply; 375+ messages in thread From: Phillip Lord @ 2015-12-18 10:39 UTC (permalink / raw) To: Richard Stallman; +Cc: kaushal.modi, John Wiegley, emacs-devel, acm Richard Stallman <rms@gnu.org> writes: > [[[ 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. ]]] > > > There are many special UPatterns, and their variety makes this the hardest > > aspect to master. Let's consider them one by one. > > > ## Underscore `_' > > > To match against anything whatsoever, no matter its type or value, use > > underscore. Thus to match against a list containing anything at all at its > > head, we'd use: > > > (pcase value > > (`(_ 1 2) > > (message "Matched a list of anything followed by (2 3)"))) > > I don't follow this part. (_ 1 2) seems to be a QPattern. > Is that right? So how is it that an element can be a UPattern? I think the example is wrong. This.... (pcase '(3 1 2) (`(_ 1 2) (message "Matched a list of anything followed by (2 3)"))) prints nothing. while this... (pcase '(3 1 2) (`(,_ 1 2) (message "Matched a list of anything followed by (2 3)"))) prints the message (which should be "followed by (2 3)"). I am a bit surprised to find that _ needs , in these examples, and I think that it's a bug. I would anyway change it to: (pcase '(3 1 2) (`(,_ 1 2) "Matched a list of anything followed by (1 2)")) As I think it makes the point that `pcase' returns something, as opposed to working by side effect. I think the example in the manual needs the same change. > It would help if some of the examples used symbols inside a QPattern, > without comma, so we can see what that does. A symbol IS a QPattern (pcase '(a b c) (`(a b ,x) x)) returns "c". Phil ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: The poor state of documentation of pcase like things. 2015-12-18 10:39 ` Phillip Lord @ 2015-12-19 15:14 ` Michael Heerdegen 2015-12-19 19:23 ` Phillip Lord 2015-12-19 19:24 ` Phillip Lord 0 siblings, 2 replies; 375+ messages in thread From: Michael Heerdegen @ 2015-12-19 15:14 UTC (permalink / raw) To: emacs-devel phillip.lord@russet.org.uk (Phillip Lord) writes: > (pcase '(3 1 2) > (`(_ 1 2) > (message "Matched a list of anything followed by (2 3)"))) > > prints nothing. > > while this... > > (pcase '(3 1 2) > (`(,_ 1 2) > (message "Matched a list of anything followed by (2 3)"))) > > prints the message (which should be "followed by (2 3)"). > > I am a bit surprised to find that _ needs , in these examples, and I > think that it's a bug. I think it's intentional, and it fits the documentation. We think of elements in a backquoted list to be all quoted unless explicitly unquoted. It makes no sense that '_ matches any expression. It matches only the symbol _, and that can be useful, too. Michael. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: The poor state of documentation of pcase like things. 2015-12-19 15:14 ` Michael Heerdegen @ 2015-12-19 19:23 ` Phillip Lord 2015-12-19 21:09 ` Michael Heerdegen 2015-12-19 19:24 ` Phillip Lord 1 sibling, 1 reply; 375+ messages in thread From: Phillip Lord @ 2015-12-19 19:23 UTC (permalink / raw) To: Michael Heerdegen; +Cc: emacs-devel Michael Heerdegen <michael_heerdegen@web.de> writes: > phillip.lord@russet.org.uk (Phillip Lord) writes: > >> (pcase '(3 1 2) >> (`(_ 1 2) >> (message "Matched a list of anything followed by (2 3)"))) >> >> prints nothing. >> >> while this... >> >> (pcase '(3 1 2) >> (`(,_ 1 2) >> (message "Matched a list of anything followed by (2 3)"))) >> >> prints the message (which should be "followed by (2 3)"). >> >> I am a bit surprised to find that _ needs , in these examples, and I >> think that it's a bug. > > I think it's intentional, and it fits the documentation. Not convinced. The documentation says.... ‘(pred numberp)’ is a pattern that simply checks that ‘exp’ is a number, and ‘_’ is the catch-all pattern that matches anything. for example, which made me assume that "_" matches anything. > We think of elements in a backquoted list to be all quoted unless > explicitly unquoted. It makes no sense that '_ matches any expression. > It matches only the symbol _, and that can be useful, too. To be it seems unintuitive, to be honest. It took me a while to work this out; John made the same mistake, it seems. Phil ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: The poor state of documentation of pcase like things. 2015-12-19 19:23 ` Phillip Lord @ 2015-12-19 21:09 ` Michael Heerdegen 2015-12-19 21:57 ` Phillip Lord 0 siblings, 1 reply; 375+ messages in thread From: Michael Heerdegen @ 2015-12-19 21:09 UTC (permalink / raw) To: Phillip Lord; +Cc: emacs-devel phillip.lord@russet.org.uk (Phillip Lord) writes: > >> I am a bit surprised to find that _ needs , in these examples, and I > >> think that it's a bug. > > > > I think it's intentional, and it fits the documentation. > > Not convinced. The documentation says.... > > ‘(pred numberp)’ is a pattern that simply checks that ‘exp’ is a number, > and ‘_’ is the catch-all pattern that matches anything. > > for example, which made me assume that "_" matches anything. Anything in a backquote is implicitly quoted, and thus should behave like 'VAL matches if the object is ‘equal’ to VAL. The elements in a backquoted list in a pcase pattern are _not_ interpreted as pcase patterns, unless unquoted. _ is not special here. You also can't use `(1 2 (pred numberp)) as you would expect. Why should _ be different? Michael. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: The poor state of documentation of pcase like things. 2015-12-19 21:09 ` Michael Heerdegen @ 2015-12-19 21:57 ` Phillip Lord 2015-12-20 5:13 ` Richard Stallman 2015-12-20 13:33 ` Michael Heerdegen 0 siblings, 2 replies; 375+ messages in thread From: Phillip Lord @ 2015-12-19 21:57 UTC (permalink / raw) To: Michael Heerdegen; +Cc: emacs-devel Michael Heerdegen <michael_heerdegen@web.de> writes: >> Not convinced. The documentation says.... >> >> ‘(pred numberp)’ is a pattern that simply checks that ‘exp’ is a number, >> and ‘_’ is the catch-all pattern that matches anything. >> >> for example, which made me assume that "_" matches anything. > > Anything in a backquote is implicitly quoted, and thus should behave > like > > 'VAL matches if the object is ‘equal’ to VAL. > > The elements in a backquoted list in a pcase pattern are _not_ > interpreted as pcase patterns, unless unquoted. _ is not special here. > > You also can't use > > `(1 2 (pred numberp)) > > as you would expect. Why should _ be different? I can certainly see your point, and agree from a point-of-view of semantics then it makes sense. But from a point-of-view of usability, I am less convinced. "_" is different because it has no formal semantics in the rest of lisp. So, for example, (funcall (lambda(_) _) 1) returns 1. Compare this with works (pcase 1 (a a)) and this which errors (pcase 1 (_ _)) So, "_" can have any semantics we like, and remain consistent. To me, I would expect this: (pcase '(1) (`(_) 'hello)) to return 'hello and yet it does not. Set against, this, I guess you are worried that with the semantics I suggest then you cannot do something like this: (pcase '(1) (`(_) 'hello) (`(1) 'goodbye)) which now returns 'goodbye, but would return 'hello. This is a valid concern, I agree, although I think is a more minor usage (since "_" has no special semantics, how often do you want to match this!). Perhaps, it could be supported by a syntax like this: (pcase '(1) (`('_) 'hello) (`(1) 'goodbye)) => 'goodbye Irrespective of whether you agree with this or not, what I would say is that the current requirement for ,_ is not obvious, and that it is a pcase "gotcha". I would say that least one concrete example in the manual of this usage, explicitly mentioning the , is a good idea. Phil ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: The poor state of documentation of pcase like things. 2015-12-19 21:57 ` Phillip Lord @ 2015-12-20 5:13 ` Richard Stallman 2015-12-20 9:25 ` Phillip Lord 2015-12-20 13:45 ` Michael Heerdegen 2015-12-20 13:33 ` Michael Heerdegen 1 sibling, 2 replies; 375+ messages in thread From: Richard Stallman @ 2015-12-20 5:13 UTC (permalink / raw) To: Phillip Lord; +Cc: michael_heerdegen, emacs-devel [[[ 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. ]]] Could someone report on what the current meaning of _ is? How is it actually used in pcase? -- Dr Richard Stallman President, Free Software Foundation (gnu.org, fsf.org) Internet Hall-of-Famer (internethalloffame.org) Skype: No way! See stallman.org/skype.html. ^ permalink raw reply [flat|nested] 375+ messages in thread
* RE: The poor state of documentation of pcase like things. 2015-12-20 5:13 ` Richard Stallman @ 2015-12-20 9:25 ` Phillip Lord 2015-12-21 5:04 ` Richard Stallman 2015-12-20 13:45 ` Michael Heerdegen 1 sibling, 1 reply; 375+ messages in thread From: Phillip Lord @ 2015-12-20 9:25 UTC (permalink / raw) To: rms@gnu.org, Phillip Lord; +Cc: michael_heerdegen@web.de, emacs-devel@gnu.org It matches anything (like a variable) but does not actually bind a variable. It's also being used in other parts of Emacs -- I've used it for generic EIEIO methods (defmethod blah (a b _)) to mean "I have to have a parameter, but am not going to use it", although it's just a symbol like any other and binds a variable. IIRC it shuts byte compiler warnings up about unused variables. ________________________________________ From: Richard Stallman [rms@gnu.org] Sent: 20 December 2015 05:13 To: Phillip Lord Cc: michael_heerdegen@web.de; emacs-devel@gnu.org Subject: Re: The poor state of documentation of pcase like things. [[[ 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. ]]] Could someone report on what the current meaning of _ is? How is it actually used in pcase? -- Dr Richard Stallman President, Free Software Foundation (gnu.org, fsf.org) Internet Hall-of-Famer (internethalloffame.org) Skype: No way! See stallman.org/skype.html. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: The poor state of documentation of pcase like things. 2015-12-20 9:25 ` Phillip Lord @ 2015-12-21 5:04 ` Richard Stallman 2015-12-21 10:15 ` Phillip Lord 2015-12-22 5:18 ` John Wiegley 0 siblings, 2 replies; 375+ messages in thread From: Richard Stallman @ 2015-12-21 5:04 UTC (permalink / raw) To: Phillip Lord; +Cc: michael_heerdegen, emacs-devel, phillip.lord [[[ 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. ]]] > It matches anything (like a variable) but does not actually bind a variable. Alas, that's the half of the answer that I already knew. What I don't know is, how do you _write_ the use of _? That seemed self-contradictory in the text that was posted. Can someone show me some properly working examples of _ in pcase and say what they do? -- Dr Richard Stallman President, Free Software Foundation (gnu.org, fsf.org) Internet Hall-of-Famer (internethalloffame.org) Skype: No way! See stallman.org/skype.html. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: The poor state of documentation of pcase like things. 2015-12-21 5:04 ` Richard Stallman @ 2015-12-21 10:15 ` Phillip Lord 2015-12-22 5:18 ` John Wiegley 1 sibling, 0 replies; 375+ messages in thread From: Phillip Lord @ 2015-12-21 10:15 UTC (permalink / raw) To: Richard Stallman; +Cc: michael_heerdegen, emacs-devel Richard Stallman <rms@gnu.org> writes: > [[[ 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. ]]] > > > It matches anything (like a variable) but does not actually bind a variable. > > Alas, that's the half of the answer that I already knew. > What I don't know is, how do you _write_ the use of _? > That seemed self-contradictory in the text that was posted. > > Can someone show me some properly working examples of _ in pcase > and say what they do? Okay. This is the simplest use and it returns 'hello (pcase 1 (_ 'hello)) It differs from a normal symbol because this: (pcase 1 (a a)) evals to 1, while this (pcase 1 (_ _)) errors with "void variable". That is `_' is not bound, unlike a. So `_' is more than just convention. Inside a list, though, it needs to be comma'd. So: (pcase '(1 2 3) (`(,a 2 3) 'hello)) (pcase '(1 2 3) (`(,_ 2 3) 'hello)) both return `hello' (the former binding `a', the latter not binding `_'). The question is how should this form behave. (pcase '(1 2 3) (`(_ 2 3) 'hello)) Currently, it returns `nil' because `_' matches the symbol `_' not anything. Obviously, this is useful if you want to match the symbol `_'. But I think it's unintuitive. Even if everyone agrees it is wrong, if it is fixable, I do not know. I suspect it's probably too late in the day for the emacs-25. Phil ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: The poor state of documentation of pcase like things. 2015-12-21 5:04 ` Richard Stallman 2015-12-21 10:15 ` Phillip Lord @ 2015-12-22 5:18 ` John Wiegley 1 sibling, 0 replies; 375+ messages in thread From: John Wiegley @ 2015-12-22 5:18 UTC (permalink / raw) To: Richard Stallman Cc: michael_heerdegen, Phillip Lord, phillip.lord, emacs-devel >>>>> Richard Stallman <rms@gnu.org> writes: > Can someone show me some properly working examples of _ in pcase and say > what they do? I made an error in the example, Richard, it should have been ,_. Otherwise, it matches the explicit symbol named `_'. I'll correct the example. -- John Wiegley GPG fingerprint = 4710 CF98 AF9B 327B B80F http://newartisans.com 60E1 46C4 BD1A 7AC1 4BA2 ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: The poor state of documentation of pcase like things. 2015-12-20 5:13 ` Richard Stallman 2015-12-20 9:25 ` Phillip Lord @ 2015-12-20 13:45 ` Michael Heerdegen 1 sibling, 0 replies; 375+ messages in thread From: Michael Heerdegen @ 2015-12-20 13:45 UTC (permalink / raw) To: Richard Stallman; +Cc: emacs-devel, Phillip Lord Richard Stallman <rms@gnu.org> writes: > Could someone report on what the current meaning of _ is? > How is it actually used in pcase? It's one of the pcase pattern types. It matches anything. That's all. See the doc of `pcase'. Apart from pcase, AFAIK the symbol _ is not special at all, it's just a symbol. But the byte compiler suppresses some warnings for symbols whose names start with a _, in particular, about unused variables. It is also allowed to use `_' multiple times in the argument list of a function. The intended usage is to give function arguments a name starting with _ (including `_' itself) when they are ignored by the function. Michael. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: The poor state of documentation of pcase like things. 2015-12-19 21:57 ` Phillip Lord 2015-12-20 5:13 ` Richard Stallman @ 2015-12-20 13:33 ` Michael Heerdegen 2015-12-20 18:51 ` Phillip Lord 1 sibling, 1 reply; 375+ messages in thread From: Michael Heerdegen @ 2015-12-20 13:33 UTC (permalink / raw) To: Phillip Lord; +Cc: emacs-devel phillip.lord@russet.org.uk (Phillip Lord) writes: > Irrespective of whether you agree with this or not, what I would say is > that the current requirement for ,_ is not obvious, and that it is a > pcase "gotcha". You know, I wanted to make the same suggestion a year ago. ,_ looks weird, I see all your arguments, they are all valid. But how would that fit into the semantics we have? _ is a pcase pattern. You would like it to be also a valid QPAT, matching anything. This would mess up the semantics to the worse: `_ would then be a pcase pattern matching anything. Should '_ also match anything? But how to match the symbol _ then? If not, why should `_ be different from '_ when there is no unquoting involved? Or should _ as a QPAT only behave different when used "not at toplevel"? This would be horribly inconsequent: We would get two different types of QPATs: toplevel QPATS, and non-toplevel-QPATS. That would confuse people even more, a pain to explain and to internalize. Regards, Michael. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: The poor state of documentation of pcase like things. 2015-12-20 13:33 ` Michael Heerdegen @ 2015-12-20 18:51 ` Phillip Lord 2015-12-24 17:46 ` Michael Heerdegen 0 siblings, 1 reply; 375+ messages in thread From: Phillip Lord @ 2015-12-20 18:51 UTC (permalink / raw) To: Michael Heerdegen; +Cc: emacs-devel Michael Heerdegen <michael_heerdegen@web.de> writes: > phillip.lord@russet.org.uk (Phillip Lord) writes: > >> Irrespective of whether you agree with this or not, what I would say is >> that the current requirement for ,_ is not obvious, and that it is a >> pcase "gotcha". > > You know, I wanted to make the same suggestion a year ago. ,_ looks > weird, I see all your arguments, they are all valid. > > But how would that fit into the semantics we have? _ is a pcase > pattern. You would like it to be also a valid QPAT, matching anything. I don't know. I am thinking of it from a point-of-view of the syntax I would like as a user, rather than the semantics I would use to achieve this. I do worry that the syntax of pcase is too complex. As an example compare dash.el and pcase: (-let [(a b _) '(1 2 3)] (list a b)) (pcase-let ((`(,a ,b ,_) '(1 2 3))) (list a b)) I've chosen an extreme example here, but the pcase version has a lot of punctuation (and worth remembering however familiar the macro expert is with punctuation not all emacs-lisp programmers are). Set against this, dash is imperfect in it's handling of "_". Compare: (-let [(a b _) '(1 2 3)] (list a b _)) (pcase-let ((`(,a ,b ,_) '(1 2 3))) (list a b _)) The former returns "(1 2 3) while the later errors with "No such var". > This would mess up the semantics to the worse: `_ would > then be a pcase pattern matching anything. Should '_ also match > anything? But how to match the symbol _ then? If not, why should `_ be > different from '_ when there is no unquoting involved? > > Or should _ as a QPAT only behave different when used "not at toplevel"? > This would be horribly inconsequent: We would get two different types of > QPATs: toplevel QPATS, and non-toplevel-QPATS. That would confuse > people even more, a pain to explain and to internalize. I thought we were not going to mention q-patterns any more! I think that too much of the implementation semantics is poking through into the syntax. I suspect no one would notice if "_" matched anything inside a backquoted list, because it feels natural. Phil ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: The poor state of documentation of pcase like things. 2015-12-20 18:51 ` Phillip Lord @ 2015-12-24 17:46 ` Michael Heerdegen 2015-12-24 17:51 ` John Wiegley 0 siblings, 1 reply; 375+ messages in thread From: Michael Heerdegen @ 2015-12-24 17:46 UTC (permalink / raw) To: Phillip Lord; +Cc: emacs-devel phillip.lord@russet.org.uk (Phillip Lord) writes: > I do worry that the syntax of pcase is too complex. As an example > compare dash.el and pcase: > > (-let [(a b _) '(1 2 3)] > (list a b)) > > (pcase-let > ((`(,a ,b ,_) '(1 2 3))) > (list a b)) -let is only about binding. pcase, and it's ` macro, is about matching and binding, including condition testing etc. Since the latter offers more features, it is not a surprise that it can be beaten by specialized tools in special cases wrt the length of the call. > I've chosen an extreme example here, I don't think that three additional colons are extreme. > but the pcase version has a lot of punctuation (and worth remembering > however familiar the macro expert is with punctuation not all > emacs-lisp programmers are). You can just use the `seq' pattern type if you are not familiar with punctuation. > > This would mess up the semantics to the worse: `_ would > > then be a pcase pattern matching anything. Should '_ also match > > anything? But how to match the symbol _ then? If not, why should `_ be > > different from '_ when there is no unquoting involved? > > > > Or should _ as a QPAT only behave different when used "not at toplevel"? > > This would be horribly inconsequent: We would get two different types of > > QPATs: toplevel QPATS, and non-toplevel-QPATS. That would confuse > > people even more, a pain to explain and to internalize. > > I thought we were not going to mention q-patterns any more! I never said that. "qpattern" is a useful term when describing the ` pattern. What I said was we should avoid the old term "upattern" for general type pcase patterns. > I think that too much of the implementation semantics is poking > through into the syntax. It's a good thing if the syntax reflects the semantics. And I don't think that Stefan had let the semantics be dictated by implementation details. > I suspect no one would notice if "_" matched anything inside a > backquoted list, because it feels natural. It doesn't feel natural anymore once you have used the thing yourself and understood the concept. Yes, pcase does look unusual at the first look, as does Lisp, but it won't kill you, I promise. Just give it a chance. Regards, Michael. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: The poor state of documentation of pcase like things. 2015-12-24 17:46 ` Michael Heerdegen @ 2015-12-24 17:51 ` John Wiegley 2015-12-24 19:10 ` Michael Heerdegen 0 siblings, 1 reply; 375+ messages in thread From: John Wiegley @ 2015-12-24 17:51 UTC (permalink / raw) To: Michael Heerdegen; +Cc: emacs-devel, Phillip Lord >>>>> Michael Heerdegen <michael_heerdegen@web.de> writes: >> I thought we were not going to mention q-patterns any more! > I never said that. "qpattern" is a useful term when describing the ` > pattern. What I said was we should avoid the old term "upattern" for general > type pcase patterns. They are both terrible names. Even knowing exactly what they, they don't help me to think about pcase. For macros, `foo' gets evaluated, and a quoted foo doesn't. Back-quoting reverses the idea: `foo' does not get evaluted, and a comma'd foo is. For patterns, `foo' is computed to determine the pattern, and a quoted foo matches exactly. Back-quoting reverse the idea: `foo' matches exactly, and a comma'd foo is evaluated to determine its logical behavior. -- John Wiegley GPG fingerprint = 4710 CF98 AF9B 327B B80F http://newartisans.com 60E1 46C4 BD1A 7AC1 4BA2 ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: The poor state of documentation of pcase like things. 2015-12-24 17:51 ` John Wiegley @ 2015-12-24 19:10 ` Michael Heerdegen 0 siblings, 0 replies; 375+ messages in thread From: Michael Heerdegen @ 2015-12-24 19:10 UTC (permalink / raw) To: Phillip Lord; +Cc: emacs-devel John Wiegley <jwiegley@gmail.com> writes: > They are both terrible names. Even knowing exactly what they, they > don't help me to think about pcase. Indeed. The doc of pcase now uses only "QPAT" as name of a meta variable describing the syntax of `. I find that acceptable, but a better name might be good. The manual needs to be updated anyway... though this paragraph: ,---------------------------------------------------------------------- | There are two kinds of patterns involved in ‘pcase’, called | _U-patterns_ and _Q-patterns_. The UPATTERN mentioned above are | U-patterns and can take the following forms: | | ‘`QPATTERN’ | [...] `---------------------------------------------------------------------- somewhat makes me smile ;-) Michael. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: The poor state of documentation of pcase like things. 2015-12-19 15:14 ` Michael Heerdegen 2015-12-19 19:23 ` Phillip Lord @ 2015-12-19 19:24 ` Phillip Lord 1 sibling, 0 replies; 375+ messages in thread From: Phillip Lord @ 2015-12-19 19:24 UTC (permalink / raw) To: Michael Heerdegen; +Cc: emacs-devel Michael Heerdegen <michael_heerdegen@web.de> writes: > phillip.lord@russet.org.uk (Phillip Lord) writes: > >> (pcase '(3 1 2) >> (`(_ 1 2) >> (message "Matched a list of anything followed by (2 3)"))) >> >> prints nothing. >> >> while this... >> >> (pcase '(3 1 2) >> (`(,_ 1 2) >> (message "Matched a list of anything followed by (2 3)"))) >> >> prints the message (which should be "followed by (2 3)"). >> >> I am a bit surprised to find that _ needs , in these examples, and I >> think that it's a bug. > > I think it's intentional, and it fits the documentation. Not convinced. The documentation says.... ‘(pred numberp)’ is a pattern that simply checks that ‘exp’ is a number, and ‘_’ is the catch-all pattern that matches anything. for example, which made me assume that "_" matches anything. > We think of elements in a backquoted list to be all quoted unless > explicitly unquoted. It makes no sense that '_ matches any expression. > It matches only the symbol _, and that can be useful, too. To me it seems unintuitive, to be honest. It took me a while to work this out; John made the same mistake, it seems. Phil ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: The poor state of documentation of pcase like things. 2015-12-18 0:42 ` John Wiegley 2015-12-18 4:07 ` Richard Stallman @ 2015-12-18 8:55 ` Eli Zaretskii 2015-12-19 15:18 ` Michael Heerdegen 2015-12-19 15:55 ` Michael Heerdegen 2015-12-19 15:44 ` Michael Heerdegen 2015-12-24 5:49 ` Richard Stallman 3 siblings, 2 replies; 375+ messages in thread From: Eli Zaretskii @ 2015-12-18 8:55 UTC (permalink / raw) To: John Wiegley; +Cc: acm, emacs-devel, kaushal.modi > From: John Wiegley <jwiegley@gmail.com> > Date: Thu, 17 Dec 2015 16:42:13 -0800 > Cc: Alan Mackenzie <acm@muc.de>, Emacs developers <emacs-devel@gnu.org> > > >>>>> Kaushal Modi <kaushal.modi@gmail.com> writes: > > > I would welcome a short tutorial on how (and why) to use pcase. > > The following is a brief pcase tutorial. I welcome any edits and comments. Thanks, please find below a few questions of a naïve reader. > Also, I wonder if anyone would be willing to hammer this into a form better > suited to the Emacs Lisp manual. I could try, but only if I understand this enough to write about it, and if the description you posted is complete (is it?). It's hard to convert tutorials into a manual section otherwise. > # QPatterns and UPatterns > > To master `pcase', there are two types of patterns you must know: UPatterns > and QPatterns. UPatterns are the "logical" aspect of pattern matching, where > we describe the kind of data we'd like to match against, and other special > actions to take when it matches; and QPatterns are the "literal" aspect, > stating the exact form of a particular match. What do "Q" and "U" stand for? "Quoted" and "Unquoted", something else? When introducing terminology that is not English words, you need to help the reader form a mental model by connecting terms to words. > The only special QPattern is the anti-quoting pattern, `,foo` But the example doesn't use `,foo`, it uses just ,foo. I guess `..` here is some markdown-style "quoting", unrelated to the Lisp backticks? > (pcase value > (`(1 2 ,(or `3 `4)) > (message "Matched either the list (1 2 3) or (1 2 4)"))) Do 3 and 4 really have to be quoted here? Why? > When performing a match, if a symbol occurs within a UPattern, it binds > whatever was found at that position to a local symbol of the same name. "Local symbol" here meaning what? an un-interned symbol or a local variable by that name? > (pcase value > (`(1 2 ,foo 3) > (message "Matched 1, 2, something now bound to foo, and 3")) > (foo > (message "Match anything at all, and bind it to foo!")) > (`(,the-car . ,the-cdr)) > (message "Match any cons cell, binding the car and cdr locally")) So to bind something to 'foo' you just use "foo", but to bind something to 'the-car' and 'the-cdr' you need to use ",the-car" and ",the-cdr"? Why the inconsistency? > The reason for doing this is two-fold: Either to refer to a previous match > later in the pattern (where it is compared using `eq'), or to make use of a > matched value within the related code block: > > (pcase value > (`(1 2 ,foo ,foo 3) > (message "Matched (1 2 %s %s 3)" foo))) ??? Is "foo" here bound to 2 different values? And how come the format has 2 %s, but only one variable, foo, to provide values? > We can express boolean logic within a pattern match using the `or` and `and` > Patterns: > > (pcase value > (`(1 2 ,(or 3 4) > ,(and (pred stringp) > (pred (string> "aaa")) > (pred (lambda (x) (> (length x) 10))))) > (message "Matched 1, 2, 3 or 4, and a long string " > "that is lexically greater than 'aaa'"))) Why did you use 'lambda' for the 3rd predicate, but not for the 2nd? Is it just a way to show off use of 'lambda', or is there some significant difference between these 2 use cases that requires a 'lambda' in the latter case? More generally, when is 'lambda' required in a predicate like these ones? > (pcase value > (`(1 2 ,foo ,(guard (and (not (numberp foo)) (/= foo 10))) > (message "Matched 1, 2, anything, and then anything again, " > "but only if the first anything wasn't the number 10")))) How is using 'guard' here different from using a predicate? > Note that in this example, the guard occurs at a match position, so even > though the guard doesn't refer to what is being matched, if it passes, then > whatever occurs at that position (the fourth element of the list), would be an > unnamed successful matched. What is the significance of an "unnamed successful matched"? > This is rather bad form, so we can be more > explicit about the logic here: > > (pcase value > (`(1 2 ,(and foo (guard (and (not (numberp foo)) (/= foo 10)))) _) > (message "Matched 1, 2, anything, and then anything again, " > "but only if the first anything wasn't the number 10")))) > > > This means the same, but associates the guard with the value it tests, and > makes it clear that we don't care what the fourth element is, only that it > exists. Again, how is this different from using a 'pred'? > > ## Pattern let bindings > > Within a pattern we can match sub-patterns, using a special form of let that > has a meaning specific to `pcase': > > (pcase value > (`(1 2 ,(and foo (let 3 foo))) > (message "A weird way of matching (1 2 3)"))) > > This example is a bit contrived, but it allows us to build up complex guard > patterns that might match against values captured elsewhere in the surrounding > code: > > (pcase value1 > (`(1 2 ,foo) > (pcase value2 > (`(1 2 ,(and (let (or 3 4) foo) bar)) > (message "A nested pcase depends on the results of the first"))))) > > Here the third value of `value2' -- which must be a list of exactly three > elements, starting with 1 and 2 -- is being bound to the local variable `bar', > but only if foo was a 3 or 4. Why do you need the 'let' here? Binding bar to the 3rd element can be expressed without a 'let', I think. And why is 'and' needed here? > That's all there is to know about `pcase'! The other two utilities you might > like to use are `pcase-let` and `pcase-let*`, which do similar things to their > UPattern counter-part `let', but as regular Lisp forms: > > (pcase-let ((`(1 2 ,foo) value1) > (`(3 4 ,bar) value2)) > (message "value1 is a list of (1 2 %s); value2 ends with %s" > foo bar)) Isn't it true that pcase-let is just a short-hand for a pcase that assigns values according to patterns, and has nil as the default value? If that's true, I think it explains better what pcase-let does, especially when backed up by an example of a pcase and the equivalent pcase-let. Looking at the ELisp manual's node "Pattern matching case statement", it sounds like everything you've described is already covered there, so perhaps what we need is more examples? Thanks. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: The poor state of documentation of pcase like things. 2015-12-18 8:55 ` Eli Zaretskii @ 2015-12-19 15:18 ` Michael Heerdegen 2015-12-22 5:22 ` John Wiegley 2015-12-19 15:55 ` Michael Heerdegen 1 sibling, 1 reply; 375+ messages in thread From: Michael Heerdegen @ 2015-12-19 15:18 UTC (permalink / raw) To: Eli Zaretskii; +Cc: kaushal.modi, John Wiegley, emacs-devel, acm Eli Zaretskii <eliz@gnu.org> writes: > > (pcase value > > (`(1 2 ,(or `3 `4)) > > (message "Matched either the list (1 2 3) or (1 2 4)"))) > > Do 3 and 4 really have to be quoted here? Why? Of course not! The form after the `unquote' is a "normal" pcase pattern. Numbers count as atoms matching themselves. Michael. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: The poor state of documentation of pcase like things. 2015-12-19 15:18 ` Michael Heerdegen @ 2015-12-22 5:22 ` John Wiegley 0 siblings, 0 replies; 375+ messages in thread From: John Wiegley @ 2015-12-22 5:22 UTC (permalink / raw) To: Michael Heerdegen Cc: kaushal.modi, John Wiegley, Eli Zaretskii, emacs-devel, acm >>>>> Michael Heerdegen <michael_heerdegen@web.de> writes: >> > (pcase value >> > (`(1 2 ,(or `3 `4)) >> >> Do 3 and 4 really have to be quoted here? Why? > Of course not! The form after the `unquote' is a "normal" pcase pattern. > Numbers count as atoms matching themselves. This was an unfortunate attempt to follow the sequence of unveiling features. I'll avoid this unnecessary complexity. -- John Wiegley GPG fingerprint = 4710 CF98 AF9B 327B B80F http://newartisans.com 60E1 46C4 BD1A 7AC1 4BA2 ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: The poor state of documentation of pcase like things. 2015-12-18 8:55 ` Eli Zaretskii 2015-12-19 15:18 ` Michael Heerdegen @ 2015-12-19 15:55 ` Michael Heerdegen 2015-12-19 17:08 ` Eli Zaretskii 1 sibling, 1 reply; 375+ messages in thread From: Michael Heerdegen @ 2015-12-19 15:55 UTC (permalink / raw) To: Eli Zaretskii; +Cc: kaushal.modi, John Wiegley, emacs-devel, acm Eli Zaretskii <eliz@gnu.org> writes: > But the example doesn't use `,foo`, it uses just ,foo. I guess `..` > here is some markdown-style "quoting", unrelated to the Lisp > backticks? Yes. > "Local symbol" here meaning what? an un-interned symbol or a local > variable by that name? It binds to the symbol specified. The type of binding is local. > > (pcase value > > (`(1 2 ,foo 3) > > (message "Matched 1, 2, something now bound to foo, and 3")) > > (foo > > (message "Match anything at all, and bind it to foo!")) > > (`(,the-car . ,the-cdr)) > > (message "Match any cons cell, binding the car and cdr locally")) > > So to bind something to 'foo' you just use "foo", but to bind > something to 'the-car' and 'the-cdr' you need to use ",the-car" and > ",the-cdr"? Why the inconsistency? The examples only differ because some symbols occur inside backquote and others don't. > > The reason for doing this is two-fold: Either to refer to a previous match > > later in the pattern (where it is compared using `eq'), or to make use of a > > matched value within the related code block: > > > > (pcase value > > (`(1 2 ,foo ,foo 3) > > (message "Matched (1 2 %s %s 3)" foo))) > > ??? Is "foo" here bound to 2 different values? And how come the > format has 2 %s, but only one variable, foo, to provide values? The second occurrence is turned into an equivalence test (the pcase docstring does already say that). The message call is invalid. > > We can express boolean logic within a pattern match using the `or` and `and` > > Patterns: > > > > (pcase value > > (`(1 2 ,(or 3 4) > > ,(and (pred stringp) > > (pred (string> "aaa")) > > (pred (lambda (x) (> (length x) 10))))) > > (message "Matched 1, 2, 3 or 4, and a long string " > > "that is lexically greater than 'aaa'"))) > > Why did you use 'lambda' for the 3rd predicate, but not for the 2nd? > Is it just a way to show off use of 'lambda', or is there some > significant difference between these 2 use cases that requires a > 'lambda' in the latter case? More generally, when is 'lambda' > required in a predicate like these ones? That's explained in the pcase docstring. > Isn't it true that pcase-let is just a short-hand for a pcase that > assigns values according to patterns, and has nil as the default > value? If that's true, I think it explains better what pcase-let > does, especially when backed up by an example of a pcase and the > equivalent pcase-let. I think there are more differences, AFAICT pcase-let can't "fail", and it can bind multiple value--pattern pairs. Michael. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: The poor state of documentation of pcase like things. 2015-12-19 15:55 ` Michael Heerdegen @ 2015-12-19 17:08 ` Eli Zaretskii 2015-12-19 17:19 ` Eli Zaretskii 2015-12-19 17:40 ` Michael Heerdegen 0 siblings, 2 replies; 375+ messages in thread From: Eli Zaretskii @ 2015-12-19 17:08 UTC (permalink / raw) To: Michael Heerdegen; +Cc: kaushal.modi, jwiegley, emacs-devel, acm > From: Michael Heerdegen <michael_heerdegen@web.de> > Cc: John Wiegley <jwiegley@gmail.com>, acm@muc.de, emacs-devel@gnu.org, kaushal.modi@gmail.com > Date: Sat, 19 Dec 2015 16:55:12 +0100 > > > > (pcase value > > > (`(1 2 ,foo 3) > > > (message "Matched 1, 2, something now bound to foo, and 3")) > > > (foo > > > (message "Match anything at all, and bind it to foo!")) > > > (`(,the-car . ,the-cdr)) > > > (message "Match any cons cell, binding the car and cdr locally")) > > > > So to bind something to 'foo' you just use "foo", but to bind > > something to 'the-car' and 'the-cdr' you need to use ",the-car" and > > ",the-cdr"? Why the inconsistency? > > The examples only differ because some symbols occur inside backquote and > others don't. ",foo" in the first pattern is also inside a backquote, but it is still different from "foo" in the second pattern and ",the-car" in the third. So I'm still not out of the woods regarding the inconsistency. > > > (pcase value > > > (`(1 2 ,(or 3 4) > > > ,(and (pred stringp) > > > (pred (string> "aaa")) > > > (pred (lambda (x) (> (length x) 10))))) > > > (message "Matched 1, 2, 3 or 4, and a long string " > > > "that is lexically greater than 'aaa'"))) > > > > Why did you use 'lambda' for the 3rd predicate, but not for the 2nd? > > Is it just a way to show off use of 'lambda', or is there some > > significant difference between these 2 use cases that requires a > > 'lambda' in the latter case? More generally, when is 'lambda' > > required in a predicate like these ones? > > That's explained in the pcase docstring. Which part of it? > > Isn't it true that pcase-let is just a short-hand for a pcase that > > assigns values according to patterns, and has nil as the default > > value? If that's true, I think it explains better what pcase-let > > does, especially when backed up by an example of a pcase and the > > equivalent pcase-let. > > I think there are more differences, AFAICT pcase-let can't "fail" Neither can a pcase that has a default clause, right? > and it can bind multiple value--pattern pairs. Did John's tutorial include an example of that? Or maybe I shouldn't ask about pcase-let, as it's not for the uninitiated yet? ;-) ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: The poor state of documentation of pcase like things. 2015-12-19 17:08 ` Eli Zaretskii @ 2015-12-19 17:19 ` Eli Zaretskii 2015-12-19 21:03 ` Michael Heerdegen 2015-12-19 17:40 ` Michael Heerdegen 1 sibling, 1 reply; 375+ messages in thread From: Eli Zaretskii @ 2015-12-19 17:19 UTC (permalink / raw) To: michael_heerdegen; +Cc: jwiegley, emacs-devel, acm, kaushal.modi > Date: Sat, 19 Dec 2015 19:08:18 +0200 > From: Eli Zaretskii <eliz@gnu.org> > Cc: kaushal.modi@gmail.com, jwiegley@gmail.com, emacs-devel@gnu.org, acm@muc.de > > > > (pcase value > > > > (`(1 2 ,foo 3) > > > > (message "Matched 1, 2, something now bound to foo, and 3")) > > > > (foo > > > > (message "Match anything at all, and bind it to foo!")) > > > > (`(,the-car . ,the-cdr)) > > > > (message "Match any cons cell, binding the car and cdr locally")) > > > > > > So to bind something to 'foo' you just use "foo", but to bind > > > something to 'the-car' and 'the-cdr' you need to use ",the-car" and > > > ",the-cdr"? Why the inconsistency? > > > > The examples only differ because some symbols occur inside backquote and > > others don't. > > ",foo" in the first pattern is also inside a backquote, but it is > still different from "foo" in the second pattern and ",the-car" in the > third. So I'm still not out of the woods regarding the inconsistency. (Time passes...) Ah, I see: I was confused by John's different style: "now bound to foo" vs "bind it to foo". These actually intend to say the same thing: "match anything and bind it to foo", but the former wording made it sound like it was already bound to foo before, i.e. as if the first pattern _uses_ the existing binding of foo, instead of binding foo. Silly me, trying to assign too much importance to the wording. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: The poor state of documentation of pcase like things. 2015-12-19 17:19 ` Eli Zaretskii @ 2015-12-19 21:03 ` Michael Heerdegen 0 siblings, 0 replies; 375+ messages in thread From: Michael Heerdegen @ 2015-12-19 21:03 UTC (permalink / raw) To: Eli Zaretskii; +Cc: jwiegley, emacs-devel, acm, kaushal.modi Eli Zaretskii <eliz@gnu.org> writes: > (Time passes...) Ah, I see: I was confused by John's different style: > "now bound to foo" vs "bind it to foo". These actually intend to say > the same thing: "match anything and bind it to foo", but the former > wording made it sound like it was already bound to foo before, i.e. as > if the first pattern _uses_ the existing binding of foo, instead of > binding foo. Yes, exactly. > Silly me, trying to assign too much importance to the wording. Ok, but the words are there to explain the thing, so... Regards, Michael. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: The poor state of documentation of pcase like things. 2015-12-19 17:08 ` Eli Zaretskii 2015-12-19 17:19 ` Eli Zaretskii @ 2015-12-19 17:40 ` Michael Heerdegen 2015-12-22 5:21 ` John Wiegley 1 sibling, 1 reply; 375+ messages in thread From: Michael Heerdegen @ 2015-12-19 17:40 UTC (permalink / raw) To: Eli Zaretskii; +Cc: kaushal.modi, jwiegley, emacs-devel, acm Eli Zaretskii <eliz@gnu.org> writes: > > > Why did you use 'lambda' for the 3rd predicate, but not for the 2nd? > > > Is it just a way to show off use of 'lambda', or is there some > > > significant difference between these 2 use cases that requires a > > > 'lambda' in the latter case? More generally, when is 'lambda' > > > required in a predicate like these ones? > > > > That's explained in the pcase docstring. > > Which part of it? (pred FUN) matches if FUN applied to the object returns non-nil. [...] FUN can take the form SYMBOL or (lambda ARGS BODY) in which case it’s called with one argument. (F ARG1 .. ARGn) in which case F gets called with an n+1’th argument which is the value being matched. So, FUN is generally a symbol or a lambda, as everywhere, nothing special. In addition there is a (F ARG1 .. ARGn) ("in which case F gets called with an n+1’th argument which is the value being matched.") form that can be used to abbreviate things in some cases. Probably you got confused with this additional possible syntax. > > > Isn't it true that pcase-let is just a short-hand for a pcase that > > > assigns values according to patterns, and has nil as the default > > > value? If that's true, I think it explains better what pcase-let > > > does, especially when backed up by an example of a pcase and the > > > equivalent pcase-let. > > > > I think there are more differences, AFAICT pcase-let can't "fail" > > Neither can a pcase that has a default clause, right? Yes - but `pcase-let' never fails AFAIR, no matter how the clauses look like. > Did John's tutorial include an example of that? Haven't looked yet. > Or maybe I shouldn't ask about pcase-let, as it's not for the > uninitiated yet? ;-) I don't expect the semantics of `pcase-let' to change much in the future, and I think it's quite unquestioned that it's useful and a good-to-have form per se. Michael. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: The poor state of documentation of pcase like things. 2015-12-19 17:40 ` Michael Heerdegen @ 2015-12-22 5:21 ` John Wiegley 0 siblings, 0 replies; 375+ messages in thread From: John Wiegley @ 2015-12-22 5:21 UTC (permalink / raw) To: Michael Heerdegen; +Cc: kaushal.modi, jwiegley, Eli Zaretskii, emacs-devel, acm >>>>> Michael Heerdegen <michael_heerdegen@web.de> writes: >> Neither can a pcase that has a default clause, right? A default clause for pcase would be: (_ (message "Hello, this is the default case")) -- John Wiegley GPG fingerprint = 4710 CF98 AF9B 327B B80F http://newartisans.com 60E1 46C4 BD1A 7AC1 4BA2 ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: The poor state of documentation of pcase like things. 2015-12-18 0:42 ` John Wiegley 2015-12-18 4:07 ` Richard Stallman 2015-12-18 8:55 ` Eli Zaretskii @ 2015-12-19 15:44 ` Michael Heerdegen 2015-12-19 17:02 ` Eli Zaretskii 2015-12-19 20:31 ` Phillip Lord 2015-12-24 5:49 ` Richard Stallman 3 siblings, 2 replies; 375+ messages in thread From: Michael Heerdegen @ 2015-12-19 15:44 UTC (permalink / raw) To: Kaushal Modi; +Cc: Alan Mackenzie, Emacs developers John Wiegley <jwiegley@gmail.com> writes: > # QPatterns and UPatterns > > To master `pcase', there are two types of patterns you must know: UPatterns > and QPatterns. UPatterns are the "logical" aspect of pattern matching, where > we describe the kind of data we'd like to match against, and other special > actions to take when it matches; and QPatterns are the "literal" aspect, > stating the exact form of a particular match. I think we should not emphasize QPatterns and UPatterns too much, because today, ``' is just a pcase macro. When not using ``' is pcase, we speak of just PATTERNs. > QPatterns are by far the easiest to think about. To match against any atom, > string, or list of the same, the corresponding QPattern is that exact value. > So the QPattern "foo" matches the string "foo", 1 matches the atom 1, > etc. Note that atoms are compared with `equal', so "foo" matches any string "foo", for example. > `pcase' matches against a list of UPatterns, so to use a QPattern, we must > backquote it: > > (pcase value > (`1 (message "Matched a 1")) > (`2 (message "Matched a 2")) > (`"Hello" (message "Matched the string Hello"))) We used to write it like that in the old times. Today, we better quote stuff at toplevel with quote: `''. > (pcase value > (`(_ 1 2) > (message "Matched a list of anything followed by (2 3)"))) The example is wrong, as already had been mentioned. Just had a very quick look. To sum up, I don't think that basing the tutorial on the difference of qpatterns and upatterns is a good idea. Destructuring is only one specific aspect of pcase. And there are even different means of destructuring now, namely seq and map. If there are still examples like > (pcase value > (`1 (message "Matched a 1")) > (`2 (message "Matched a 2")) > (`"Hello" (message "Matched the string Hello"))) in the info manual, they should be changed to not use backquote. Regards, Michael. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: The poor state of documentation of pcase like things. 2015-12-19 15:44 ` Michael Heerdegen @ 2015-12-19 17:02 ` Eli Zaretskii 2015-12-19 20:58 ` Michael Heerdegen 2015-12-22 5:28 ` John Wiegley 2015-12-19 20:31 ` Phillip Lord 1 sibling, 2 replies; 375+ messages in thread From: Eli Zaretskii @ 2015-12-19 17:02 UTC (permalink / raw) To: Michael Heerdegen; +Cc: acm, emacs-devel, kaushal.modi > From: Michael Heerdegen <michael_heerdegen@web.de> > Date: Sat, 19 Dec 2015 16:44:34 +0100 > Cc: Alan Mackenzie <acm@muc.de>, Emacs developers <emacs-devel@gnu.org> > > John Wiegley <jwiegley@gmail.com> writes: > > I think we should not emphasize QPatterns and UPatterns too much, > because today, ``' is just a pcase macro. When not using ``' is pcase, > we speak of just PATTERNs. If we want to do that, we need to rewrite both the ELisp manual and the doc string to never use these. With the current text of the manual, you simply cannot ignore them. (Personally, I think trying to stop using them is futile, since so many people who actively use 'pcase' use these terms freely in their messages and other text they write. But that's me.) > If there are still examples like > > > (pcase value > > (`1 (message "Matched a 1")) > > (`2 (message "Matched a 2")) > > (`"Hello" (message "Matched the string Hello"))) > > in the info manual, they should be changed to not use backquote. There are quite a few of these there. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: The poor state of documentation of pcase like things. 2015-12-19 17:02 ` Eli Zaretskii @ 2015-12-19 20:58 ` Michael Heerdegen 2015-12-22 5:28 ` John Wiegley 1 sibling, 0 replies; 375+ messages in thread From: Michael Heerdegen @ 2015-12-19 20:58 UTC (permalink / raw) To: Eli Zaretskii; +Cc: acm, emacs-devel, kaushal.modi Eli Zaretskii <eliz@gnu.org> writes: > If we want to do that, we need to rewrite both the ELisp manual and > the doc string to never use these. With the current text of the > manual, you simply cannot ignore them. (Personally, I think trying to > stop using them is futile, since so many people who actively use > 'pcase' use these terms freely in their messages and other text they > write. But that's me.) The terms are useful when explaining the semantics of ``'. Using the terms all the time can be confusing, however, because these terms are completely unrelated to the semantics of other pcase pattern types. > > If there are still examples like > > > > > (pcase value > > > (`1 (message "Matched a 1")) > > > (`2 (message "Matched a 2")) > > > (`"Hello" (message "Matched the string Hello"))) > > > > in the info manual, they should be changed to not use backquote. > > There are quite a few of these there. Yip, I think they should be changed, for the same reason we prefer using a simple quote over using backquote in Lisp when there is no unquoting involved. (And it looks unnecessarily weird...) When pcase had been invented, it was more or less destructuring with tests. Now, the thing has developed, and ` does not play such an central role anymore (though it's still important) because we found out that it is much more useful for matching non-list values than we had expected (with "we" I mean Stefan, and that's just my version of the story). Michael. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: The poor state of documentation of pcase like things. 2015-12-19 17:02 ` Eli Zaretskii 2015-12-19 20:58 ` Michael Heerdegen @ 2015-12-22 5:28 ` John Wiegley 1 sibling, 0 replies; 375+ messages in thread From: John Wiegley @ 2015-12-22 5:28 UTC (permalink / raw) To: Eli Zaretskii; +Cc: Michael Heerdegen, acm, kaushal.modi, emacs-devel >>>>> Eli Zaretskii <eliz@gnu.org> writes: >> I think we should not emphasize QPatterns and UPatterns too much, >> because today, ``' is just a pcase macro. When not using ``' is pcase, >> we speak of just PATTERNs. > If we want to do that, we need to rewrite both the ELisp manual and the doc > string to never use these. I'm at least fine with de-emphasizing them. They convey no information at all (is it "Quoted" and "Unquoted"? What does that really mean, since they both have meanings in terms of matching, beyond their quotation level). So in a word, the two terms are almost worst than nothing. I prefer logical and explicit matches, where a logical match compares an entity against some form of query, while an explicit match is the special case of a query by `eq'. -- John Wiegley GPG fingerprint = 4710 CF98 AF9B 327B B80F http://newartisans.com 60E1 46C4 BD1A 7AC1 4BA2 ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: The poor state of documentation of pcase like things. 2015-12-19 15:44 ` Michael Heerdegen 2015-12-19 17:02 ` Eli Zaretskii @ 2015-12-19 20:31 ` Phillip Lord 2015-12-19 21:16 ` Michael Heerdegen 1 sibling, 1 reply; 375+ messages in thread From: Phillip Lord @ 2015-12-19 20:31 UTC (permalink / raw) To: Michael Heerdegen; +Cc: Alan Mackenzie, Emacs developers, Kaushal Modi Michael Heerdegen <michael_heerdegen@web.de> writes: > Just had a very quick look. > > > To sum up, I don't think that basing the tutorial on the difference of > qpatterns and upatterns is a good idea. Destructuring is only one > specific aspect of pcase. And there are even different means of > destructuring now, namely seq and map. These forms could do with documenting. I've tried to get the seq and map pcase-macro's working and have failed. Phil ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: The poor state of documentation of pcase like things. 2015-12-19 20:31 ` Phillip Lord @ 2015-12-19 21:16 ` Michael Heerdegen 2015-12-19 22:11 ` Phillip Lord 0 siblings, 1 reply; 375+ messages in thread From: Michael Heerdegen @ 2015-12-19 21:16 UTC (permalink / raw) To: Phillip Lord; +Cc: Alan Mackenzie, Emacs developers, Kaushal Modi phillip.lord@russet.org.uk (Phillip Lord) writes: > These forms could do with documenting. I've tried to get the seq and > map pcase-macro's working and have failed. What did you try and what failed? Did you load seq.el and map.el before trying? Michael. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: The poor state of documentation of pcase like things. 2015-12-19 21:16 ` Michael Heerdegen @ 2015-12-19 22:11 ` Phillip Lord 2015-12-20 12:45 ` Michael Heerdegen 0 siblings, 1 reply; 375+ messages in thread From: Phillip Lord @ 2015-12-19 22:11 UTC (permalink / raw) To: Michael Heerdegen; +Cc: Alan Mackenzie, Kaushal Modi, Emacs developers Michael Heerdegen <michael_heerdegen@web.de> writes: > phillip.lord@russet.org.uk (Phillip Lord) writes: > >> These forms could do with documenting. I've tried to get the seq and >> map pcase-macro's working and have failed. > > What did you try and what failed? Did you load seq.el and map.el before > trying? Just get them working at all. The pcase doc says: -- (map &rest ARGS) ARGS can be a list of the form (KEY PAT), in which case KEY in an unquoted form. ARGS can also be a list of symbols, which stands for (’SYMBOL SYMBOL). So, I tried something like: (pcase '(:a 1) ((map `(:a ,a)) a)) which I thought might eval to 1. Phil ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: The poor state of documentation of pcase like things. 2015-12-19 22:11 ` Phillip Lord @ 2015-12-20 12:45 ` Michael Heerdegen 0 siblings, 0 replies; 375+ messages in thread From: Michael Heerdegen @ 2015-12-20 12:45 UTC (permalink / raw) To: Phillip Lord; +Cc: Alan Mackenzie, nicolas, Kaushal Modi, Emacs developers phillip.lord@russet.org.uk (Phillip Lord) writes: > (pcase '(:a 1) (:a 1) is not a map in the sense of map.el. You probably want an alist: ((:a . 1)). > ((map `(:a ,a)) a)) ``' is a different pattern type. You want to use the `map', and backquote is not part of its syntax. So, this is how the example should look like: (pcase '((:a . 1)) ((map (:a a)) a)) But the doc is not correct indeed: @Nicolas: Can you please correct these sentences of the "map" pcase pattern documentation: ,---------------------------------------------------------------------- | ARGS can be a list of the form (KEY PAT), in which case KEY in an | unquoted form. | | ARGS can also be a list of symbols, which stands for (’SYMBOL | SYMBOL). `---------------------------------------------------------------------- It should say that ARGS can be a list of elements of the form (KEY PAT) ^^^^^^^^^^^ (at least that's how I think it is meant. OTOH, (pcase '((:a . 1) (:b . 2)) ((map (:a a :b b)) (list a b))) gives an error (void variable: b), so I'm not sure) In the second sentence, our new quoting magic messes the quote character in the doc shown in the help buffer. Thanks, Michael. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: The poor state of documentation of pcase like things. 2015-12-18 0:42 ` John Wiegley ` (2 preceding siblings ...) 2015-12-19 15:44 ` Michael Heerdegen @ 2015-12-24 5:49 ` Richard Stallman 2015-12-24 6:15 ` John Wiegley 3 siblings, 1 reply; 375+ messages in thread From: Richard Stallman @ 2015-12-24 5:49 UTC (permalink / raw) To: John Wiegley; +Cc: acm, emacs-devel, kaushal.modi [[[ 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. ]]] Is _ as wildcard a UPattern? In other words, should this > (pcase value > (`(_ 1 2) > (message "Matched a list of anything followed by (2 3)"))) really be this? > (pcase value > (`(,_ 1 2) > (message "Matched a list of anything followed by (2 3)"))) If so, now the description makes sense. But I think it might be useful to define _ as a QPattern to be equivalent to ,_. It is true that this would make it an exception among QPatterns, but one exception might be worth while. -- Dr Richard Stallman President, Free Software Foundation (gnu.org, fsf.org) Internet Hall-of-Famer (internethalloffame.org) Skype: No way! See stallman.org/skype.html. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: The poor state of documentation of pcase like things. 2015-12-24 5:49 ` Richard Stallman @ 2015-12-24 6:15 ` John Wiegley 2015-12-25 5:49 ` Richard Stallman 0 siblings, 1 reply; 375+ messages in thread From: John Wiegley @ 2015-12-24 6:15 UTC (permalink / raw) To: Richard Stallman; +Cc: acm, emacs-devel, kaushal.modi >>>>> Richard Stallman <rms@gnu.org> writes: > Is _ as wildcard a UPattern? In other words, should this >> (pcase value >> (`(_ 1 2) >> (message "Matched a list of anything followed by (2 3)"))) > really be this? >> (pcase value >> (`(,_ 1 2) >> (message "Matched a list of anything followed by (2 3)"))) > If so, now the description makes sense. Yes, this is correct. > But I think it might be useful to define _ > as a QPattern to be equivalent to ,_. > It is true that this would make it an exception among QPatterns, > but one exception might be worth while. I don't see much value in doing so; is it just to save a comma? -- John Wiegley GPG fingerprint = 4710 CF98 AF9B 327B B80F http://newartisans.com 60E1 46C4 BD1A 7AC1 4BA2 ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: The poor state of documentation of pcase like things. 2015-12-24 6:15 ` John Wiegley @ 2015-12-25 5:49 ` Richard Stallman 2015-12-25 14:59 ` Michael Heerdegen 0 siblings, 1 reply; 375+ messages in thread From: Richard Stallman @ 2015-12-25 5:49 UTC (permalink / raw) To: John Wiegley; +Cc: acm, emacs-devel, kaushal.modi [[[ 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. ]]] > > But I think it might be useful to define _ > > as a QPattern to be equivalent to ,_. > > It is true that this would make it an exception among QPatterns, > > but one exception might be worth while. > I don't see much value in doing so; is it just to save a comma? Yes. That comma won't add much to the size of the code, and typing it is not much work. But I think that avoiding it would make pcase more attractive and conceptually simpler. -- Dr Richard Stallman President, Free Software Foundation (gnu.org, fsf.org) Internet Hall-of-Famer (internethalloffame.org) Skype: No way! See stallman.org/skype.html. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: The poor state of documentation of pcase like things. 2015-12-25 5:49 ` Richard Stallman @ 2015-12-25 14:59 ` Michael Heerdegen 2015-12-25 16:55 ` John Wiegley 2015-12-26 6:13 ` Richard Stallman 0 siblings, 2 replies; 375+ messages in thread From: Michael Heerdegen @ 2015-12-25 14:59 UTC (permalink / raw) To: emacs-devel Richard Stallman <rms@gnu.org> writes: > That comma won't add much to the size of the code, and typing it is > not much work. But I think that avoiding it would make pcase more > attractive and conceptually simpler. But it will make it conceptually more complicated, because we would obfuscate the real semantics. A tool with inconsistent semantics is neither simple nor attractive. If you understand "_" as a "concept" per se in Elisp, I think we agree that in your case it doesn't fit the expectations of how you think it would integrate in pcase's semantics. If we make it just look like some people guess it would be working, we are not doing them a favor, because we just spare them to learn the real semantics at the moment. That will make it harder to learn pcase, not easier. If for some people the thing is different as they first expect, avoiding to let them see that it is different is not good, just for the sake of making it look more familiar at the first look. I think people will then more likely forget commas at other places in ` patterns. They will have more problems to understand more complicated ` patterns. It is important to understand that _ is a pattern in pcase, a pattern like any other pcase pattern, and not something else or special. OTOH after you have written ",_" for yourself a three times or so, you'll just have gotten used to it. Regards, Michael. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: The poor state of documentation of pcase like things. 2015-12-25 14:59 ` Michael Heerdegen @ 2015-12-25 16:55 ` John Wiegley 2015-12-26 6:13 ` Richard Stallman 1 sibling, 0 replies; 375+ messages in thread From: John Wiegley @ 2015-12-25 16:55 UTC (permalink / raw) To: Michael Heerdegen; +Cc: emacs-devel >>>>> Michael Heerdegen <michael_heerdegen@web.de> writes: > OTOH after you have written ",_" for yourself a three times or so, you'll > just have gotten used to it. I agree with Michael; special casing _ might be prettier, but it's actually more complicated, not less, and in a really subtle way. -- John Wiegley GPG fingerprint = 4710 CF98 AF9B 327B B80F http://newartisans.com 60E1 46C4 BD1A 7AC1 4BA2 ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: The poor state of documentation of pcase like things. 2015-12-25 14:59 ` Michael Heerdegen 2015-12-25 16:55 ` John Wiegley @ 2015-12-26 6:13 ` Richard Stallman 2015-12-26 17:10 ` Michael Heerdegen 1 sibling, 1 reply; 375+ messages in thread From: Richard Stallman @ 2015-12-26 6:13 UTC (permalink / raw) To: Michael Heerdegen; +Cc: emacs-devel [[[ 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. ]]] > If we make it just look like some > people guess it would be working, we are not doing them a favor, because > we just spare them to learn the real semantics at the moment. I am not convinced, but I won't argue about it. -- Dr Richard Stallman President, Free Software Foundation (gnu.org, fsf.org) Internet Hall-of-Famer (internethalloffame.org) Skype: No way! See stallman.org/skype.html. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: The poor state of documentation of pcase like things. 2015-12-26 6:13 ` Richard Stallman @ 2015-12-26 17:10 ` Michael Heerdegen 2015-12-26 20:52 ` Aaron Ecay 2015-12-27 2:53 ` Richard Stallman 0 siblings, 2 replies; 375+ messages in thread From: Michael Heerdegen @ 2015-12-26 17:10 UTC (permalink / raw) To: emacs-devel Richard Stallman <rms@gnu.org> writes: > I am not convinced, but I won't argue about it. I'm open to improvement suggestions, as long as they keep the thing consistent. We could try to define a new pattern offering destructuring looking less "unusual" (though we already have `seq' provided by seq.el which has very simple semantics). OTOH I think ` is already quite optimal for the set of features it offers. For the _ pattern, I guess we could reinvent it's meaning in pcase in general. But I don't see how the resulting semantics could be made equally simple as it is currently. Just changing what _ does in pcase's ` to save a comma would IMHO be what we call in German "verschlimmbessern" (my dictionary says you can translate that into "disimprove"). Regards, Michael. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: The poor state of documentation of pcase like things. 2015-12-26 17:10 ` Michael Heerdegen @ 2015-12-26 20:52 ` Aaron Ecay 2015-12-26 23:17 ` Michael Heerdegen 2015-12-27 2:53 ` Richard Stallman 1 sibling, 1 reply; 375+ messages in thread From: Aaron Ecay @ 2015-12-26 20:52 UTC (permalink / raw) To: Michael Heerdegen, emacs-devel Hi Michael, 2015ko abenudak 26an, Michael Heerdegen-ek idatzi zuen: > > Richard Stallman <rms@gnu.org> writes: > >> I am not convinced, but I won't argue about it. > > I'm open to improvement suggestions, as long as they keep the thing > consistent. > > We could try to define a new pattern offering destructuring looking less > "unusual" (though we already have `seq' provided by seq.el which has > very simple semantics). OTOH I think ` is already quite optimal for the > set of features it offers. > > For the _ pattern, I guess we could reinvent it's meaning in pcase in > general. But I don't see how the resulting semantics could be made > equally simple as it is currently. > > Just changing what _ does in pcase's ` to save a comma would IMHO be > what we call in German "verschlimmbessern" (my dictionary says you can > translate that into "disimprove"). Atoms (strings, numbers, and keywords) are simultaneously patterns and qpatterns. That is, one writes `(1 2) and not `(,1 ,2) to match a list containing 1 and 2 (though actually either form works). Why could _ not also be shared between the pattern and qpattern classes? (I guess part of the answer is aesthetics – but I’m pointing out that the set of patterns and qpatterns is already non-disjoint.) -- Aaron Ecay ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: The poor state of documentation of pcase like things. 2015-12-26 20:52 ` Aaron Ecay @ 2015-12-26 23:17 ` Michael Heerdegen 2016-01-01 7:57 ` Eli Zaretskii [not found] ` <<83y4c9ag06.fsf@gnu.org> 0 siblings, 2 replies; 375+ messages in thread From: Michael Heerdegen @ 2015-12-26 23:17 UTC (permalink / raw) To: Aaron Ecay; +Cc: emacs-devel Aaron Ecay <aaronecay@gmail.com> writes: > Atoms (strings, numbers, and keywords) are simultaneously patterns and > qpatterns. That is, one writes `(1 2) and not `(,1 ,2) to match a list > containing 1 and 2 (though actually either form works). Why could _ not > also be shared between the pattern and qpattern classes? If you consider that ` quotes any element in its argument list unless it is explicitly unquoted (that's how it actually works), an ATOM becomes 'ATOM, which is equivalent to just ATOM as a pattern. That one can avoid the comma before atoms inside ` reflects that equivalence on a different level. There are more such analogies (for example `something and 'something are equivalent if something doesn't include a comma) and it's good that they are there, because it makes the grammar easier to memorize, aka "build a mental model". Maybe you can call this "aesthetics" in this regard. Making _ a qpattern would break the logic in the design: '_ matches the symbol _, not anything as the _ pattern does (disjointness of qpatterns and pcase patterns is a different thing, and I think nobody cares about that). Making _ a qpattern wouldn't break pcase, but it would make the thing less consistent, because there would be a fracture somewhere in the logic, e.g. if _ is a qpattern matching anything, `_ and '_ would have different semantics as pcase patterns (the first would be equivalent to _), or such things. I would agree to do this anyway if there was a good reason. Saving a comma or fitting the expectations of users that haven't yet completely understood the semantics (I don't mean Phillip by that, I mean users who want to learn the thing) is not a sufficing reason for obfuscating the logic behind the design, I think. Another thing is that I think, and that's what we want to emphasize in the docs, that qpatterns are conceptually a different thing than pcase patterns. Actually, the term "qpattern" has not much meaning at all, it is only used as a helper to describe the grammar of ` (because it is recursive, but actually, the grammar is very simple). A qpattern is either an expression that is compared with equal, or a placeholder for a real pattern via unquoting. That's all. If the description of ` in pcase would be less formal and e.g. more like the doc of `backquote', we probably would not even have a name for that. Anyway, I think it's conceptually a bad thing to merge those two quite different things. Just my personal opinion of course. I've worked with pcase quite a lot now. It took some time until I had internalized the concept (which is why I think it's important to keep it simple). If others who have used the tool quite regularly do think it would be a good idea to make _ a qpattern, let's do it. But I think we should not hurry modifying a thing in a way which at the first look seems like a good idea, and we may regret later. Sorry for the prose, this was more than you had asked for. Regards, Michael. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: The poor state of documentation of pcase like things. 2015-12-26 23:17 ` Michael Heerdegen @ 2016-01-01 7:57 ` Eli Zaretskii 2016-01-01 17:46 ` John Wiegley [not found] ` <<83y4c9ag06.fsf@gnu.org> 1 sibling, 1 reply; 375+ messages in thread From: Eli Zaretskii @ 2016-01-01 7:57 UTC (permalink / raw) To: Michael Heerdegen, John Wiegley; +Cc: emacs-devel Btw, could someone please tell what are the benefits of using 'pcase' in snippets like this one: (pcase skip (`nil nil) (`0 t) (_ (setq i (+ i skip -1)) (funcall get-next-frame))))))) How is this different from using 'cond' in trivial ways? (I see quite a few of such uses of 'pcase' in the sources, and when I read them, I always wonder what is it that I'm missing about that code.) TIA ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: The poor state of documentation of pcase like things. 2016-01-01 7:57 ` Eli Zaretskii @ 2016-01-01 17:46 ` John Wiegley 2016-01-01 18:39 ` David Kastrup 2016-01-02 3:51 ` Drew Adams 0 siblings, 2 replies; 375+ messages in thread From: John Wiegley @ 2016-01-01 17:46 UTC (permalink / raw) To: Eli Zaretskii; +Cc: Michael Heerdegen, emacs-devel >>>>> Eli Zaretskii <eliz@gnu.org> writes: > (pcase skip > (`nil nil) > (`0 t) > (_ (setq i (+ i skip -1)) (funcall get-next-frame))))))) (cond ((null skip)) ((eq skip 0) t) (t (setq i (+ i skip -1)) (funcall get-next-frame))) Not much difference. Also, `0 could just be 0. One thing it does do: avoids repeating "skip" in the first two tests. That's the only merit I can see, but would have been more worthwhile if there were, say, 10 value tests. -- John Wiegley GPG fingerprint = 4710 CF98 AF9B 327B B80F http://newartisans.com 60E1 46C4 BD1A 7AC1 4BA2 ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: The poor state of documentation of pcase like things. 2016-01-01 17:46 ` John Wiegley @ 2016-01-01 18:39 ` David Kastrup 2016-01-01 19:05 ` Daniel Colascione 2016-01-02 1:15 ` Richard Copley 2016-01-02 3:51 ` Drew Adams 1 sibling, 2 replies; 375+ messages in thread From: David Kastrup @ 2016-01-01 18:39 UTC (permalink / raw) To: Eli Zaretskii; +Cc: Michael Heerdegen, emacs-devel John Wiegley <jwiegley@gmail.com> writes: >>>>>> Eli Zaretskii <eliz@gnu.org> writes: > >> (pcase skip >> (`nil nil) >> (`0 t) >> (_ (setq i (+ i skip -1)) (funcall get-next-frame))))))) > > (cond ((null skip)) > ((eq skip 0) t) > (t (setq i (+ i skip -1)) > (funcall get-next-frame))) > > Not much difference. If skip is nil, the first returns probably nil and the second t. One could probably do (and skip (or (eql skip 0) (setq ...))) I'm not fond of eq for numeric comparisons: that's an Elispism. -- David Kastrup ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: The poor state of documentation of pcase like things. 2016-01-01 18:39 ` David Kastrup @ 2016-01-01 19:05 ` Daniel Colascione 2016-01-02 8:16 ` Eli Zaretskii 2016-01-02 1:15 ` Richard Copley 1 sibling, 1 reply; 375+ messages in thread From: Daniel Colascione @ 2016-01-01 19:05 UTC (permalink / raw) To: David Kastrup, Eli Zaretskii; +Cc: Michael Heerdegen, emacs-devel [-- Attachment #1: Type: text/plain, Size: 755 bytes --] On 01/01/2016 10:39 AM, David Kastrup wrote: > John Wiegley <jwiegley@gmail.com> writes: > >>>>>>> Eli Zaretskii <eliz@gnu.org> writes: >> >>> (pcase skip >>> (`nil nil) >>> (`0 t) >>> (_ (setq i (+ i skip -1)) (funcall get-next-frame))))))) >> >> (cond ((null skip)) >> ((eq skip 0) t) >> (t (setq i (+ i skip -1)) >> (funcall get-next-frame))) >> >> Not much difference. > > If skip is nil, the first returns probably nil and the second t. One > could probably do > > (and skip > (or (eql skip 0) > (setq ...))) > > I'm not fond of eq for numeric comparisons: that's an Elispism. That's true, but I think it's too pervasive to change now, so why fight it? [-- Attachment #2: OpenPGP digital signature --] [-- Type: application/pgp-signature, Size: 819 bytes --] ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: The poor state of documentation of pcase like things. 2016-01-01 19:05 ` Daniel Colascione @ 2016-01-02 8:16 ` Eli Zaretskii 2016-01-02 8:35 ` David Kastrup 2016-01-03 0:41 ` Dmitry Gutov 0 siblings, 2 replies; 375+ messages in thread From: Eli Zaretskii @ 2016-01-02 8:16 UTC (permalink / raw) To: Daniel Colascione; +Cc: michael_heerdegen, dak, emacs-devel > From: Daniel Colascione <dancol@dancol.org> > Date: Fri, 1 Jan 2016 11:05:31 -0800 > Cc: Michael Heerdegen <michael_heerdegen@web.de>, emacs-devel@gnu.org > > >>> (pcase skip > >>> (`nil nil) > >>> (`0 t) > >>> (_ (setq i (+ i skip -1)) (funcall get-next-frame))))))) > >> > >> (cond ((null skip)) > >> ((eq skip 0) t) > >> (t (setq i (+ i skip -1)) > >> (funcall get-next-frame))) > >> > >> Not much difference. > > > > If skip is nil, the first returns probably nil and the second t. One > > could probably do > > > > (and skip > > (or (eql skip 0) > > (setq ...))) > > > > I'm not fond of eq for numeric comparisons: that's an Elispism. > > That's true, but I think it's too pervasive to change now, so why fight it? Who said anything about fighting? I just asked if there was anything there that I was missing. Now that I know there isn't, I can convert such code to using 'cond' whenever I feel like it. Like we do with whitespace changes. Thanks. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: The poor state of documentation of pcase like things. 2016-01-02 8:16 ` Eli Zaretskii @ 2016-01-02 8:35 ` David Kastrup 2016-01-03 0:19 ` Michael Heerdegen 2016-01-03 0:41 ` Dmitry Gutov 1 sibling, 1 reply; 375+ messages in thread From: David Kastrup @ 2016-01-02 8:35 UTC (permalink / raw) To: Eli Zaretskii; +Cc: michael_heerdegen, Daniel Colascione, emacs-devel Eli Zaretskii <eliz@gnu.org> writes: >> From: Daniel Colascione <dancol@dancol.org> >> Date: Fri, 1 Jan 2016 11:05:31 -0800 >> Cc: Michael Heerdegen <michael_heerdegen@web.de>, emacs-devel@gnu.org [pcase stuff] >> > One could probably do >> > >> > (and skip >> > (or (eql skip 0) >> > (setq ...))) >> > >> > I'm not fond of eq for numeric comparisons: that's an Elispism. >> >> That's true, but I think it's too pervasive to change now, so why >> fight it? > > Who said anything about fighting? I just asked if there was anything > there that I was missing. I am pretty sure Daniel was referring to my eq/eql side remark. I certainly hope that "pervasive" is not a proper characterization of pcase use yet though I haven't checked. > Now that I know there isn't, I can convert such code to using 'cond' > whenever I feel like it. Like we do with whitespace changes. Some of the quoted pcase examples indeed felt like the "if your preferred tool is a hammer, every problem looks like a nail" phenomenon. There certainly is a case for liberal use of complex complexity-taming constructs (for example, overall I can appreciate how cl-loop straightens out a lot of awkward loop constructs even though its syntax is not really Elisp-like). But when a simple construct is a perfect fit, it's not helping understanding. -- David Kastrup ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: The poor state of documentation of pcase like things. 2016-01-02 8:35 ` David Kastrup @ 2016-01-03 0:19 ` Michael Heerdegen 2016-01-03 2:47 ` Drew Adams ` (2 more replies) 0 siblings, 3 replies; 375+ messages in thread From: Michael Heerdegen @ 2016-01-03 0:19 UTC (permalink / raw) To: David Kastrup; +Cc: Eli Zaretskii, Daniel Colascione, emacs-devel David Kastrup <dak@gnu.org> writes: > Some of the quoted pcase examples indeed felt like the "if your > preferred tool is a hammer, every problem looks like a nail" > phenomenon. Ironically, the same applies to Emacs itself ;-) > There certainly is a case for liberal use of complex complexity-taming > constructs (for example, overall I can appreciate how cl-loop > straightens out a lot of awkward loop constructs even though its syntax > is not really Elisp-like). But when a simple construct is a perfect > fit, it's not helping understanding. I don't see how a pcase used like a cl-case - as in the quoted example - is any harder to read or understand. And of course it has also advantages to use pcase in such cases. If you want to change the code or try things and you suddenly want a feature from pcase, you don't have to rewrite the whole thing. It just...arguable what you prefer. What I find a bit irritating is this seemingly upcoming kind of agreement "Please, let's all avoid this thing, ok? - it's frightening!" I read between the lines. Sorry if my impression is wrong. Michael. ^ permalink raw reply [flat|nested] 375+ messages in thread
* RE: The poor state of documentation of pcase like things. 2016-01-03 0:19 ` Michael Heerdegen @ 2016-01-03 2:47 ` Drew Adams 2016-01-03 3:21 ` Michael Heerdegen 2016-01-03 3:45 ` Eli Zaretskii 2016-01-03 9:03 ` David Kastrup 2 siblings, 1 reply; 375+ messages in thread From: Drew Adams @ 2016-01-03 2:47 UTC (permalink / raw) To: Michael Heerdegen, David Kastrup Cc: Eli Zaretskii, Daniel Colascione, emacs-devel > I don't see how a pcase used like a cl-case - as in the quoted example - > is any harder to read or understand. > > And of course it has also advantages to use pcase in such cases. If you > want to change the code or try things and you suddenly want a feature > from pcase, you don't have to rewrite the whole thing. > > It just...arguable what you prefer. Yes. So let me argue ;-) in favor of using `pcase' only, or mainly, when decomposition pattern-matching is used, and not just for literal tests. Your point is that `pcase' is more general, so if you want to later add a clause that does make use of decomposition pattern-matching then it's easy to do so. That is a good argument. It's not the argument that persuades me, however. I generally come down on the side of trying to have the most readable code, even at the cost of more maintenance work, in terms of typing. Why? Because I think that code readability is primary, and the biggest maintenance burden is not typing but understanding. Why do I think that a control structure that tests only literals is clearer for literal-testing than one that also uses decomposition patterns? Because the former necessarily shouts that there are ONLY literal tests here. `pcase' is harder to parse not just because some of us might not be as used to it, but also precisely because of its generality. You have to look closely, to see whether there might be some decomposition pattern-matching going on. (Occam's razor. Einstein's as-simple-as-possible-but-no-simpler.) Because `pcase' is so general that it can handle also fancy patterns, its syntax is more involved - overkill. Not overkill for the cases where it makes sense and takes advantage of pattern matching. But overkill for the mundane, literal-matching cases. I prefer to use the simpler `cl-case' or whatever when possible, because it says, loud-and-clear, to a reader: "Nothing fancy here." The reader is the one who counts, for me, not the writer. And I don't mind having to later rewrite the code if a feature change or bug fix makes it possible to really take advantage of what `pcase' has to offer. Yes, that's an added burden, but one that I, personally, don't mind. (I'm talking about me and my code. I can understand, if Emacs maintainers feel differently about the distributed Emacs code.) IOW, I echo the hammer=>nail reflection that David made. There is no need to think that `pcase' _needs_ to be used everywhere, just because it _can_ be used everywhere. (And I feel the same about `loop', FWIW.) Just one opinion, of course. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: The poor state of documentation of pcase like things. 2016-01-03 2:47 ` Drew Adams @ 2016-01-03 3:21 ` Michael Heerdegen 2016-01-03 3:46 ` Drew Adams 0 siblings, 1 reply; 375+ messages in thread From: Michael Heerdegen @ 2016-01-03 3:21 UTC (permalink / raw) To: emacs-devel Drew Adams <drew.adams@oracle.com> writes: > Just one opinion, of course. I think I do the same most of the time. Probably some examples of pcase in the sources are not good code, and not good examples of how work with pcase. You can write good and bad pcase code, code that emphasizes what it's doing, and code that looks more like the result of a mechanical replacement. Maybe the latter is the case for a lot of places in the sources. But I think I agree to the goal to use cl-case where possible. cond is a bit different, since it is as powerful as pcase (in principle), so when you see a cond, you can't assume much about what is (not) done there. pcase is not only useful when destructuring is involved (though it is the most important feature). The often cited case of a long list of conditions that only tests for equality for a longer list of symbols is a good example, but also an extreme one, because this is a case that doesn't appear so often in practise. Oh, and I also think there are a lot of places in the sources that would get simpler when using pcase. Michael. ^ permalink raw reply [flat|nested] 375+ messages in thread
* RE: The poor state of documentation of pcase like things. 2016-01-03 3:21 ` Michael Heerdegen @ 2016-01-03 3:46 ` Drew Adams 2016-01-03 5:17 ` Michael Heerdegen 0 siblings, 1 reply; 375+ messages in thread From: Drew Adams @ 2016-01-03 3:46 UTC (permalink / raw) To: Michael Heerdegen, emacs-devel > You can write good and bad > pcase code, code that emphasizes what it's doing, and code that looks > more like the result of a mechanical replacement. +1 for that formulation: "code that emphasizes what it's doing". When I see a `pcase' I want it to be telling me that there is some local-binding (decomposition pattern-matching) going on. > But I think I agree to the goal to use cl-case where possible. > cond is a bit different, Definitely different from `cl-case', since it does not do any pattern-matching (except perhaps by explicit testing with a predicate). > since it is as powerful as pcase (in principle), See previous - it does not do pattern-matching. And that is the particular "power" of `pcase' - what it really has to offer (IMO). > so when you see a cond, you can't assume much about what is (not) done > there. > pcase is not only useful when destructuring is involved (though > it is the most important feature). I disagree. I think it is only useful when destructuring is involved. If it is just doing literal pattern-matching then it offers nothing more than does `cl-case'. (Unless it lets you change the equality predicate (does it?). That's one thing that I wish `cl-case' (and Common lisp `case') would let you do: specify something a comparer other than `eql'.) > The often cited case of a long list of conditions that only tests for > equality for a longer list of symbols is a good example, I don't know what example you mean. Do you mean testing for equality against more than one symbol, as in multiple `cl-case's? Or testing the same symbol value more than once (just use a `let')? > but also an extreme one, because this is a case that doesn't appear > so often in practise. > > Oh, and I also think there are a lot of places in the sources that would > get simpler when using pcase. To vague to judge whether you are right. But maybe so, if you mean taking advantage of destructuring. The same would be true of a let construct that only destructures (e.g., `destructuring-bind'). ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: The poor state of documentation of pcase like things. 2016-01-03 3:46 ` Drew Adams @ 2016-01-03 5:17 ` Michael Heerdegen 0 siblings, 0 replies; 375+ messages in thread From: Michael Heerdegen @ 2016-01-03 5:17 UTC (permalink / raw) To: emacs-devel Drew Adams <drew.adams@oracle.com> writes: > > pcase is not only useful when destructuring is involved (though > > it is the most important feature). > > I disagree. I think it is only useful when destructuring is > involved. If it is just doing literal pattern-matching then > it offers nothing more than does `cl-case'. Well, there are some more pattern types available, and you can all combine them. > (Unless it lets you change the equality predicate (does it?). No, but you can just use (pred (my-eq thing)) as pattern. That would test whether `thing' is `my-eq' to the object. > > The often cited case of a long list of conditions that only tests > > for equality for a longer list of symbols is a good example, > > I don't know what example you mean. Do you mean testing > for equality against more than one symbol, as in multiple > `cl-case's? Or testing the same symbol value more than once > (just use a `let')? I was talking about Lars' example. > The same would be true of a let construct that only destructures > (e.g., `destructuring-bind'). destructuring-bind is much less powerful than pcase. pcase can test whether something matches, combined with condition testing, boolean operations and local variable binding. There are cases where it's worth it to prefer pcase over other tools where no destr-bind is involved. But that's a minority of cases, yes. Michael. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: The poor state of documentation of pcase like things. 2016-01-03 0:19 ` Michael Heerdegen 2016-01-03 2:47 ` Drew Adams @ 2016-01-03 3:45 ` Eli Zaretskii 2016-01-03 4:21 ` Michael Heerdegen 2016-01-03 9:03 ` David Kastrup 2 siblings, 1 reply; 375+ messages in thread From: Eli Zaretskii @ 2016-01-03 3:45 UTC (permalink / raw) To: Michael Heerdegen; +Cc: dak, dancol, emacs-devel > From: Michael Heerdegen <michael_heerdegen@web.de> > Cc: Eli Zaretskii <eliz@gnu.org>, Daniel Colascione <dancol@dancol.org>, emacs-devel@gnu.org > Date: Sun, 03 Jan 2016 01:19:55 +0100 > > I don't see how a pcase used like a cl-case - as in the quoted example - > is any harder to read or understand. Are you serious? We've just had a long discussion about its missing or incomplete or inadequate documentation, including a long dispute about whether it would be better to quote _. My summary of that discussion is that the syntax is complicated and quite weird. Using such a beast where it is not required makes reading harder because it requires the reader to understand its syntax, if nothing else. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: The poor state of documentation of pcase like things. 2016-01-03 3:45 ` Eli Zaretskii @ 2016-01-03 4:21 ` Michael Heerdegen 2016-01-03 9:13 ` David Kastrup 2016-01-03 15:29 ` Eli Zaretskii 0 siblings, 2 replies; 375+ messages in thread From: Michael Heerdegen @ 2016-01-03 4:21 UTC (permalink / raw) To: Eli Zaretskii; +Cc: dak, dancol, emacs-devel Eli Zaretskii <eliz@gnu.org> writes: > Are you serious? We've just had a long discussion about its missing > or incomplete or inadequate documentation, I know that, but that we can and want to fix, so it is no argument about whether pcase is really eval or not. > including a long dispute about whether it would be better to quote _. Yes, and...??? > My summary of that discussion is that the syntax is complicated and > quite weird. Where did we at all talk about the syntax? Or do you just mean those examples that were shorter than with any other tool? Or those that were faster? > Using such a beast where it is not required makes reading harder > because it requires the reader to understand its syntax, if nothing > else. And that's the real problem: (some) people refrain to try to understand the syntax and prefer to complain. The syntax is very simple for its expressiveness. But maybe I'm just obsessed by the beast. Sorry, I give up. pcase seems to scare off people somehow. If 50 percent of the people are not able to cope with the thing, for whatever reason, and get stalled whenever they see it, I think we probably can't use it. A pity. Is it even worth to update the docs of pcase? Will anyone from those antagonizing it really try to learn how the thing is supposed to be used? I've got the feeling some people anyway prefer to gain their knowledge from such pcase-bashing discussions. Michael. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: The poor state of documentation of pcase like things. 2016-01-03 4:21 ` Michael Heerdegen @ 2016-01-03 9:13 ` David Kastrup 2016-01-03 16:52 ` Clément Pit--Claudel 2016-01-04 1:28 ` Michael Heerdegen 2016-01-03 15:29 ` Eli Zaretskii 1 sibling, 2 replies; 375+ messages in thread From: David Kastrup @ 2016-01-03 9:13 UTC (permalink / raw) To: Michael Heerdegen; +Cc: Eli Zaretskii, dancol, emacs-devel Michael Heerdegen <michael_heerdegen@web.de> writes: > The syntax is very simple for its expressiveness. So? In ancient Greek, "you two should have started feeling a bit ashamed of yourself" is a single word (employing the numerus Dual, the mode Optative, the time Aorist, and a compounded word). The syntax is very simple for its expressiveness. There is a reason we don't use it any more. > But maybe I'm just obsessed by the beast. If you want to use the syntax where no expressiveness is required because you find it to be a nice tradeoff in case where huge amounts of expressiveness are required, yes, you may be obsessed by it. As it stands, we are just converging on the syntax. It makes sense to do that on those cases where the differences count, namely the complex ones, so that we don't need to change the simple ones all over the map for every change we make. > Sorry, I give up. pcase seems to scare off people somehow. We don't use any constructs for the sake of using them. We use them to get stuff done in a manner where other people feel comfortable picking up where we left off. Using complex constructs for simple, well-covered cases tends not to do that. -- David Kastrup ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: The poor state of documentation of pcase like things. 2016-01-03 9:13 ` David Kastrup @ 2016-01-03 16:52 ` Clément Pit--Claudel 2016-01-04 1:28 ` Michael Heerdegen 1 sibling, 0 replies; 375+ messages in thread From: Clément Pit--Claudel @ 2016-01-03 16:52 UTC (permalink / raw) To: emacs-devel On 01/03/2016 04:13 AM, David Kastrup wrote: > So? In ancient Greek, "you two should have started feeling a bit > ashamed of yourself" is a single word (employing the numerus Dual, the > mode Optative, the time Aorist, and a compounded word). > > The syntax is very simple for its expressiveness. There is a reason we > don't use it any more. ??? ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: The poor state of documentation of pcase like things. 2016-01-03 9:13 ` David Kastrup 2016-01-03 16:52 ` Clément Pit--Claudel @ 2016-01-04 1:28 ` Michael Heerdegen 1 sibling, 0 replies; 375+ messages in thread From: Michael Heerdegen @ 2016-01-04 1:28 UTC (permalink / raw) To: emacs-devel David Kastrup <dak@gnu.org> writes: > > But maybe I'm just obsessed by the beast. > > If you want to use the syntax where no expressiveness is required > because you find it to be a nice tradeoff in case where huge amounts of > expressiveness are required, yes, you may be obsessed by it. Where did I say I would want that? And didn't I already agree to Drew's complete message suggesting the opposite, and said that I do this myself? Michael. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: The poor state of documentation of pcase like things. 2016-01-03 4:21 ` Michael Heerdegen 2016-01-03 9:13 ` David Kastrup @ 2016-01-03 15:29 ` Eli Zaretskii 2016-01-04 2:05 ` Michael Heerdegen 1 sibling, 1 reply; 375+ messages in thread From: Eli Zaretskii @ 2016-01-03 15:29 UTC (permalink / raw) To: Michael Heerdegen; +Cc: dak, dancol, emacs-devel > From: Michael Heerdegen <michael_heerdegen@web.de> > Cc: dak@gnu.org, dancol@dancol.org, emacs-devel@gnu.org > Date: Sun, 03 Jan 2016 05:21:48 +0100 > > > Are you serious? We've just had a long discussion about its missing > > or incomplete or inadequate documentation, > > I know that, but that we can and want to fix, so it is no argument about > whether pcase is really eval or not. The discussion is IMO a clear indication that at least some people have difficulties reading the code which involves 'pcase'. Which means, IMO, that it shouldn't be used where simpler, more clear forms will do. > > including a long dispute about whether it would be better to quote _. > > Yes, and...??? And that was IMO a clear indication that even the tiniest syntax issues related to 'pcase' raise problems. > > My summary of that discussion is that the syntax is complicated and > > quite weird. > > Where did we at all talk about the syntax? If the semantics are not clear, the syntax is the first suspect. > > Using such a beast where it is not required makes reading harder > > because it requires the reader to understand its syntax, if nothing > > else. > > And that's the real problem: (some) people refrain to try to understand > the syntax and prefer to complain. That's not my concern. I'm not one of those people. > Sorry, I give up. pcase seems to scare off people somehow. If 50 > percent of the people are not able to cope with the thing, for whatever > reason, and get stalled whenever they see it, I think we probably can't > use it. A pity. I never said anything even close to such an extreme. I don't think there's any danger of refraining to use 'pcase' any time soon. It does its job well, and where it's needed, it should definitely be used. > Is it even worth to update the docs of pcase? Yes, definitely. With the current proliferation of its use in our sources, we cannot leave it under-documented. I hope to see proposals for documentation patches soon, thank you. > Will anyone from those antagonizing it really try to learn how the > thing is supposed to be used? I'm sure more than one will, indeed. Thanks. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: The poor state of documentation of pcase like things. 2016-01-03 15:29 ` Eli Zaretskii @ 2016-01-04 2:05 ` Michael Heerdegen 0 siblings, 0 replies; 375+ messages in thread From: Michael Heerdegen @ 2016-01-04 2:05 UTC (permalink / raw) To: emacs-devel Eli Zaretskii <eliz@gnu.org> writes: > > > including a long dispute about whether it would be better to quote _. > > > > Yes, and...??? > > And that was IMO a clear indication that even the tiniest syntax > issues related to 'pcase' raise problems. If the fact that some people suggested to make it possible to leave out a comma counts as a relevant problem or bug, I must say I'm surprised how well this quite new thing works, after all, a complete new library. The syntax still has been changed by Stefan himself recently, so it's normal that we still discuss it, even when we didn't find a conclusion. > If the semantics are not clear, the syntax is the first suspect. > > > Using such a beast where it is not required makes reading harder > > > because it requires the reader to understand its syntax, if nothing > > > else. > > > > And that's the real problem: (some) people refrain to try to understand > > the syntax and prefer to complain. > > That's not my concern. I'm not one of those people. Ok. So, what aspect of the semantics did you find not clear after reading the documentation we currently have? > > Sorry, I give up. pcase seems to scare off people somehow. If 50 > > percent of the people are not able to cope with the thing, for whatever > > reason, and get stalled whenever they see it, I think we probably can't > > use it. A pity. > > I never said anything even close to such an extreme. I don't think > there's any danger of refraining to use 'pcase' any time soon. It > does its job well, and where it's needed, it should definitely be > used. That sounds somewhat different from what you said previously ("beast", your conclusions about the discussion that the thing is "weird", etc). Regards, Michael. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: The poor state of documentation of pcase like things. 2016-01-03 0:19 ` Michael Heerdegen 2016-01-03 2:47 ` Drew Adams 2016-01-03 3:45 ` Eli Zaretskii @ 2016-01-03 9:03 ` David Kastrup 2016-01-04 2:08 ` Michael Heerdegen 2 siblings, 1 reply; 375+ messages in thread From: David Kastrup @ 2016-01-03 9:03 UTC (permalink / raw) To: Michael Heerdegen; +Cc: Eli Zaretskii, Daniel Colascione, emacs-devel Michael Heerdegen <michael_heerdegen@web.de> writes: > David Kastrup <dak@gnu.org> writes: > >> Some of the quoted pcase examples indeed felt like the "if your >> preferred tool is a hammer, every problem looks like a nail" >> phenomenon. > > Ironically, the same applies to Emacs itself ;-) > >> There certainly is a case for liberal use of complex complexity-taming >> constructs (for example, overall I can appreciate how cl-loop >> straightens out a lot of awkward loop constructs even though its syntax >> is not really Elisp-like). But when a simple construct is a perfect >> fit, it's not helping understanding. > > I don't see how a pcase used like a cl-case - as in the quoted example - > is any harder to read or understand. Quasiquotes are quasiquotes. They are harder to read for the Lisp reader, and they are harder to read for the human reader. -- David Kastrup ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: The poor state of documentation of pcase like things. 2016-01-03 9:03 ` David Kastrup @ 2016-01-04 2:08 ` Michael Heerdegen 2016-01-04 22:05 ` John Wiegley 0 siblings, 1 reply; 375+ messages in thread From: Michael Heerdegen @ 2016-01-04 2:08 UTC (permalink / raw) To: emacs-devel David Kastrup <dak@gnu.org> writes: > > I don't see how a pcase used like a cl-case - as in the quoted example - > > is any harder to read or understand. > > Quasiquotes are quasiquotes. They are harder to read for the Lisp > reader, and they are harder to read for the human reader. I already said it multiple times, and I will say it again, every time this complaint is formulated: This is outdated syntax, you don't have to use backquote to quote symbols, only when you really want to do list destructuring. Michael. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: The poor state of documentation of pcase like things. 2016-01-04 2:08 ` Michael Heerdegen @ 2016-01-04 22:05 ` John Wiegley 0 siblings, 0 replies; 375+ messages in thread From: John Wiegley @ 2016-01-04 22:05 UTC (permalink / raw) To: Michael Heerdegen; +Cc: emacs-devel >>>>> Michael Heerdegen <michael_heerdegen@web.de> writes: > I already said it multiple times, and I will say it again, every time this > complaint is formulated: This is outdated syntax, you don't have to use > backquote to quote symbols, only when you really want to do list > destructuring. Please move this discussion to emacs-tangents. Thank you, -- John Wiegley GPG fingerprint = 4710 CF98 AF9B 327B B80F http://newartisans.com 60E1 46C4 BD1A 7AC1 4BA2 ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: The poor state of documentation of pcase like things. 2016-01-02 8:16 ` Eli Zaretskii 2016-01-02 8:35 ` David Kastrup @ 2016-01-03 0:41 ` Dmitry Gutov 2016-01-03 1:07 ` Lars Magne Ingebrigtsen 2016-01-03 3:47 ` Eli Zaretskii 1 sibling, 2 replies; 375+ messages in thread From: Dmitry Gutov @ 2016-01-03 0:41 UTC (permalink / raw) To: Eli Zaretskii, Daniel Colascione; +Cc: michael_heerdegen, dak, emacs-devel On 01/02/2016 10:16 AM, Eli Zaretskii wrote: > Now that I know there isn't, I can convert such code to using 'cond' > whenever I feel like it. Like we do with whitespace changes. FWIW, converting that kind of pcase form to a cond, to my eyes, would look like replacing (when ...) with (if ... (progn ...))). ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: The poor state of documentation of pcase like things. 2016-01-03 0:41 ` Dmitry Gutov @ 2016-01-03 1:07 ` Lars Magne Ingebrigtsen 2016-01-03 1:21 ` Dmitry Gutov ` (2 more replies) 2016-01-03 3:47 ` Eli Zaretskii 1 sibling, 3 replies; 375+ messages in thread From: Lars Magne Ingebrigtsen @ 2016-01-03 1:07 UTC (permalink / raw) To: Dmitry Gutov Cc: michael_heerdegen, Eli Zaretskii, Daniel Colascione, dak, emacs-devel Dmitry Gutov <dgutov@yandex.ru> writes: > On 01/02/2016 10:16 AM, Eli Zaretskii wrote: > >> Now that I know there isn't, I can convert such code to using 'cond' >> whenever I feel like it. Like we do with whitespace changes. > > FWIW, converting that kind of pcase form to a cond, to my eyes, would > look like replacing (when ...) with (if ... (progn ...))). Well, I'd say that pcase is kinda awkward because you can't tell by skimming whether it's complex or not (which is something it shares with cond, in a way). Take for instance the following I was reading in url-http (simplified and way shortened): (pcase status-symbol (`unauthorized ; 401 (url-http-handle-authentication nil)) (`payment-required ; 402 (url-mark-buffer-as-dead buffer) (error "Somebody wants you to give them money")) (`forbidden ; 403 t) (`not-found ; 404 t) (`method-not-allowed ; 405 t) ...) The only way you'll know whether `status-symbol' is really a symbol, and all the cases are really symbols, is by reading the entire thing. The 44th case could have been (_ foo bar zot), for instance. In Common Lisp, you'd say (case status-symbol (unauthorized ; 401 (url-http-handle-authentication nil)) (payment-required ; 402 (url-mark-buffer-as-dead buffer) (error "Somebody wants you to give them money")) (forbidden ; 403 t) (not-found ; 404 t) (method-not-allowed ; 405 t) ...) and you'd know that this was a simple `eql' thing going on here. I kinda liked pcase at first, but the more I see of the pcase language, the more sceptical I get. I'm beginning to wonder whether the whole thing is a misfeature that should be replaced with several separate operators. -- (domestic pets only, the antidote for overdose, milk.) bloggy blog: http://lars.ingebrigtsen.no ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: The poor state of documentation of pcase like things. 2016-01-03 1:07 ` Lars Magne Ingebrigtsen @ 2016-01-03 1:21 ` Dmitry Gutov 2016-01-03 2:49 ` Drew Adams 2016-01-03 1:32 ` Michael Heerdegen 2016-01-03 2:48 ` Drew Adams 2 siblings, 1 reply; 375+ messages in thread From: Dmitry Gutov @ 2016-01-03 1:21 UTC (permalink / raw) To: Lars Magne Ingebrigtsen Cc: michael_heerdegen, Eli Zaretskii, Daniel Colascione, dak, emacs-devel On 01/03/2016 03:07 AM, Lars Magne Ingebrigtsen wrote: > The only way you'll know whether `status-symbol' is really a symbol, and > all the cases are really symbols, is by reading the entire thing. The > 44th case could have been (_ foo bar zot), for instance. How is that different from cond? If I have cond like this: (cond ((eq status-symbol 'unauthorized) (url-http-handle-authentication nil)) ((eq status-symbol 'payment-required) (url-mark-buffer-as-dead buffer) (error "Somebody wants you to give them money")) ...) ...you'll also have to read until its end to find out for sure whether the variable name lies or not: (cond ((eq status-symbol 'unauthorized) (url-http-handle-authentication nil)) ((eq status-symbol 'payment-required) (url-mark-buffer-as-dead buffer) (error "Somebody wants you to give them money")) ((memq 'zomg status-symbol) (give-away all-moneys))) > In Common Lisp, you'd say cl-case is more restricted, yes, but I thought this discussion was about how pcase is worse than cond. > I kinda liked pcase at first, but the more I see of the pcase language, > the more sceptical I get. I'm beginning to wonder whether the whole > thing is a misfeature that should be replaced with several separate > operators. You mean pattern matching? A lot of language and library designers would disagree with you. ^ permalink raw reply [flat|nested] 375+ messages in thread
* RE: The poor state of documentation of pcase like things. 2016-01-03 1:21 ` Dmitry Gutov @ 2016-01-03 2:49 ` Drew Adams 2016-01-03 10:49 ` David Kastrup 0 siblings, 1 reply; 375+ messages in thread From: Drew Adams @ 2016-01-03 2:49 UTC (permalink / raw) To: Dmitry Gutov, Lars Magne Ingebrigtsen Cc: michael_heerdegen, Eli Zaretskii, Daniel Colascione, dak, emacs-devel > cl-case is more restricted, yes, but I thought this discussion was about > how pcase is worse than cond. I don't think so. To me, this discussion is about whether to use `pcase': * Only when it really offers something, * All the time, everywhere, * Or something in between (what?). > > I kinda liked pcase at first, but the more I see of the pcase language, > > the more sceptical I get. I'm beginning to wonder whether the whole > > thing is a misfeature that should be replaced with several separate > > operators. > > You mean pattern matching? A lot of language and library designers would > disagree with you. Decomposition pattern-matching. Use it when it helps. Literal "pattern" matching does not require `pcase'. Should `pcase' be used for such mundane cases anyway, since it can be? That's the question that I think is being discussed. Whether wholesale replacement of `cond', `case', `if', etc. by `pcase' is a good idea, just because it could do the job. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: The poor state of documentation of pcase like things. 2016-01-03 2:49 ` Drew Adams @ 2016-01-03 10:49 ` David Kastrup 0 siblings, 0 replies; 375+ messages in thread From: David Kastrup @ 2016-01-03 10:49 UTC (permalink / raw) To: Drew Adams Cc: michael_heerdegen, emacs-devel, Dmitry Gutov, Lars Magne Ingebrigtsen, Daniel Colascione, Eli Zaretskii Drew Adams <drew.adams@oracle.com> writes: > That's the question that I think is being discussed. Whether > wholesale replacement of `cond', `case', `if', etc. by `pcase' is a > good idea, just because it could do the job. I don't write `("blabla") on the off-chance that someone would want to replace it with `(,(concat `"bla" `"bla")). We don't quote self-quoting forms gratuitously, and we don't use quasiquote gratuitously: the latter only gets used when we indeed use an unquoting form inside. In short, we don't use constructs for the sake of using constructs. -- David Kastrup ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: The poor state of documentation of pcase like things. 2016-01-03 1:07 ` Lars Magne Ingebrigtsen 2016-01-03 1:21 ` Dmitry Gutov @ 2016-01-03 1:32 ` Michael Heerdegen 2016-01-03 2:48 ` Drew Adams 2 siblings, 0 replies; 375+ messages in thread From: Michael Heerdegen @ 2016-01-03 1:32 UTC (permalink / raw) To: Lars Magne Ingebrigtsen Cc: Eli Zaretskii, Daniel Colascione, emacs-devel, dak, Dmitry Gutov Lars Magne Ingebrigtsen <larsi@gnus.org> writes: > Well, I'd say that pcase is kinda awkward because you can't tell by > skimming whether it's complex or not (which is something it shares with > cond, in a way). Take for instance the following I was reading in > url-http (simplified and way shortened): > > (pcase status-symbol > (`unauthorized ; 401 > (url-http-handle-authentication nil)) > (`payment-required ; 402 > (url-mark-buffer-as-dead buffer) > (error "Somebody wants you to give them money")) > (`forbidden ; 403 > t) > (`not-found ; 404 > t) > (`method-not-allowed ; 405 > t) > ...) > > The only way you'll know whether `status-symbol' is really a symbol, and > all the cases are really symbols, is by reading the entire thing. The > 44th case could have been (_ foo bar zot), for instance. That code indeed looks weird. But you can also write similarly weird code with `cond'. > I kinda liked pcase at first, but the more I see of the pcase language, > the more sceptical I get. I'm beginning to wonder whether the whole > thing is a misfeature that should be replaced with several separate > operators. The concept (one can combine different types of things and tests - destructuring, predicate testing, matching against constants etc.) has it's pros and cons. In cases where one single tool doesn't fit, it is a very good thing when the code doesn't need to nest different types of tools, and the layout can concentrate on the different cases. Michael. ^ permalink raw reply [flat|nested] 375+ messages in thread
* RE: The poor state of documentation of pcase like things. 2016-01-03 1:07 ` Lars Magne Ingebrigtsen 2016-01-03 1:21 ` Dmitry Gutov 2016-01-03 1:32 ` Michael Heerdegen @ 2016-01-03 2:48 ` Drew Adams 2016-01-03 3:11 ` Noam Postavsky 2 siblings, 1 reply; 375+ messages in thread From: Drew Adams @ 2016-01-03 2:48 UTC (permalink / raw) To: Lars Magne Ingebrigtsen, Dmitry Gutov Cc: michael_heerdegen, Eli Zaretskii, Daniel Colascione, dak, emacs-devel > Well, I'd say that pcase is kinda awkward because you can't tell by > skimming whether it's complex or not 100% agreement. That's really the point, for me. * `pcase' shouts: "This might be complicated. Better look closely." * `cond' and `cl-case' and `if' ... shout: "Nothing fancy here. We're only testing literals" > (pcase status-symbol ...) > > The only way you'll know whether `status-symbol' is really a symbol, and > all the cases are really symbols, is by reading the entire thing. The > 44th case could have been (_ foo bar zot), for instance. > > (case status-symbol ...) > > and you'd know that this was a simple `eql' thing going on here. > > I kinda liked pcase at first, but the more I see of the pcase language, Good one. That's really it. When you have a very general construct it can begin to be its own _language_. This is the case for UNIX `find', for instance, and for Common Lisp `loop'. That's not to say that using such a language can't be useful. It's only to say that I use it when it is most useful. If I don't need it then I tend not to use it. > the more sceptical I get. I'm beginning to wonder whether the whole > thing is a misfeature that should be replaced with several separate > operators. That's an interesting question. Maybe you have something in mind? Could be an interesting thread, even if it ultimately went nowhere. Certainly, something like `pcase' provides a good deal of food for thought, which can also mean room for improvement. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: The poor state of documentation of pcase like things. 2016-01-03 2:48 ` Drew Adams @ 2016-01-03 3:11 ` Noam Postavsky 2016-01-03 3:18 ` Dmitry Gutov 2016-01-03 3:45 ` Drew Adams 0 siblings, 2 replies; 375+ messages in thread From: Noam Postavsky @ 2016-01-03 3:11 UTC (permalink / raw) To: Drew Adams Cc: dak, michael_heerdegen, emacs-devel, Dmitry Gutov, Lars Magne Ingebrigtsen, Daniel Colascione, Eli Zaretskii On Sat, Jan 2, 2016 at 9:48 PM, Drew Adams <drew.adams@oracle.com> wrote: >> Well, I'd say that pcase is kinda awkward because you can't tell by >> skimming whether it's complex or not > > 100% agreement. That's really the point, for me. > > * `pcase' shouts: "This might be complicated. Better look closely." > > * `cond' and `cl-case' and `if' ... shout: "Nothing fancy here. > We're only testing literals" I don't see how `cond' and `if' shout that at all, they can test anything, no restrictions. I would prefer `pcase` over `cond` (if there were some reason to exclude `cl-case') because the code is shorter and simpler so I can skim it faster than the equivalent `cond'. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: The poor state of documentation of pcase like things. 2016-01-03 3:11 ` Noam Postavsky @ 2016-01-03 3:18 ` Dmitry Gutov 2016-01-03 3:55 ` John Wiegley 2016-01-03 3:45 ` Drew Adams 1 sibling, 1 reply; 375+ messages in thread From: Dmitry Gutov @ 2016-01-03 3:18 UTC (permalink / raw) To: Noam Postavsky, Drew Adams Cc: dak, michael_heerdegen, emacs-devel, Lars Magne Ingebrigtsen, Daniel Colascione, Eli Zaretskii On 01/03/2016 05:11 AM, Noam Postavsky wrote: > (if > there were some reason to exclude `cl-case') It's a minor thing, but `pcase' is actually faster at macro-expansion, in addition to being more powerful. Try: (benchmark 10000 '(cl-case 1 (2 3) (4 5) (1 6))) (benchmark 10000 '(pcase 1 (2 3) (4 5) (1 6))) ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: The poor state of documentation of pcase like things. 2016-01-03 3:18 ` Dmitry Gutov @ 2016-01-03 3:55 ` John Wiegley 0 siblings, 0 replies; 375+ messages in thread From: John Wiegley @ 2016-01-03 3:55 UTC (permalink / raw) To: emacs-devel [-- Attachment #1: Type: text/plain, Size: 561 bytes --] We're now entering emacs-tangents territory here. We should discuss the merits of various programming constructions over on that list, since it is has no objective answer here. We are all volunteers. Use whichever construction suits you best for the code you write or maintain. Do not mechanically translate what others have written to your preferred style unless there is a genuine need to do so. -- John Wiegley GPG fingerprint = 4710 CF98 AF9B 327B B80F http://newartisans.com 60E1 46C4 BD1A 7AC1 4BA2 [-- Attachment #2: signature.asc --] [-- Type: application/pgp-signature, Size: 629 bytes --] ^ permalink raw reply [flat|nested] 375+ messages in thread
* RE: The poor state of documentation of pcase like things. 2016-01-03 3:11 ` Noam Postavsky 2016-01-03 3:18 ` Dmitry Gutov @ 2016-01-03 3:45 ` Drew Adams 1 sibling, 0 replies; 375+ messages in thread From: Drew Adams @ 2016-01-03 3:45 UTC (permalink / raw) To: Noam Postavsky Cc: dak, michael_heerdegen, emacs-devel, Dmitry Gutov, Lars Magne Ingebrigtsen, Daniel Colascione, Eli Zaretskii > >> Well, I'd say that pcase is kinda awkward because you can't tell by > >> skimming whether it's complex or not > > > > 100% agreement. That's really the point, for me. > > > > * `pcase' shouts: "This might be complicated. Better look closely." > > > > * `cond' and `cl-case' and `if' ... shout: "Nothing fancy here. > > We're only testing literals" > > I don't see how `cond' and `if' shout that at all, they can test > anything, no restrictions. I would prefer `pcase` over `cond` (if > there were some reason to exclude `cl-case') because the code is > shorter and simpler so I can skim it faster than the equivalent > `cond'. I tried to consistently contrast what they do with the "_decomposition pattern-matching_" that `pcase' can do (in addition to only matching literal "patterns" - `eql'). Sorry if that wasn't clear. Of course the ordinary control structures can perform any kind of test. That's not in question. But when it comes to _pattern matching_ (e.g., for `cl-case'), only literal matches are done. `pcase' is unique among control structures in being able to decompose what a pattern matches, i.e., to bind local variables. This is really what it has to offer (IMHO). The rest is nothing new. And I would (personally) typically use it only when it was doing that. You could get `pcase' behavior with just a decomposing let combined with the classic control structures. You might even argue that that might be clearer. (I used to use a Lisp, many moon ago, that had such a let, but I've forgotten what it was. Maybe it was something I wrote, instead of being part of the language - I don't recall.) ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: The poor state of documentation of pcase like things. 2016-01-03 0:41 ` Dmitry Gutov 2016-01-03 1:07 ` Lars Magne Ingebrigtsen @ 2016-01-03 3:47 ` Eli Zaretskii [not found] ` <56889EC3.3040108@yandex.ru> 1 sibling, 1 reply; 375+ messages in thread From: Eli Zaretskii @ 2016-01-03 3:47 UTC (permalink / raw) To: Dmitry Gutov; +Cc: michael_heerdegen, dancol, dak, emacs-devel > Cc: michael_heerdegen@web.de, dak@gnu.org, emacs-devel@gnu.org > From: Dmitry Gutov <dgutov@yandex.ru> > Date: Sun, 3 Jan 2016 02:41:22 +0200 > > On 01/02/2016 10:16 AM, Eli Zaretskii wrote: > > > Now that I know there isn't, I can convert such code to using 'cond' > > whenever I feel like it. Like we do with whitespace changes. > > FWIW, converting that kind of pcase form to a cond, to my eyes, would > look like replacing (when ...) with (if ... (progn ...))). The syntax of 'when' is nowhere as complex as that of 'pcase'. ^ permalink raw reply [flat|nested] 375+ messages in thread
[parent not found: <56889EC3.3040108@yandex.ru>]
[parent not found: <877fjrkpdf.fsf@fencepost.gnu.org>]
[parent not found: <56892334.4000106@yandex.ru>]
[parent not found: <8760zakb7q.fsf@fencepost.gnu.org>]
[parent not found: <56892BDA.6060103@dancol.org>]
[parent not found: <871t9yk98g.fsf@fencepost.gnu.org>]
[parent not found: <568936F0.3060505@yandex.ru>]
[parent not found: <87wprqitj5.fsf@fencepost.gnu.org>]
[parent not found: <56893C8C.3060200@yandex.ru>]
* Re: The poor state of documentation of pcase like things. [not found] ` <56893C8C.3060200@yandex.ru> @ 2016-01-03 15:52 ` David Kastrup 2016-01-03 15:59 ` Dmitry Gutov 2016-01-04 2:54 ` The poor state of documentation of pcase like things Michael Heerdegen 0 siblings, 2 replies; 375+ messages in thread From: David Kastrup @ 2016-01-03 15:52 UTC (permalink / raw) To: Dmitry Gutov Cc: michael_heerdegen, Eli Zaretskii, Daniel Colascione, emacs-devel Dmitry Gutov <dgutov@yandex.ru> writes: > On 01/03/2016 05:15 PM, David Kastrup wrote: > >> So why would people write >> >> (pcase exp >> (`nil nil) ... > > Easier to just use the same kind of quote everywhere? More like "easier" to just use the _only_ documented kind of quote for pcase everywhere. We don't use quasiquote all over the rest of Emacs just because it is "easier to just use the same kind of quote everywhere". >> ? What's with the overuse of quasiquote? > > You should ask those people. I suspect it would be the poor state of documentation of pcase like things. At any rate, while we are still figuring out how to use and not use pcase in the Emacs code base, I don't see the point in diverting the discussion to emacs-tangents silently. However, it would seem to indicate that the proponents of pcase do not want to see their actions discussed, so I'm not going to respond to this thread anymore either way. It would appear that we are on course replacing consensual agreed-upon action with battling commits and stifling speech. -- David Kastrup ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: The poor state of documentation of pcase like things. 2016-01-03 15:52 ` David Kastrup @ 2016-01-03 15:59 ` Dmitry Gutov 2016-01-03 17:15 ` David Kastrup 2016-01-04 2:54 ` The poor state of documentation of pcase like things Michael Heerdegen 1 sibling, 1 reply; 375+ messages in thread From: Dmitry Gutov @ 2016-01-03 15:59 UTC (permalink / raw) To: David Kastrup Cc: michael_heerdegen, Eli Zaretskii, Daniel Colascione, emacs-devel On 01/03/2016 05:52 PM, David Kastrup wrote: > More like "easier" to just use the _only_ documented kind of quote for > pcase everywhere. From pcase docstring: 'VAL matches if the object is ‘equal’ to VAL ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: The poor state of documentation of pcase like things. 2016-01-03 15:59 ` Dmitry Gutov @ 2016-01-03 17:15 ` David Kastrup 2016-01-03 17:52 ` Dmitry Gutov 0 siblings, 1 reply; 375+ messages in thread From: David Kastrup @ 2016-01-03 17:15 UTC (permalink / raw) To: Dmitry Gutov Cc: michael_heerdegen, Eli Zaretskii, Daniel Colascione, emacs-devel Dmitry Gutov <dgutov@yandex.ru> writes: > On 01/03/2016 05:52 PM, David Kastrup wrote: > >> More like "easier" to just use the _only_ documented kind of quote for >> pcase everywhere. > > From pcase docstring: > > 'VAL matches if the object is ‘equal’ to VAL Congratulations. From <URL:https://www.gnu.org/software/emacs/manual/html_node/elisp/Pattern-matching-case-statement.html#index-pcase> To compare a particular value against various possible cases, the macro pcase can come handy. It takes the following form: (pcase exp branch1 branch2 branch3 …) where each branch takes the form (upattern body-forms…). It will first evaluate exp and then compare the value against each upattern to see which branch to use, after which it will run the corresponding body-forms. A common use case is to distinguish between a few different constant values: (pcase (get-return-code x) (`success (message "Done!")) (`would-block (message "Sorry, can't do it now")) (`read-only (message "The shmliblick is read-only")) (`access-denied (message "You do not have the needed rights")) (code (message "Unknown return code %S" code))) In the last clause, code is a variable that gets bound to the value that was returned by (get-return-code x). And so forth and so on. The whole documentation idea of "qpattern" and "upattern" does not even _allow_ discussing different ways of quoting (since of course '-quoted entries are different from "qpatterns" as they don't interpret unquote and unquote-splicing, namely , and ,@) so the Elisp manual entry, arguably the decisive reference for use of pcase, actively avoids mentioning ' at all in order not to have to upset its terminology. This is not helpful, as witnessed by the actual code extracts seen in the Emacs code base and mailing list. -- David Kastrup ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: The poor state of documentation of pcase like things. 2016-01-03 17:15 ` David Kastrup @ 2016-01-03 17:52 ` Dmitry Gutov 2016-01-03 18:17 ` David Kastrup 0 siblings, 1 reply; 375+ messages in thread From: Dmitry Gutov @ 2016-01-03 17:52 UTC (permalink / raw) To: David Kastrup Cc: michael_heerdegen, Eli Zaretskii, Daniel Colascione, emacs-devel On 01/03/2016 07:15 PM, David Kastrup wrote: > This is not helpful, as witnessed by the actual code extracts seen in > the Emacs code base and mailing list. Why don't you suggest an improvement (with a patch)? ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: The poor state of documentation of pcase like things. 2016-01-03 17:52 ` Dmitry Gutov @ 2016-01-03 18:17 ` David Kastrup 2016-01-04 2:34 ` Michael Heerdegen 0 siblings, 1 reply; 375+ messages in thread From: David Kastrup @ 2016-01-03 18:17 UTC (permalink / raw) To: Dmitry Gutov Cc: michael_heerdegen, Eli Zaretskii, Daniel Colascione, emacs-devel Dmitry Gutov <dgutov@yandex.ru> writes: > On 01/03/2016 07:15 PM, David Kastrup wrote: > >> This is not helpful, as witnessed by the actual code extracts seen in >> the Emacs code base and mailing list. > > Why don't you suggest an improvement (with a patch)? Because I am not the one interested in promoting pcase? Frankly, I don't even have enough time to get the stuff I am interested in done. -- David Kastrup ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: The poor state of documentation of pcase like things. 2016-01-03 18:17 ` David Kastrup @ 2016-01-04 2:34 ` Michael Heerdegen 2016-01-04 6:19 ` Drew Adams ` (2 more replies) 0 siblings, 3 replies; 375+ messages in thread From: Michael Heerdegen @ 2016-01-04 2:34 UTC (permalink / raw) To: emacs-devel David Kastrup <dak@gnu.org> writes: > >> Elisp manual entry, arguably the decisive reference for use of pcase, > >> actively avoids mentioning ' at all in order not to have to upset its > >> terminology. The reason is that the manual had not been updated after 'VAL had been introduced. It dates from a time where ` was indeed the only way of quoting. > >> This is not helpful, as witnessed by the actual code extracts seen in > >> the Emacs code base and mailing list. > > > > Why don't you suggest an improvement (with a patch)? > > Because I am not the one interested in promoting pcase? Frankly, I > don't even have enough time to get the stuff I am interested in done. I'll try to take care of that stuff. After all, despite of the tone on both sides, I think we came to some conclusions: - The pcase docs must be updated, esp. wrt quoting/ backquote, and missing stuff (e.g. first matching branches' body is executed, remaining branches are ignored). - We should not use it in cases where a different thing (esp. cl-case) exactly fits. "Promoters" should use it sparse in contributions and only in cases where it improves readability or makes the case distinction clearer (given the reader read the documentation). Others should accept that some people find it handy and will use it in such cases in their contributions. - Occurrences in the sources must be revised. The only substantial difference, I think, was whether the design and concept of pcase is useful. I think it's ok when people have different preferences here (like with `loop', which I personally avoid btw). Thanks everyone, Michael. ^ permalink raw reply [flat|nested] 375+ messages in thread
* RE: The poor state of documentation of pcase like things. 2016-01-04 2:34 ` Michael Heerdegen @ 2016-01-04 6:19 ` Drew Adams 2016-01-04 22:07 ` John Wiegley 2016-01-04 15:52 ` Eli Zaretskii 2018-10-23 13:04 ` Replace trivial pcase occurrences in the Emacs sources (was: The poor state of documentation of pcase like things.) Michael Heerdegen 2 siblings, 1 reply; 375+ messages in thread From: Drew Adams @ 2016-01-04 6:19 UTC (permalink / raw) To: Michael Heerdegen, emacs-devel > I'll try to take care of that stuff. > > After all, despite of the tone on both sides, I think we came to > some conclusions: > > - The pcase docs must be updated, esp. wrt quoting/ backquote, and > missing stuff (e.g. first matching branches' body is executed, > remaining branches are ignored). > > - We should not use it in cases where a different thing (esp. cl-case) > exactly fits. "Promoters" should use it sparse in contributions and > only in cases where it improves readability or makes the case > distinction clearer (given the reader read the documentation). Others > should accept that some people find it handy and will use it in such > cases in their contributions. > > - Occurrences in the sources must be revised. > > The only substantial difference, I think, was whether the design and > concept of pcase is useful. I think it's ok when people have different > preferences here (like with `loop', which I personally avoid btw). > > Thanks everyone, Michael. A very constructive contribution to the discussion, IMO. Thanks for taking a stab at the doc improvement. That will be a great help, including in terms of guiding our use of `pcase'. And thanks for the consensus summary - sounds good to me. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: The poor state of documentation of pcase like things. 2016-01-04 6:19 ` Drew Adams @ 2016-01-04 22:07 ` John Wiegley 0 siblings, 0 replies; 375+ messages in thread From: John Wiegley @ 2016-01-04 22:07 UTC (permalink / raw) To: Drew Adams; +Cc: Michael Heerdegen, emacs-devel >>>>> Drew Adams <drew.adams@oracle.com> writes: >> After all, despite of the tone on both sides, I think we came to >> some conclusions: >> >> - The pcase docs must be updated, esp. wrt quoting/ backquote, and >> missing stuff (e.g. first matching branches' body is executed, >> remaining branches are ignored). >> >> - We should not use it in cases where a different thing (esp. cl-case) >> exactly fits. "Promoters" should use it sparse in contributions and >> only in cases where it improves readability or makes the case >> distinction clearer (given the reader read the documentation). Others >> should accept that some people find it handy and will use it in such >> cases in their contributions. >> >> - Occurrences in the sources must be revised. >> >> The only substantial difference, I think, was whether the design and >> concept of pcase is useful. I think it's ok when people have different >> preferences here (like with `loop', which I personally avoid btw). >> >> Thanks everyone, Michael. > A very constructive contribution to the discussion, IMO. > Thanks for taking a stab at the doc improvement. That will be > a great help, including in terms of guiding our use of `pcase'. > And thanks for the consensus summary - sounds good to me. Excellent summary and resolution, I agree. We can continue debate on emacs-tangents, but this is resolved now from emacs-devel's point of view. Michael and I will produce new documentation shortly. -- John Wiegley GPG fingerprint = 4710 CF98 AF9B 327B B80F http://newartisans.com 60E1 46C4 BD1A 7AC1 4BA2 ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: The poor state of documentation of pcase like things. 2016-01-04 2:34 ` Michael Heerdegen 2016-01-04 6:19 ` Drew Adams @ 2016-01-04 15:52 ` Eli Zaretskii 2018-10-23 13:04 ` Replace trivial pcase occurrences in the Emacs sources (was: The poor state of documentation of pcase like things.) Michael Heerdegen 2 siblings, 0 replies; 375+ messages in thread From: Eli Zaretskii @ 2016-01-04 15:52 UTC (permalink / raw) To: Michael Heerdegen; +Cc: emacs-devel > From: Michael Heerdegen <michael_heerdegen@web.de> > Date: Mon, 04 Jan 2016 03:34:39 +0100 > > After all, despite of the tone on both sides, I think we came to > some conclusions: > > - The pcase docs must be updated, esp. wrt quoting/ backquote, and > missing stuff (e.g. first matching branches' body is executed, > remaining branches are ignored). > > - We should not use it in cases where a different thing (esp. cl-case) > exactly fits. "Promoters" should use it sparse in contributions and > only in cases where it improves readability or makes the case > distinction clearer (given the reader read the documentation). Others > should accept that some people find it handy and will use it in such > cases in their contributions. > > - Occurrences in the sources must be revised. 100% agreement. Hope to see the documentation patches some time soon. Thanks. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Replace trivial pcase occurrences in the Emacs sources (was: The poor state of documentation of pcase like things.) 2016-01-04 2:34 ` Michael Heerdegen 2016-01-04 6:19 ` Drew Adams 2016-01-04 15:52 ` Eli Zaretskii @ 2018-10-23 13:04 ` Michael Heerdegen 2018-10-23 14:43 ` Clément Pit-Claudel ` (2 more replies) 2 siblings, 3 replies; 375+ messages in thread From: Michael Heerdegen @ 2018-10-23 13:04 UTC (permalink / raw) To: emacs-devel; +Cc: Eli Zaretskii, Stefan Monnier Hello, > [pcase] - Occurrences in the sources must be revised. Some time (two years) ago I volunteered to replace lots of the `pcase' occurrences in the Emacs sources (back) to cl-case where possible. Lots of people wanted this because they found understanding pcase expressions hard. I would like to do that now. Stefan, can you live with that (AFAIR you didn't participate in the discussion at that time)? Or has the mood of people changed in the meantime due to the improved documentation of `pcase'? In a second step, I also would want to replace the unnecessarily backquoted patterns to use quotes, i.e. `DOESNT-UNQUOTE -> 'DOESNT-UNQUOTE (the `ATOM patterns go back to a time where the quoted syntax wasn't yet implemented). A question: when I compose the commit message, I can write something like "Change all affected callers in all files" instead of listing all individual changed functions separately, right? Thanks, Michael. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources (was: The poor state of documentation of pcase like things.) 2018-10-23 13:04 ` Replace trivial pcase occurrences in the Emacs sources (was: The poor state of documentation of pcase like things.) Michael Heerdegen @ 2018-10-23 14:43 ` Clément Pit-Claudel 2018-10-23 14:46 ` Replace trivial pcase occurrences in the Emacs sources Michael Heerdegen 2018-10-23 15:17 ` Replace trivial pcase occurrences in the Emacs sources (was: The poor state of documentation of pcase like things.) Eli Zaretskii 2018-10-23 17:16 ` Stefan Monnier 2 siblings, 1 reply; 375+ messages in thread From: Clément Pit-Claudel @ 2018-10-23 14:43 UTC (permalink / raw) To: emacs-devel On 23/10/2018 09.04, Michael Heerdegen wrote: > In a second step, I also would want to replace the unnecessarily > backquoted patterns to use quotes IIRC, one issue with that is that the quoted form doesn't work in some old-but-still-popular Emacsen. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-23 14:43 ` Clément Pit-Claudel @ 2018-10-23 14:46 ` Michael Heerdegen 2018-10-23 14:57 ` Clément Pit-Claudel 2018-10-23 15:07 ` Noam Postavsky 0 siblings, 2 replies; 375+ messages in thread From: Michael Heerdegen @ 2018-10-23 14:46 UTC (permalink / raw) To: Clément Pit-Claudel; +Cc: emacs-devel Clément Pit-Claudel <cpitclaudel@gmail.com> writes: > On 23/10/2018 09.04, Michael Heerdegen wrote: > > In a second step, I also would want to replace the unnecessarily > > backquoted patterns to use quotes > > IIRC, one issue with that is that the quoted form doesn't work in some > old-but-still-popular Emacsen. I'm not sure I understand. I plan to do that only in the Emacs sources (in master). How can that be problematic for older Emacsen? Michael. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-23 14:46 ` Replace trivial pcase occurrences in the Emacs sources Michael Heerdegen @ 2018-10-23 14:57 ` Clément Pit-Claudel 2018-10-23 15:16 ` Michael Heerdegen 2018-10-23 15:07 ` Noam Postavsky 1 sibling, 1 reply; 375+ messages in thread From: Clément Pit-Claudel @ 2018-10-23 14:57 UTC (permalink / raw) To: Michael Heerdegen; +Cc: emacs-devel On 23/10/2018 10.46, Michael Heerdegen wrote: > Clément Pit-Claudel <cpitclaudel@gmail.com> writes: > >> On 23/10/2018 09.04, Michael Heerdegen wrote: >>> In a second step, I also would want to replace the unnecessarily >>> backquoted patterns to use quotes >> >> IIRC, one issue with that is that the quoted form doesn't work in some >> old-but-still-popular Emacsen. > > I'm not sure I understand. I plan to do that only in the Emacs sources > (in master). How can that be problematic for older Emacsen? The first pcase I wrote was adapted from an example in the sources that used quotes; that code broke when a user tried it on an older Emacsen. It's not a huge issue, of course. Clément. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-23 14:57 ` Clément Pit-Claudel @ 2018-10-23 15:16 ` Michael Heerdegen 0 siblings, 0 replies; 375+ messages in thread From: Michael Heerdegen @ 2018-10-23 15:16 UTC (permalink / raw) To: Clément Pit-Claudel; +Cc: emacs-devel Clément Pit-Claudel <cpitclaudel@gmail.com> writes: > The first pcase I wrote was adapted from an example in the sources > that used quotes; that code broke when a user tried it on an older > Emacsen. > It's not a huge issue, of course. I see. But measured from now, if the Emacs is only a bit older than that one, there is no pcase at all. And the semantics of pcase also saw some more additions in the meantime. So I tend to do what I suggested. BTW, why I do want to do these replacements is because I think `ATOM looks frightening to people: they think "what the hell does this mean" though it's actually something simple. Or, with other words, I think replacing `ATOM with 'ATOM would improve readability. Michael. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-23 14:46 ` Replace trivial pcase occurrences in the Emacs sources Michael Heerdegen 2018-10-23 14:57 ` Clément Pit-Claudel @ 2018-10-23 15:07 ` Noam Postavsky 2018-10-23 15:24 ` Michael Heerdegen 1 sibling, 1 reply; 375+ messages in thread From: Noam Postavsky @ 2018-10-23 15:07 UTC (permalink / raw) To: Michael Heerdegen; +Cc: Clément Pit-Claudel, Emacs developers On Tue, 23 Oct 2018 at 10:47, Michael Heerdegen <michael_heerdegen@web.de> wrote: > > Clément Pit-Claudel <cpitclaudel@gmail.com> writes: > > > On 23/10/2018 09.04, Michael Heerdegen wrote: > > > In a second step, I also would want to replace the unnecessarily > > > backquoted patterns to use quotes > > > > IIRC, one issue with that is that the quoted form doesn't work in some > > old-but-still-popular Emacsen. > > I'm not sure I understand. I plan to do that only in the Emacs sources > (in master). How can that be problematic for older Emacsen? There are some files in Emacs master branch that are also distributed in GNU ELPA for older Emacs, e.g., python.el (I don't know if it has any pcase instances that you might want to replace, it's just the first example that came to mind). Another thing to watch out for is that pcase is available earlier than cl-case in the bootstrap sequence. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-23 15:07 ` Noam Postavsky @ 2018-10-23 15:24 ` Michael Heerdegen 2018-10-23 15:31 ` Noam Postavsky 0 siblings, 1 reply; 375+ messages in thread From: Michael Heerdegen @ 2018-10-23 15:24 UTC (permalink / raw) To: Noam Postavsky; +Cc: Clément Pit-Claudel, Emacs developers Noam Postavsky <npostavs@gmail.com> writes: > There are some files in Emacs master branch that are also distributed > in GNU ELPA for older Emacs, e.g., python.el (I don't know if it has > any pcase instances that you might want to replace, it's just the > first example that came to mind). Ok, I guess I can just leave out these for now. > Another thing to watch out for is that pcase is available earlier than > cl-case in the bootstrap sequence. What does that mean in concrete - should I leave out even more files - which are these? I don't think that replacing such pcase expressions with something different instead - e.g. an equivalent `cond' - would be a real improvement. Michael. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-23 15:24 ` Michael Heerdegen @ 2018-10-23 15:31 ` Noam Postavsky 2018-10-24 13:15 ` Michael Heerdegen 0 siblings, 1 reply; 375+ messages in thread From: Noam Postavsky @ 2018-10-23 15:31 UTC (permalink / raw) To: Michael Heerdegen; +Cc: Clément Pit-Claudel, Emacs developers On Tue, 23 Oct 2018 at 11:24, Michael Heerdegen <michael_heerdegen@web.de> wrote: > > Another thing to watch out for is that pcase is available earlier than > > cl-case in the bootstrap sequence. > > What does that mean in concrete - should I leave out even more files - > which are these? I'm not sure exactly files this would be, possibly the ones listed in lisp/loadup.el, but anyway, testing that 'make bootstrap' succeeds would be a good idea. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-23 15:31 ` Noam Postavsky @ 2018-10-24 13:15 ` Michael Heerdegen 0 siblings, 0 replies; 375+ messages in thread From: Michael Heerdegen @ 2018-10-24 13:15 UTC (permalink / raw) To: Noam Postavsky; +Cc: Emacs developers Noam Postavsky <npostavs@gmail.com> writes: > I'm not sure exactly files this would be, possibly the ones listed in > lisp/loadup.el, but anyway, testing that 'make bootstrap' succeeds > would be a good idea. Sure, I'll do that. BTW, what about org files? I heard they use a separate repository for development. Should I also skip all org files? Michael. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources (was: The poor state of documentation of pcase like things.) 2018-10-23 13:04 ` Replace trivial pcase occurrences in the Emacs sources (was: The poor state of documentation of pcase like things.) Michael Heerdegen 2018-10-23 14:43 ` Clément Pit-Claudel @ 2018-10-23 15:17 ` Eli Zaretskii 2018-10-23 17:14 ` Replace trivial pcase occurrences in the Emacs sources Stefan Monnier 2018-10-23 17:22 ` John Wiegley 2018-10-23 17:16 ` Stefan Monnier 2 siblings, 2 replies; 375+ messages in thread From: Eli Zaretskii @ 2018-10-23 15:17 UTC (permalink / raw) To: Michael Heerdegen; +Cc: monnier, emacs-devel > From: Michael Heerdegen <michael_heerdegen@web.de> > Cc: Stefan Monnier <monnier@iro.umontreal.ca>, > Eli Zaretskii <eliz@gnu.org> > Date: Tue, 23 Oct 2018 15:04:45 +0200 > > Some time (two years) ago I volunteered to replace lots of the `pcase' > occurrences in the Emacs sources (back) to cl-case where possible. Lots > of people wanted this because they found understanding pcase expressions > hard. > > I would like to do that now. Thank you. If you find places where pcase is used, but a simple cond will do (without obfuscating the code, of course), please use cond where appropriate. > Or has the mood of people changed in the meantime due to the improved > documentation of `pcase'? Mine didn't (and I do appreciate the improvement in the docs). > A question: when I compose the commit message, I can write something > like "Change all affected callers in all files" instead of listing all > individual changed functions separately, right? "All callers changed" is the usual wording. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-23 15:17 ` Replace trivial pcase occurrences in the Emacs sources (was: The poor state of documentation of pcase like things.) Eli Zaretskii @ 2018-10-23 17:14 ` Stefan Monnier 2018-10-23 17:24 ` Michael Heerdegen 2018-10-24 4:51 ` Richard Stallman 2018-10-23 17:22 ` John Wiegley 1 sibling, 2 replies; 375+ messages in thread From: Stefan Monnier @ 2018-10-23 17:14 UTC (permalink / raw) To: Eli Zaretskii; +Cc: Michael Heerdegen, emacs-devel >> Some time (two years) ago I volunteered to replace lots of the `pcase' >> occurrences in the Emacs sources (back) to cl-case where possible. You're suggesting changing (pcase X ('a (fooa)) ('b (foob)) ...) with (cl-case X (a (fooa)) (b (foob)) ...) ? >> Lots of people wanted this because they found understanding pcase >> expressions hard. In what sense is the above cl-case more clear than the pcase equivalent? I'm not saying the pcase version is better in those cases, but I think the respective advantages and disadvantages pretty much balance out. Stefan PS: In case anyone still doubts it, I'm opposed to replacing `pcase` uses with `cl-case` uses. I think it'd be at best a waste of time. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-23 17:14 ` Replace trivial pcase occurrences in the Emacs sources Stefan Monnier @ 2018-10-23 17:24 ` Michael Heerdegen 2018-10-23 18:12 ` Stefan Monnier 2018-10-24 4:51 ` Richard Stallman 1 sibling, 1 reply; 375+ messages in thread From: Michael Heerdegen @ 2018-10-23 17:24 UTC (permalink / raw) To: Stefan Monnier; +Cc: Eli Zaretskii, emacs-devel Stefan Monnier <monnier@IRO.UMontreal.CA> writes: > You're suggesting changing > > (pcase X > ('a (fooa)) > ('b (foob)) > ...) > > with > > (cl-case X > (a (fooa)) > (b (foob)) > ...) > > ? Yes. > >> Lots of people wanted this because they found understanding pcase > >> expressions hard. > > In what sense is the above cl-case more clear than the pcase equivalent? > I'm not saying the pcase version is better in those cases, but I think > the respective advantages and disadvantages pretty much balance out. > PS: In case anyone still doubts it, I'm opposed to replacing `pcase` uses > with `cl-case` uses. I think it'd be at best a waste of time. I think so too, but it seems the majority of developers has a different option, at least in this (old) thread. Michael. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-23 17:24 ` Michael Heerdegen @ 2018-10-23 18:12 ` Stefan Monnier 2018-10-23 19:52 ` pcase vs. case (where it could also be used) [Was: Re: Replace trivial pcase occurrences in the Emacs sources] Garreau, Alexandre 2018-10-24 15:03 ` Replace trivial pcase occurrences in the Emacs sources Eli Zaretskii 0 siblings, 2 replies; 375+ messages in thread From: Stefan Monnier @ 2018-10-23 18:12 UTC (permalink / raw) To: emacs-devel > I think so too, but it seems the majority of developers has a different > option, at least in this (old) thread. So I guess I'm gonna have to try and argue my case. OK, here are the advantages I see for `cl-case`: - simpler doc because its functionality is much more limited. - easier for people who already know Common-Lisp (or those who learned `case` from the cl.el package). - more concise syntax for branches that match multiple constants. Here are the problems I see with cl-case (regardless of pcase): - some users naturally write (case X ('a fooa) ...) without realizing that it also matches thew `quote` value. - tricky corner cases when trying to match the `t` or `nil` values (or `otherwise` as well, tho this one is much more rarely needed). - in (case X (a fooa)), the syntax looks a bit like a call to the function `a`: emacs-lisp-mode gets confused in terms of highlighting and completion, last I checked. - only works with numbers and symbols: can't use it to match against strings. In the specific case of using `pcase` where `cl-case` could also be used, the downsides I know of `pcase` are the following: - because it can also do a lot more, its doc is much more complex. - you have to use the more verbose ((or 'a 'b 'c) ...) syntax when matching several alternative values. - if you forget to quote your constant symbols the code behaves differently (and arguably surprisingly for some user) rather than giving you an error, tho in many cases the macro will detect a problem and give you a warning about a subsequent redundant branch (but the unsuspecting user will likely find it puzzling and it will take a while for him to figure out what's going on). The advantages are: - it fixes all four problems I described about `cl-case`. - it can accommodate many more cases, so it offers a smoother evolution. IOW, you will rarely find yourself having to stop using `pcase` and to rewrite the code to use `cond` instead just because you need to add a case that's a bit different from the others. - once you learn it, you can use it elsewhere, e.g. pcase-let, pcase-dolist, ... - Elisp+pcase is simpler than Elisp+clcase+pcase, so if we aim for overall simplicity we'd be better off without cl-case (to the extend that `cl-case` is too limited and hence we'll still want to use `pcase`). Stefan ^ permalink raw reply [flat|nested] 375+ messages in thread
* pcase vs. case (where it could also be used) [Was: Re: Replace trivial pcase occurrences in the Emacs sources] 2018-10-23 18:12 ` Stefan Monnier @ 2018-10-23 19:52 ` Garreau, Alexandre 2018-10-23 20:19 ` Stefan Monnier 2018-10-24 15:03 ` Replace trivial pcase occurrences in the Emacs sources Eli Zaretskii 1 sibling, 1 reply; 375+ messages in thread From: Garreau, Alexandre @ 2018-10-23 19:52 UTC (permalink / raw) To: Stefan Monnier; +Cc: emacs-devel On 2018-10-23 at 14:12, Stefan Monnier wrote: > In the specific case of using `pcase` where `cl-case` could also be > used, the downsides I know of `pcase` are the following: > - if you forget to quote your constant symbols the code behaves > differently (and arguably surprisingly for some user) rather than > giving you an error, tho in many cases the macro will detect a problem > and give you a warning about a subsequent redundant branch (but the > unsuspecting user will likely find it puzzling and it will take > a while for him to figure out what's going on). Aren’t non-quoted for bind? what should give an error or a warning? I didn’t understood? Also, in either pcase or case: can’t they eval a symbol as a variable value to be used in tests? > [but] because it can also do a lot more, its doc is much more complex. > The advantages are: > - it can accommodate many more cases, so it offers a smoother evolution. > IOW, you will rarely find yourself having to stop using `pcase` and > to rewrite the code to use `cond` instead just because you need to > add a case that's a bit different from the others. To push the reasoning on an extreme: would that be a reason for abandoning cond, lambda, etc. in favor of pcase? ML do that, and I find it sad and less minimal and lightweight. > - once you learn it, you can use it elsewhere, e.g. pcase-let, > pcase-dolist, ... Could have been the same for cl-destructuring-bind. > - Elisp+pcase is simpler than Elisp+clcase+pcase, so if we aim for > overall simplicity we'd be better off without cl-case (to the extend > that `cl-case` is too limited and hence we'll still want to use > `pcase`). > the advantages I see for `cl-case`: You forgot simplicity and concision of implementation: easier to understand and reimplement, thus more hackable upon and widespread. For instance, I personally have my own case* implementation for using other test-fn than eql (such as equal, the only possible one for pcase, and I don’t even hope making my own version for eq/eql/etc.). Many people will want case anyway, probably much code uses it (including but not limited to fragments of common lisp afaik), so it’ll stay anyway, because it is a trivial and obvious factorization of cond, already existing in most languages, and simpler to make. While pcase is much more questionable, trivial, straightforward and widespread. elisp+clcase is simpler than elisp+pcase, overall. So for any codebase, one only needing case (more likely) will be simpler and have less dependency burden that one needing pcase. Also, from a more reductionist point of view: pcase can be implemented more simply and readably using case, typecase, etc. so that’s yet another argument for case to stay used and widespread. > - easier for people who already know Common-Lisp (or those who learned > `case` from the cl.el package). Also it is basically the equivalent of “switch/case/etc.” many will search for, coming from another language such as C: and not everybody is fond of destructuring and pattern matching > Here are the problems I see with cl-case (regardless of pcase): > - only works with numbers and symbols: can't use it to match against > strings. Can be fixed, and without breaking backward-compatibility. > - in (case X (a fooa)), the syntax looks a bit like a call to the > function `a`: emacs-lisp-mode gets confused in terms of highlighting > and completion, last I checked. case is a macro: why making assumption on calls in macros arguments? from time case known as a macro (I’ve a hard time imagining what a “case” *function* would be anyway)… Also, with an unquoted symbol (so to bind the default case), you have this very same problem with pcase: (pcase X (a (fooa))) (and emacs syntax highlighting is confused here too: (pcase X (cond (fooa))), (pcase X (function (fooa))). So emacs-lisp-mode would better be fixed at some point rather than macros arbitrarily disapproved. Then: > - [pcase] fixes all four problems I described about `cl-case`. hence not even. > - tricky corner cases when trying to match the `t` or `nil` values (or > `otherwise` as well, tho this one is much more rarely needed). I find these interface details sadening, it would have been more useful the other way. Btw as said before, matching the default case can be considered confusing as well with pcase. > - some users naturally write (case X ('a fooa) ...) without realizing > that it also matches thew `quote` value. I find sad cl case doesn’t eval its arguments :/ The two last issue would be lessened it it was this way btw. But doing otherwise would be incompatible with cl, with which I find neat emacs lisp is partially compatible with, and it would break backward-compatibility, and much code (as much as it would to remove it at all). ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: pcase vs. case (where it could also be used) [Was: Re: Replace trivial pcase occurrences in the Emacs sources] 2018-10-23 19:52 ` pcase vs. case (where it could also be used) [Was: Re: Replace trivial pcase occurrences in the Emacs sources] Garreau, Alexandre @ 2018-10-23 20:19 ` Stefan Monnier 2018-10-23 22:24 ` Garreau, Alexandre 0 siblings, 1 reply; 375+ messages in thread From: Stefan Monnier @ 2018-10-23 20:19 UTC (permalink / raw) To: emacs-devel >> - if you forget to quote your constant symbols the code behaves >> differently (and arguably surprisingly for some user) rather than >> giving you an error, tho in many cases the macro will detect a problem >> and give you a warning about a subsequent redundant branch (but the >> unsuspecting user will likely find it puzzling and it will take >> a while for him to figure out what's going on). > Aren’t non-quoted for bind? what should give an error or a warning? > I didn’t understood? If the naive user wrote (pcase X (a fooa) (b foob)) when the intended behavior was (pcase X ('a fooa) ('b foob)) pcase will give a warning during macro-expansion that the second branch is redundant (since the first branch matches everything already). So, in a sense the user's error is detected, but the resulting warning is hard to understand if you don't know that the pattern `a` matches everything and binds it to the variable `a`. > Also, in either pcase or case: can’t they eval a symbol as a variable > value to be used in tests? Sorry, I don't understand what you mean: X can be a variable that's evaluated, yes. Or do you mean the case where we want to test equality with Y? `pcase` can do that with (pcase X ((pred (equal Y)) foo-equal-Y) ...) but I think this is irrelevant for the discussion at hand. > To push the reasoning on an extreme: Given Turing-equivalence, I don't think pushing the reasoning to the extreme will be a good guide. >> - once you learn it, you can use it elsewhere, e.g. pcase-let, >> pcase-dolist, ... > Could have been the same for cl-destructuring-bind. Except cl-destructuring-bind only covers (a subset of) pcase-let. It could cover pcase-let as well pcase-dolist, but not `pcase` itself. [ And even then, it would be less flexible than pcase-let because the syntax of cl-destructuring-bind's patterns doesn't leave much space for extensions. ] > You forgot simplicity and concision of implementation: easier to > understand and reimplement, thus more hackable upon and widespread. I don't think it's particularly important, indeed. > For instance, I personally have my own case* implementation for using > other test-fn than eql (such as equal, That highlights the problem that cl-case doesn't work with strings, forcing users like you to write their own alternative. > the only possible one for pcase, and I don’t even hope making my own > version for eq/eql/etc.). Could you show me a pcase pattern where pcase's choice of equality is problematic? [ FWIW, there's only one case to comes to my mind. ] >> - easier for people who already know Common-Lisp (or those who learned >> `case` from the cl.el package). > Also it is basically the equivalent of “switch/case/etc.” many will > search for, coming from another language such as C: and not everybody is > fond of destructuring and pattern matching pcase works just as well to replace "switch/case/etc." You don't have to use pcase's destrucuring, and this discussion is about the subset of case covered by `cl-case`, so destructuring is outside of its scope, AFAIC. >> - in (case X (a fooa)), the syntax looks a bit like a call to the >> function `a`: emacs-lisp-mode gets confused in terms of highlighting >> and completion, last I checked. > case is a macro: why making assumption on calls in macros arguments? > from time case known as a macro (I’ve a hard time imagining what a > “case” *function* would be anyway)… Also, with an unquoted symbol (so > to bind the default case), you have this very same problem with pcase: > (pcase X (a (fooa))) (and emacs syntax highlighting is confused here Not again that the pattern `a` here is outside the scope of this discussion (except to the extent that user can write it by mistake). Stefan ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: pcase vs. case (where it could also be used) [Was: Re: Replace trivial pcase occurrences in the Emacs sources] 2018-10-23 20:19 ` Stefan Monnier @ 2018-10-23 22:24 ` Garreau, Alexandre 0 siblings, 0 replies; 375+ messages in thread From: Garreau, Alexandre @ 2018-10-23 22:24 UTC (permalink / raw) To: Stefan Monnier; +Cc: emacs-devel On 2018-10-23 at 16:19, Stefan Monnier wrote: >> To push the reasoning on an extreme: > > Given Turing-equivalence, I don't think pushing the reasoning to the > extreme will be a good guide. Why? We’re talking about what’s standard or not (so what need to be redefined or not), what is (to be) popularized, common, etc. or not: “if”, simple lambda, etc. exist in ML, but according “good ML style” are (almost) never used, and pattern-matching forms is prefered (even when there’s no destructuring). The question is: do we want the same for emacs-lisp? I’m not personally fond enough of pattern-matching. That recalls me the kind of falsely consensual trends that created Rust. pattern-matching is more intuitive, familiar and straightforward to read to the unused user, but it is more complex (including but not limited to of implementation), and I believe its familiarity is subjective or at least deeply specific to the human cognition, not as systematically particularly interesting on a logical or mathematical level. As forms such as case/switch/etc. are simpler, with some habit you can get quickly get as much used to it as to pattern-matching, just like sexps: more simple, less familiar, but then not long to get used to it. Imho cases where simple `case' become unreadable and pcase becomes necessary are symptoms of trying to implement something too complex at once, that could be either breaked down into simpler and more meaningful parts, or themselves symptoms of a complex spec or interface (where pcase would then become a necessary evil, but it should be there to indicate it as such). But that might exit the subject scope. >>> - once you learn it, you can use it elsewhere, e.g. pcase-let, >>> pcase-dolist, ... >> >> Could have been the same for cl-destructuring-bind. > > Except cl-destructuring-bind only covers (a subset of) pcase-let. > It could cover pcase-let as well pcase-dolist, but not `pcase` itself. > [ And even then, it would be less flexible than pcase-let because the > syntax of cl-destructuring-bind's patterns doesn't leave much space > for extensions. ] pcase is about pattern matching, that implies conditions, or at least recognition or tests, pcase-let only does destructuring afaik, so shouldn’t cl-destructuring-bind be improved instead, and all the pcase-* functions actually only doing destructuring be based on it? >> For instance, I personally have my own case* implementation for using >> other test-fn than eql (such as equal, > > That highlights the problem that cl-case doesn't work with strings, > forcing users like you to write their own alternative. Ahh, that’s what you meant by “doesn’t work”. Well, eq can still be useful, for strings, I believe, otherwise eq wouldn’t exist and we would only have equal (though this is what pcase does), so I wouldn’t call that “doesn’t work”. But a * version that takes a testfn as argument can improve expressivity I believe (what if you want to compare, dunno, hashes?) >> the only possible one for pcase, and I don’t even hope making my own >> version for eq/eql/etc.). > > Could you show me a pcase pattern where pcase's choice of equality > is problematic? > [ FWIW, there's only one case to comes to my mind. ] Now I know about the (equal ) pattern form, I guess a (eq ) wouldn’t be that difficult to add, and as one of these would be mandatory to specify non-constant (hence possibly same) strings (though maybe there’s a way to trigger arbitrary computation from inside the pattern before another get tried), it stays under control, so I don’t have any (case) anymore. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-23 18:12 ` Stefan Monnier 2018-10-23 19:52 ` pcase vs. case (where it could also be used) [Was: Re: Replace trivial pcase occurrences in the Emacs sources] Garreau, Alexandre @ 2018-10-24 15:03 ` Eli Zaretskii 2018-10-24 15:30 ` Michael Heerdegen ` (3 more replies) 1 sibling, 4 replies; 375+ messages in thread From: Eli Zaretskii @ 2018-10-24 15:03 UTC (permalink / raw) To: Stefan Monnier; +Cc: emacs-devel > From: Stefan Monnier <monnier@iro.umontreal.ca> > Date: Tue, 23 Oct 2018 14:12:34 -0400 > > > I think so too, but it seems the majority of developers has a different > > option, at least in this (old) thread. > > So I guess I'm gonna have to try and argue my case. > OK, here are the advantages I see for `cl-case`: FWIW, my main problem is not even with cl-case, it's with 'cond'. It seems like we have some 'pcase' epidemic, whose first symptom is that people stop using 'cond' and start using 'pcase' instead. A few examples: todo-mode.el: (pcase this-param ('edit (todo-edit-item--text)) ('header (todo-edit-item--text 'include-header)) ('multiline (todo-edit-item--text 'multiline)) ('add/edit (todo-edit-item--text 'comment-edit)) ('delete (todo-edit-item--text 'comment-delete)) ('diary (todo-edit-item--diary-inclusion)) ('nonmarking (todo-edit-item--diary-inclusion 'nonmarking)) [...] auth-source-pass.el: (pcase (length matching-entries) (0 (auth-source-pass--do-debug "no match found") nil) (1 (auth-source-pass--do-debug "found 1 match: %s" (car matching-entries)) (car matching-entries)) (_ (auth-source-pass--select-one-entry matching-entries user))))) bs.el: (setq bs-buffer-show-mark (pcase bs-buffer-show-mark (`nil 'never) (`never 'always) (_ nil)))))) calculator.el: (<= inp (pcase calculator-input-radix (`nil ?9) (`bin ?1) (`oct ?7) (_ 999)))) lpr.el: (pcase (count-lines (point-min) (point-max)) (0 "") (1 ": ") (_ ":\n")) My favorite is imap.el, which does something like the above in 3 nested levels. I will spare you the code, you can look it up. Is it because people are too lazy to write (eq a b) as part of 'cond'? Or is there something else I'm missing? You may wonder why I'm bothered by such uses. It's because people are evidently confused by 'pcase's arcane syntax, and therefore produce obfuscated code even in the simple usage. For example: apropos.el: (pcase (car-safe x) ;; (autoload (push (cdr x) autoloads)) (`require (push (cdr x) requires)) (`provide (push (cdr x) provides)) (`t nil) ; Skip "was an autoload" entries. ;; FIXME: Print information about each individual method: both ;; its docstring and specializers (bug#21422). (`cl-defmethod (push (cadr x) provides)) (_ (push (or (cdr-safe x) x) symbols)))) (Quick: what's the difference between `require and 'require in this case?) easy-mmode.el: (pcase keyw (`:group (setq group (nconc group (list :group (pop keys))))) (`:global (setq keys (cdr keys))) (_ (push keyw extra-keywords) (push (pop keys) extra-keywords)))) (Aren't keywords supposed to be self-quoting? then why they are explicitly quoted?) We have dozens of such fragments in our codebase, which just makes the sources harder to read, especially for people who aren't fluent with 'pcase' (which seems to be the case with many of us). So I think we should begin by rewriting all of such uses as simple 'cond', and ask contributors not to use 'pcase' where a simple 'cond' will do. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-24 15:03 ` Replace trivial pcase occurrences in the Emacs sources Eli Zaretskii @ 2018-10-24 15:30 ` Michael Heerdegen 2018-10-24 15:40 ` Eli Zaretskii ` (2 more replies) 2018-10-24 15:47 ` Clément Pit-Claudel ` (2 subsequent siblings) 3 siblings, 3 replies; 375+ messages in thread From: Michael Heerdegen @ 2018-10-24 15:30 UTC (permalink / raw) To: Eli Zaretskii; +Cc: Stefan Monnier, emacs-devel Eli Zaretskii <eliz@gnu.org> writes: > FWIW, my main problem is not even with cl-case, it's with 'cond'. It > seems like we have some 'pcase' epidemic, whose first symptom is that > people stop using 'cond' and start using 'pcase' instead. A few > examples: > > todo-mode.el: > > (pcase this-param > ('edit (todo-edit-item--text)) > ('header (todo-edit-item--text 'include-header)) > ('multiline (todo-edit-item--text 'multiline)) > ('add/edit (todo-edit-item--text 'comment-edit)) > ('delete (todo-edit-item--text 'comment-delete)) > ('diary (todo-edit-item--diary-inclusion)) > ('nonmarking (todo-edit-item--diary-inclusion 'nonmarking)) > [...] > > auth-source-pass.el: > > (pcase (length matching-entries) > (0 (auth-source-pass--do-debug "no match found") > nil) > (1 (auth-source-pass--do-debug "found 1 match: %s" (car matching-entries)) > (car matching-entries)) > (_ (auth-source-pass--select-one-entry matching-entries user))))) > > bs.el: > > (setq bs-buffer-show-mark (pcase bs-buffer-show-mark > (`nil 'never) > (`never 'always) > (_ nil)))))) > > calculator.el: > > (<= inp (pcase calculator-input-radix > (`nil ?9) (`bin ?1) (`oct ?7) (_ 999)))) > > lpr.el: > > (pcase (count-lines (point-min) (point-max)) > (0 "") > (1 ": ") > (_ ":\n")) FWIW, these are the major cases I wanted to treat, but I wanted to replace them with equivalent cl-case forms, not with `cond's. > (Quick: what's the difference between `require and 'require in this > case?) There is none any more. > easy-mmode.el: > > (pcase keyw > (`:group (setq group (nconc group (list :group (pop keys))))) > (`:global (setq keys (cdr keys))) > (_ (push keyw extra-keywords) (push (pop keys) extra-keywords)))) > > (Aren't keywords supposed to be self-quoting? then why they are > explicitly quoted?) Yes. > We have dozens of such fragments in our codebase, which just makes the > sources harder to read, especially for people who aren't fluent with > 'pcase' (which seems to be the case with many of us). These are all cases I would want to fix, but unless the whole pcase form can be trivially rewritten as cl-case, I want to leave pcase, really. Michael. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-24 15:30 ` Michael Heerdegen @ 2018-10-24 15:40 ` Eli Zaretskii 2018-10-24 15:48 ` Michael Heerdegen 2018-10-24 18:47 ` Garreau, Alexandre 2018-10-27 15:19 ` Michael Heerdegen 2 siblings, 1 reply; 375+ messages in thread From: Eli Zaretskii @ 2018-10-24 15:40 UTC (permalink / raw) To: Michael Heerdegen; +Cc: monnier, emacs-devel > From: Michael Heerdegen <michael_heerdegen@web.de> > Cc: Stefan Monnier <monnier@iro.umontreal.ca>, emacs-devel@gnu.org > Date: Wed, 24 Oct 2018 17:30:26 +0200 > > > We have dozens of such fragments in our codebase, which just makes the > > sources harder to read, especially for people who aren't fluent with > > 'pcase' (which seems to be the case with many of us). > > These are all cases I would want to fix, but unless the whole pcase form > can be trivially rewritten as cl-case, I want to leave pcase, really. I agree with the "trivial" part, but why cl-case and not cond (with the same "trivial" caveat)? ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-24 15:40 ` Eli Zaretskii @ 2018-10-24 15:48 ` Michael Heerdegen 2018-10-24 17:35 ` Eli Zaretskii 0 siblings, 1 reply; 375+ messages in thread From: Michael Heerdegen @ 2018-10-24 15:48 UTC (permalink / raw) To: Eli Zaretskii; +Cc: monnier, emacs-devel Eli Zaretskii <eliz@gnu.org> writes: > I agree with the "trivial" part, but why cl-case and not cond (with > the same "trivial" caveat)? Just because `cl-case' fits better? - for an equivalent rewrite using `cond', I need to define an extra local variable to bind the treated value to, event a name for it (we speak about ~ 300 cases!) and all cond branches would look equally like (eq VAR 'VAL). Not an improvement in readability in my mind. There is a minority (around ~ 20 cases) that look like (pcase EXPR ('X1 foo1) ('X2 foo2) ... (VAR EXPR-USING-THE-VAR)) with a catchall last branch that already use a variable binding. These would fit a bit better to `cond', but as said, that's a minority. Michael. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-24 15:48 ` Michael Heerdegen @ 2018-10-24 17:35 ` Eli Zaretskii 2018-10-24 17:55 ` Michael Heerdegen 0 siblings, 1 reply; 375+ messages in thread From: Eli Zaretskii @ 2018-10-24 17:35 UTC (permalink / raw) To: Michael Heerdegen; +Cc: monnier, emacs-devel > From: Michael Heerdegen <michael_heerdegen@web.de> > Cc: monnier@iro.umontreal.ca, emacs-devel@gnu.org > Date: Wed, 24 Oct 2018 17:48:50 +0200 > > Eli Zaretskii <eliz@gnu.org> writes: > > > I agree with the "trivial" part, but why cl-case and not cond (with > > the same "trivial" caveat)? > > Just because `cl-case' fits better? - for an equivalent rewrite using > `cond', I need to define an extra local variable to bind the treated > value to, event a name for it (we speak about ~ 300 cases!) and all cond > branches would look equally like (eq VAR 'VAL). Not an improvement in > readability in my mind. I guess we will have to disagree about that. At the very least, you require people to be acquainted with cl-case well enough. And if repeating (eq foo 'bar) is the issue, you can use assoc and a data structure, see my other message. Just a thought. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-24 17:35 ` Eli Zaretskii @ 2018-10-24 17:55 ` Michael Heerdegen 2018-10-24 18:32 ` Eli Zaretskii 0 siblings, 1 reply; 375+ messages in thread From: Michael Heerdegen @ 2018-10-24 17:55 UTC (permalink / raw) To: Eli Zaretskii; +Cc: monnier, emacs-devel Eli Zaretskii <eliz@gnu.org> writes: > And if repeating (eq foo 'bar) is the issue, you can use assoc and a > data structure, see my other message. Just a thought. That won't do it: pcase (or cl-case) clauses specify expressions to evaluate instead of only values to return. Only those pcase forms that have no side effects could be transformed into such an cdr-assoc combination. Michael. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-24 17:55 ` Michael Heerdegen @ 2018-10-24 18:32 ` Eli Zaretskii 0 siblings, 0 replies; 375+ messages in thread From: Eli Zaretskii @ 2018-10-24 18:32 UTC (permalink / raw) To: Michael Heerdegen; +Cc: monnier, emacs-devel > From: Michael Heerdegen <michael_heerdegen@web.de> > Cc: monnier@iro.umontreal.ca, emacs-devel@gnu.org > Date: Wed, 24 Oct 2018 19:55:28 +0200 > > > And if repeating (eq foo 'bar) is the issue, you can use assoc and a > > data structure, see my other message. Just a thought. > > That won't do it: pcase (or cl-case) clauses specify expressions to > evaluate instead of only values to return. Only those pcase forms that > have no side effects could be transformed into such an cdr-assoc > combination. Yes, but there are gobs of those. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-24 15:30 ` Michael Heerdegen 2018-10-24 15:40 ` Eli Zaretskii @ 2018-10-24 18:47 ` Garreau, Alexandre 2018-10-27 15:19 ` Michael Heerdegen 2 siblings, 0 replies; 375+ messages in thread From: Garreau, Alexandre @ 2018-10-24 18:47 UTC (permalink / raw) To: Michael Heerdegen; +Cc: Eli Zaretskii, Stefan Monnier, emacs-devel On 2018-10-24 at 17:30, Michael Heerdegen wrote: > Eli Zaretskii <eliz@gnu.org> writes: > >> FWIW, my main problem is not even with cl-case, it's with 'cond'. It >> seems like we have some 'pcase' epidemic, whose first symptom is that >> people stop using 'cond' and start using 'pcase' instead. A few >> examples: >> >> todo-mode.el: >> >> (pcase this-param >> ('edit (todo-edit-item--text)) >> ('header (todo-edit-item--text 'include-header)) >> ('multiline (todo-edit-item--text 'multiline)) >> ('add/edit (todo-edit-item--text 'comment-edit)) >> ('delete (todo-edit-item--text 'comment-delete)) >> ('diary (todo-edit-item--diary-inclusion)) >> ('nonmarking (todo-edit-item--diary-inclusion 'nonmarking)) >> [...] >> >> auth-source-pass.el: >> >> (pcase (length matching-entries) >> (0 (auth-source-pass--do-debug "no match found") >> nil) >> (1 (auth-source-pass--do-debug "found 1 match: %s" (car matching-entries)) >> (car matching-entries)) >> (_ (auth-source-pass--select-one-entry matching-entries user))))) >> >> bs.el: >> >> (setq bs-buffer-show-mark (pcase bs-buffer-show-mark >> (`nil 'never) >> (`never 'always) >> (_ nil)))))) >> >> calculator.el: >> >> (<= inp (pcase calculator-input-radix >> (`nil ?9) (`bin ?1) (`oct ?7) (_ 999)))) >> >> lpr.el: >> >> (pcase (count-lines (point-min) (point-max)) >> (0 "") >> (1 ": ") >> (_ ":\n")) > > FWIW, these are the major cases I wanted to treat, but I wanted to > replace them with equivalent cl-case forms, not with `cond's. > >> (Quick: what's the difference between `require and 'require in this >> case?) > > There is none any more. > >> easy-mmode.el: >> >> (pcase keyw >> (`:group (setq group (nconc group (list :group (pop keys))))) >> (`:global (setq keys (cdr keys))) >> (_ (push keyw extra-keywords) (push (pop keys) extra-keywords)))) >> >> (Aren't keywords supposed to be self-quoting? then why they are >> explicitly quoted?) > > Yes. > >> We have dozens of such fragments in our codebase, which just makes the >> sources harder to read, especially for people who aren't fluent with >> 'pcase' (which seems to be the case with many of us). > > These are all cases I would want to fix, but unless the whole pcase form > can be trivially rewritten as cl-case, I want to leave pcase, really. I’d prefer much this, as I find `case' well much less redundant, it’s just basic factorization. Programming is here to factorize, so it should be factorized. Even C do that. Case is the simpler, most obvious and straightforward to factorize a lot of cond (it is a shame we don’t have it with equal, some case* or case-equal would be appreciated). ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-24 15:30 ` Michael Heerdegen 2018-10-24 15:40 ` Eli Zaretskii 2018-10-24 18:47 ` Garreau, Alexandre @ 2018-10-27 15:19 ` Michael Heerdegen 2018-10-27 16:56 ` Garreau, Alexandre ` (2 more replies) 2 siblings, 3 replies; 375+ messages in thread From: Michael Heerdegen @ 2018-10-27 15:19 UTC (permalink / raw) To: Eli Zaretskii; +Cc: Stefan Monnier, emacs-devel [-- Attachment #1: Type: text/plain, Size: 2640 bytes --] Michael Heerdegen <michael_heerdegen@web.de> writes: > > easy-mmode.el: > > > > (pcase keyw > > (`:group (setq group (nconc group (list :group (pop keys))))) > > (`:global (setq keys (cdr keys))) > > (_ (push keyw extra-keywords) (push (pop keys) extra-keywords)))) > > > > (Aren't keywords supposed to be self-quoting? then why they are > > explicitly quoted?) > These are all cases I would want to fix, but unless the whole pcase form > can be trivially rewritten as cl-case, I want to leave pcase, really. Here is the first patch addressing quoted selfquoting patterns. I left out cl-generic.el which is distributed via Gnu Elpa because selfquoting pattern types are two years younger than pcase is. Is the commit message ok as it is? Or should I list the changed files to say "All callers changed" every time? Here and there the patch also fixes indentation of surrounding code. In the next step I want to replace `DOESNT-UNQUOTE -> DOESNT-UNQUOTE, though we have one opinion that didn't want me to do this so that the code looks more frightening and people are warned. I don't think it is necessary to warn people about pcase, and I don't think warning people about hard to read code by making the code even harder to read is a good thing ;-) What's then left is the task to replace all pcase forms that can be trivially rewritten by using case or cond/assoc. I must admit that I'm very skeptical about this now. Not only that we would only replace exactly these pcase occurrences that are really trivial to read for anybody, which could be, at the end, counterproductive for those people who dislike pcase because the pcase forms left are the harder ones (Eli, I know you don't think like that). I also saw that people have very different likings, independent from pcase. Say, we have one third of people who want to keep pcase in these cases, one third who want to replace it with cl-case, and one third who want cond or assoc instead. We have a clear majority against pcase. But we also have a clear majority against cl-case, and a majority against cond/assoc. With all input I got, I came to the conclusion that what we have is quite ok: A pcase with branches whose condition all look like 'CONSTANT is not too hard to read for anyone. I saw there are pros and cons for and against keeping these in the code, but I didn't get the impression that one side clearly prevails. Eli and Stefan, if you could agree about something I should do, or if the maintainer(s) tell me I should do these replacement, I still offer to do it, but I don't think we came to any conclusion yet. And here is the first patch: [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #2: 0001-Don-t-quote-self-quoting-pcase-patterns.patch --] [-- Type: text/x-diff, Size: 39052 bytes --] From 0045835058ed5f0af07bfe2c67940824c6c084fd Mon Sep 17 00:00:00 2001 From: Michael Heerdegen <michael_heerdegen@web.de> Date: Sat, 27 Oct 2018 01:48:35 +0200 Subject: [PATCH] Don't quote self-quoting pcase patterns --- admin/bzrmerge.el | 6 +-- lisp/char-fold.el | 2 +- lisp/dired.el | 8 ++-- lisp/emacs-lisp/derived.el | 8 ++-- lisp/emacs-lisp/easy-mmode.el | 62 ++++++++++++++--------------- lisp/emacs-lisp/easymenu.el | 28 ++++++------- lisp/emacs-lisp/eieio-core.el | 6 +-- lisp/emacs-lisp/package.el | 22 +++++----- lisp/emacs-lisp/smie.el | 4 +- lisp/faces.el | 22 +++++----- lisp/filesets.el | 2 +- lisp/progmodes/modula2.el | 22 +++++----- lisp/progmodes/octave.el | 36 ++++++++--------- lisp/progmodes/opascal.el | 14 +++---- lisp/progmodes/perl-mode.el | 4 +- lisp/progmodes/prolog.el | 14 +++---- lisp/progmodes/ruby-mode.el | 18 ++++----- lisp/progmodes/sh-script.el | 18 ++++----- lisp/server.el | 32 +++++++-------- lisp/subr.el | 2 +- lisp/textmodes/css-mode.el | 2 +- test/lisp/emacs-lisp/pcase-tests.el | 2 +- 22 files changed, 167 insertions(+), 167 deletions(-) diff --git a/admin/bzrmerge.el b/admin/bzrmerge.el index cedb625fb0..d54ba330f9 100644 --- a/admin/bzrmerge.el +++ b/admin/bzrmerge.el @@ -150,12 +150,12 @@ bzrmerge-missing (format "%s: Skip (y/n/N/q/%s)? " str (key-description (vector help-char))) '(?y ?n ?N ?q))) - (`?y (setq skip t)) - (`?q (keyboard-quit)) + (?y (setq skip t)) + (?q (keyboard-quit)) ;; A single log entry can match skip-regexp multiple ;; times. If you are sure you don't want to skip it, ;; you don't want to be asked multiple times. - (`?N (setq skip 'no)))))) + (?N (setq skip 'no)))))) (if (eq skip t) (push revno skipped) (push revno revnos))))) diff --git a/lisp/char-fold.el b/lisp/char-fold.el index 86bd6038e3..907d49e4f2 100644 --- a/lisp/char-fold.el +++ b/lisp/char-fold.el @@ -170,7 +170,7 @@ char-fold-to-regexp ;; need to keep them grouped together like this: "\\( \\|[ ...][ ...]\\)". (while (< i end) (pcase (aref string i) - (`?\s (setq spaces (1+ spaces))) + (?\s (setq spaces (1+ spaces))) (c (when (> spaces 0) (push (char-fold--make-space-string spaces) out) (setq spaces 0)) diff --git a/lisp/dired.el b/lisp/dired.el index 5c7bb9599c..f2f2b76eb7 100644 --- a/lisp/dired.el +++ b/lisp/dired.el @@ -3046,10 +3046,10 @@ dired-delete-file ("no" ?n "skip to next") ("all" ?! "delete all remaining directories with no more questions") ("quit" ?q "exit"))) - ('"all" (setq recursive 'always dired-recursive-deletes recursive)) - ('"yes" (if (eq recursive 'top) (setq recursive 'always))) - ('"no" (setq recursive nil)) - ('"quit" (keyboard-quit)) + ("all" (setq recursive 'always dired-recursive-deletes recursive)) + ("yes" (if (eq recursive 'top) (setq recursive 'always))) + ("no" (setq recursive nil)) + ("quit" (keyboard-quit)) (_ (keyboard-quit))))) ; catch all unknown answers (setq recursive nil)) ; Empty dir or recursive is nil. (delete-directory file recursive trash)))) diff --git a/lisp/emacs-lisp/derived.el b/lisp/emacs-lisp/derived.el index 6b47ffea07..483d6fbfa4 100644 --- a/lisp/emacs-lisp/derived.el +++ b/lisp/emacs-lisp/derived.el @@ -193,10 +193,10 @@ define-derived-mode ;; Process the keyword args. (while (keywordp (car body)) (pcase (pop body) - (`:group (setq group (pop body))) - (`:abbrev-table (setq abbrev (pop body)) (setq declare-abbrev nil)) - (`:syntax-table (setq syntax (pop body)) (setq declare-syntax nil)) - (`:after-hook (setq after-hook (pop body))) + (:group (setq group (pop body))) + (:abbrev-table (setq abbrev (pop body)) (setq declare-abbrev nil)) + (:syntax-table (setq syntax (pop body)) (setq declare-syntax nil)) + (:after-hook (setq after-hook (pop body))) (_ (pop body)))) (setq docstring (derived-mode-make-docstring diff --git a/lisp/emacs-lisp/easy-mmode.el b/lisp/emacs-lisp/easy-mmode.el index 4d8a502026..d74c3ddb97 100644 --- a/lisp/emacs-lisp/easy-mmode.el +++ b/lisp/emacs-lisp/easy-mmode.el @@ -217,30 +217,30 @@ define-minor-mode (while (keywordp (setq keyw (car body))) (setq body (cdr body)) (pcase keyw - (`:init-value (setq init-value (pop body))) - (`:lighter (setq lighter (purecopy (pop body)))) - (`:global (setq globalp (pop body)) - (when (and globalp (symbolp mode)) - (setq setter `(setq-default ,mode)) - (setq getter `(default-value ',mode)))) - (`:extra-args (setq extra-args (pop body))) - (`:set (setq set (list :set (pop body)))) - (`:initialize (setq initialize (list :initialize (pop body)))) - (`:group (setq group (nconc group (list :group (pop body))))) - (`:type (setq type (list :type (pop body)))) - (`:require (setq require (pop body))) - (`:keymap (setq keymap (pop body))) - (`:variable (setq variable (pop body)) - (if (not (and (setq tmp (cdr-safe variable)) - (or (symbolp tmp) - (functionp tmp)))) - ;; PLACE is not of the form (GET . SET). - (progn - (setq setter `(setf ,variable)) - (setq getter variable)) - (setq getter (car variable)) - (setq setter `(funcall #',(cdr variable))))) - (`:after-hook (setq after-hook (pop body))) + (:init-value (setq init-value (pop body))) + (:lighter (setq lighter (purecopy (pop body)))) + (:global (setq globalp (pop body)) + (when (and globalp (symbolp mode)) + (setq setter `(setq-default ,mode)) + (setq getter `(default-value ',mode)))) + (:extra-args (setq extra-args (pop body))) + (:set (setq set (list :set (pop body)))) + (:initialize (setq initialize (list :initialize (pop body)))) + (:group (setq group (nconc group (list :group (pop body))))) + (:type (setq type (list :type (pop body)))) + (:require (setq require (pop body))) + (:keymap (setq keymap (pop body))) + (:variable (setq variable (pop body)) + (if (not (and (setq tmp (cdr-safe variable)) + (or (symbolp tmp) + (functionp tmp)))) + ;; PLACE is not of the form (GET . SET). + (progn + (setq setter `(setf ,variable)) + (setq getter variable)) + (setq getter (car variable)) + (setq setter `(funcall #',(cdr variable))))) + (:after-hook (setq after-hook (pop body))) (_ (push keyw extra-keywords) (push (pop body) extra-keywords)))) (setq keymap-sym (if (and keymap (symbolp keymap)) keymap @@ -407,8 +407,8 @@ define-globalized-minor-mode (while (keywordp (setq keyw (car keys))) (setq keys (cdr keys)) (pcase keyw - (`:group (setq group (nconc group (list :group (pop keys))))) - (`:global (setq keys (cdr keys))) + (:group (setq group (nconc group (list :group (pop keys))))) + (:global (setq keys (cdr keys))) (_ (push keyw extra-keywords) (push (pop keys) extra-keywords)))) (unless group @@ -533,11 +533,11 @@ easy-mmode-define-keymap (let ((key (pop args)) (val (pop args))) (pcase key - (`:name (setq name val)) - (`:dense (setq dense val)) - (`:inherit (setq inherit val)) - (`:suppress (setq suppress val)) - (`:group) + (:name (setq name val)) + (:dense (setq dense val)) + (:inherit (setq inherit val)) + (:suppress (setq suppress val)) + (:group) (_ (message "Unknown argument %s in defmap" key))))) (unless (keymapp m) (setq bs (append m bs)) diff --git a/lisp/emacs-lisp/easymenu.el b/lisp/emacs-lisp/easymenu.el index 94d035f374..403829ac46 100644 --- a/lisp/emacs-lisp/easymenu.el +++ b/lisp/emacs-lisp/easymenu.el @@ -226,14 +226,14 @@ easy-menu-create-menu (let ((arg (cadr menu-items))) (setq menu-items (cddr menu-items)) (pcase keyword - (`:filter + (:filter (setq filter (lambda (menu) (easy-menu-filter-return (funcall arg menu) menu-name)))) - ((or `:enable `:active) (setq enable (or arg ''nil))) - (`:label (setq label arg)) - (`:help (setq help arg)) - ((or `:included `:visible) (setq visible (or arg ''nil)))))) + ((or :enable :active) (setq enable (or arg ''nil))) + (:label (setq label arg)) + (:help (setq help arg)) + ((or :included :visible) (setq visible (or arg ''nil)))))) (if (equal visible ''nil) nil ; Invisible menu entry, return nil. (if (and visible (not (easy-menu-always-true-p visible))) @@ -325,15 +325,15 @@ easy-menu-convert-item-1 (setq arg (aref item (1+ count))) (setq count (+ 2 count)) (pcase keyword - ((or `:included `:visible) (setq visible (or arg ''nil))) - (`:key-sequence (setq cache arg cache-specified t)) - (`:keys (setq keys arg no-name nil)) - (`:label (setq label arg)) - ((or `:active `:enable) (setq active (or arg ''nil))) - (`:help (setq prop (cons :help (cons arg prop)))) - (`:suffix (setq suffix arg)) - (`:style (setq style arg)) - (`:selected (setq selected (or arg ''nil))))) + ((or :included :visible) (setq visible (or arg ''nil))) + (:key-sequence (setq cache arg cache-specified t)) + (:keys (setq keys arg no-name nil)) + (:label (setq label arg)) + ((or :active :enable) (setq active (or arg ''nil))) + (:help (setq prop (cons :help (cons arg prop)))) + (:suffix (setq suffix arg)) + (:style (setq style arg)) + (:selected (setq selected (or arg ''nil))))) (if suffix (setq label (if (stringp suffix) diff --git a/lisp/emacs-lisp/eieio-core.el b/lisp/emacs-lisp/eieio-core.el index e5ea33c003..e5c4f198f5 100644 --- a/lisp/emacs-lisp/eieio-core.el +++ b/lisp/emacs-lisp/eieio-core.el @@ -388,9 +388,9 @@ eieio-defclass-internal ;; Clean up the meaning of protection. (setq prot (pcase prot - ((or 'nil 'public ':public) nil) - ((or 'protected ':protected) 'protected) - ((or 'private ':private) 'private) + ((or 'nil 'public :public) nil) + ((or 'protected :protected) 'protected) + ((or 'private :private) 'private) (_ (signal 'invalid-slot-type (list :protection prot))))) ;; The default type specifier is supposed to be t, meaning anything. diff --git a/lisp/emacs-lisp/package.el b/lisp/emacs-lisp/package.el index 9c4c3e9fe7..f2ffef8da7 100644 --- a/lisp/emacs-lisp/package.el +++ b/lisp/emacs-lisp/package.el @@ -2911,17 +2911,17 @@ package-menu--print-info-simple Return (PKG-DESC [NAME VERSION STATUS DOC])." (let* ((status (package-desc-status pkg)) (face (pcase status - (`"built-in" 'package-status-built-in) - (`"external" 'package-status-external) - (`"available" 'package-status-available) - (`"avail-obso" 'package-status-avail-obso) - (`"new" 'package-status-new) - (`"held" 'package-status-held) - (`"disabled" 'package-status-disabled) - (`"installed" 'package-status-installed) - (`"dependency" 'package-status-dependency) - (`"unsigned" 'package-status-unsigned) - (`"incompat" 'package-status-incompat) + ("built-in" 'package-status-built-in) + ("external" 'package-status-external) + ("available" 'package-status-available) + ("avail-obso" 'package-status-avail-obso) + ("new" 'package-status-new) + ("held" 'package-status-held) + ("disabled" 'package-status-disabled) + ("installed" 'package-status-installed) + ("dependency" 'package-status-dependency) + ("unsigned" 'package-status-unsigned) + ("incompat" 'package-status-incompat) (_ 'font-lock-warning-face)))) ; obsolete. (list pkg `[(,(symbol-name (package-desc-name pkg)) diff --git a/lisp/emacs-lisp/smie.el b/lisp/emacs-lisp/smie.el index c01a40172b..4b82172984 100644 --- a/lisp/emacs-lisp/smie.el +++ b/lisp/emacs-lisp/smie.el @@ -1856,9 +1856,9 @@ smie-setup (let ((k (pop keywords)) (v (pop keywords))) (pcase k - (`:forward-token + (:forward-token (set (make-local-variable 'smie-forward-token-function) v)) - (`:backward-token + (:backward-token (set (make-local-variable 'smie-backward-token-function) v)) (_ (message "smie-setup: ignoring unknown keyword %s" k))))) (let ((ca (cdr (assq :smie-closer-alist grammar)))) diff --git a/lisp/faces.el b/lisp/faces.el index 18b821a0b6..a8c1546d5a 100644 --- a/lisp/faces.el +++ b/lisp/faces.el @@ -1084,27 +1084,27 @@ face-valid-attribute-values an integer value." (let ((valid (pcase attribute - (`:family + (:family (if (window-system frame) (mapcar (lambda (x) (cons x x)) (font-family-list)) ;; Only one font on TTYs. (list (cons "default" "default")))) - (`:foundry + (:foundry (list nil)) - (`:width + (:width (mapcar #'(lambda (x) (cons (symbol-name (aref x 1)) (aref x 1))) font-width-table)) - (`:weight + (:weight (mapcar #'(lambda (x) (cons (symbol-name (aref x 1)) (aref x 1))) font-weight-table)) - (`:slant + (:slant (mapcar #'(lambda (x) (cons (symbol-name (aref x 1)) (aref x 1))) font-slant-table)) - (`:inverse-video + (:inverse-video (mapcar #'(lambda (x) (cons (symbol-name x) x)) (internal-lisp-face-attribute-values attribute))) - ((or `:underline `:overline `:strike-through `:box) + ((or :underline :overline :strike-through :box) (if (window-system frame) (nconc (mapcar #'(lambda (x) (cons (symbol-name x) x)) (internal-lisp-face-attribute-values attribute)) @@ -1112,12 +1112,12 @@ face-valid-attribute-values (defined-colors frame))) (mapcar #'(lambda (x) (cons (symbol-name x) x)) (internal-lisp-face-attribute-values attribute)))) - ((or `:foreground `:background) + ((or :foreground :background) (mapcar #'(lambda (c) (cons c c)) (defined-colors frame))) - (`:height + (:height 'integerp) - (`:stipple + (:stipple (and (memq (window-system frame) '(x ns)) ; No stipple on w32 (mapcar #'list (apply #'nconc @@ -1126,7 +1126,7 @@ face-valid-attribute-values (file-directory-p dir) (directory-files dir))) x-bitmap-file-path))))) - (`:inherit + (:inherit (cons '("none" . nil) (mapcar #'(lambda (c) (cons (symbol-name c) c)) (face-list)))) diff --git a/lisp/filesets.el b/lisp/filesets.el index c1e6ef10d5..8ccfa570e3 100644 --- a/lisp/filesets.el +++ b/lisp/filesets.el @@ -1559,7 +1559,7 @@ filesets-file-close (defun filesets-get-fileset-from-name (name &optional mode) "Get fileset definition for NAME." (pcase mode - ((or `:ingroup `:tree) name) + ((or :ingroup :tree) name) (_ (assoc name filesets-data)))) diff --git a/lisp/progmodes/modula2.el b/lisp/progmodes/modula2.el index 582e495a2b..ef12352457 100644 --- a/lisp/progmodes/modula2.el +++ b/lisp/progmodes/modula2.el @@ -232,11 +232,11 @@ m2-smie-refine-semi ;; FIXME: "^." are two tokens, not one. (defun m2-smie-forward-token () (pcase (smie-default-forward-token) - (`"VAR" (if (zerop (car (syntax-ppss))) "VAR" "VAR-arg")) - (`"CONST" (if (zerop (car (syntax-ppss))) "CONST" "CONST-arg")) - (`";" (save-excursion (m2-smie-refine-semi))) - (`"OF" (save-excursion (forward-char -2) (m2-smie-refine-of))) - (`":" (save-excursion (forward-char -1) (m2-smie-refine-colon))) + ("VAR" (if (zerop (car (syntax-ppss))) "VAR" "VAR-arg")) + ("CONST" (if (zerop (car (syntax-ppss))) "CONST" "CONST-arg")) + (";" (save-excursion (m2-smie-refine-semi))) + ("OF" (save-excursion (forward-char -2) (m2-smie-refine-of))) + (":" (save-excursion (forward-char -1) (m2-smie-refine-colon))) ;; (`"END" (if (and (looking-at "[ \t\n]*\\(\\(?:\\sw\\|\\s_\\)+\\)") ;; (not (assoc (match-string 1) m2-smie-grammar))) ;; "END-proc" "END")) @@ -244,11 +244,11 @@ m2-smie-forward-token (defun m2-smie-backward-token () (pcase (smie-default-backward-token) - (`"VAR" (if (zerop (car (syntax-ppss))) "VAR" "VAR-arg")) - (`"CONST" (if (zerop (car (syntax-ppss))) "CONST" "CONST-arg")) - (`";" (save-excursion (forward-char 1) (m2-smie-refine-semi))) - (`"OF" (save-excursion (m2-smie-refine-of))) - (`":" (save-excursion (m2-smie-refine-colon))) + ("VAR" (if (zerop (car (syntax-ppss))) "VAR" "VAR-arg")) + ("CONST" (if (zerop (car (syntax-ppss))) "CONST" "CONST-arg")) + (";" (save-excursion (forward-char 1) (m2-smie-refine-semi))) + ("OF" (save-excursion (m2-smie-refine-of))) + (":" (save-excursion (m2-smie-refine-colon))) ;; (`"END" (if (and (looking-at "\\sw+[ \t\n]+\\(\\(?:\\sw\\|\\s_\\)+\\)") ;; (not (assoc (match-string 1) m2-smie-grammar))) ;; "END-proc" "END")) @@ -272,7 +272,7 @@ m2-smie-rules (pcase (cons kind token) (`(:elem . basic) m2-indent) (`(:after . ":=") (or m2-indent smie-indent-basic)) - (`(:after . ,(or `"CONST" `"VAR" `"TYPE")) + (`(:after . ,(or "CONST" "VAR" "TYPE")) (or m2-indent smie-indent-basic)) ;; (`(:before . ,(or `"VAR" `"TYPE" `"CONST")) ;; (if (smie-rule-parent-p "PROCEDURE") 0)) diff --git a/lisp/progmodes/octave.el b/lisp/progmodes/octave.el index 13510eef80..cce5e17e79 100644 --- a/lisp/progmodes/octave.el +++ b/lisp/progmodes/octave.el @@ -1065,8 +1065,8 @@ octave-goto-function-definition (unless found (goto-char orig)) found)))) (pcase (and buffer-file-name (file-name-extension buffer-file-name)) - (`"cc" (funcall search - "\\_<DEFUN\\(?:_DLD\\)?\\s-*(\\s-*\\(\\(?:\\sw\\|\\s_\\)+\\)" 1)) + ("cc" (funcall search + "\\_<DEFUN\\(?:_DLD\\)?\\s-*(\\s-*\\(\\(?:\\sw\\|\\s_\\)+\\)" 1)) (_ (funcall search octave-function-header-regexp 3))))) (defun octave-function-file-p () @@ -1135,19 +1135,19 @@ octave-sync-function-file-names (read-char-choice "Which name to use? (a/b/q) " '(?a ?b ?q)))))) (pcase c - (`?a (let ((newname (expand-file-name - (concat func (file-name-extension - buffer-file-name t))))) - (when (or (not (file-exists-p newname)) - (yes-or-no-p - (format "Target file %s exists; proceed? " newname))) - (when (file-exists-p buffer-file-name) - (rename-file buffer-file-name newname t)) - (set-visited-file-name newname)))) - (`?b (save-excursion - (goto-char name-start) - (delete-region name-start name-end) - (insert file))))))))) + (?a (let ((newname (expand-file-name + (concat func (file-name-extension + buffer-file-name t))))) + (when (or (not (file-exists-p newname)) + (yes-or-no-p + (format "Target file %s exists; proceed? " newname))) + (when (file-exists-p buffer-file-name) + (rename-file buffer-file-name newname t)) + (set-visited-file-name newname)))) + (?b (save-excursion + (goto-char name-start) + (delete-region name-start name-end) + (insert file))))))))) (defun octave-update-function-file-comment (beg end) "Query replace function names in function file comment." @@ -1801,19 +1801,19 @@ octave-find-definition-filename-function (defun octave-find-definition-default-filename (name) "Default value for `octave-find-definition-filename-function'." (pcase (file-name-extension name) - (`"oct" + ("oct" (octave-find-definition-default-filename (concat "libinterp/dldfcn/" (file-name-sans-extension (file-name-nondirectory name)) ".cc"))) - (`"cc" + ("cc" (let ((file (or (locate-file name (octave-source-directories)) (locate-file (file-name-nondirectory name) (octave-source-directories))))) (or (and file (file-exists-p file)) (error "File `%s' not found" name)) file)) - (`"mex" + ("mex" (if (yes-or-no-p (format-message "File `%s' may be binary; open? " (file-name-nondirectory name))) name diff --git a/lisp/progmodes/opascal.el b/lisp/progmodes/opascal.el index 4606621951..7d055b735d 100644 --- a/lisp/progmodes/opascal.el +++ b/lisp/progmodes/opascal.el @@ -393,17 +393,17 @@ opascal-literal-kind (if (null (nth 8 ppss)) (when (looking-at opascal--literal-start-re) (pcase (char-after) - (`?/ 'comment-single-line) - (`?\{ 'comment-multi-line-1) - (`?\( 'comment-multi-line-2) - (`?\' 'string) - (`?\" 'double-quoted-string))) + (?/ 'comment-single-line) + (?\{ 'comment-multi-line-1) + (?\( 'comment-multi-line-2) + (?\' 'string) + (?\" 'double-quoted-string))) (if (nth 3 ppss) ;String. (if (eq (nth 3 ppss) ?\") 'double-quoted-string 'string) (pcase (nth 7 ppss) - (`2 'comment-single-line) - (`1 'comment-multi-line-2) + (2 'comment-single-line) + (1 'comment-multi-line-2) (_ 'comment-multi-line-1)))))))) (defun opascal-literal-start-pattern (literal-kind) diff --git a/lisp/progmodes/perl-mode.el b/lisp/progmodes/perl-mode.el index b96aad7a6e..a61d1adcb7 100644 --- a/lisp/progmodes/perl-mode.el +++ b/lisp/progmodes/perl-mode.el @@ -323,8 +323,8 @@ perl-syntax-propertize-function (cons (car (string-to-syntax "< c")) ;; Remember the names of heredocs found on this line. (cons (cons (pcase (aref name 0) - (`?\\ (substring name 1)) - ((or `?\" `?\' `?\`) (substring name 1 -1)) + (?\\ (substring name 1)) + ((or ?\" ?\' ?\`) (substring name 1 -1)) (_ name)) indented) (cdr st))))))) diff --git a/lisp/progmodes/prolog.el b/lisp/progmodes/prolog.el index 3bcc9bebcd..b530c61f97 100644 --- a/lisp/progmodes/prolog.el +++ b/lisp/progmodes/prolog.el @@ -954,9 +954,9 @@ prolog-smie-rules ;; -> thenrule ;; ; elserule ;; ) - (`(:before . ,(or `"->" `";")) + (`(:before . ,(or "->" ";")) (and (smie-rule-bolp) (smie-rule-parent-p "(") (smie-rule-parent 0))) - (`(:after . ,(or `"->" `"*->")) + (`(:after . ,(or "->" "*->")) ;; We distinguish ;; ;; (a -> @@ -3247,11 +3247,11 @@ prolog-electric--underscore (defun prolog-post-self-insert () (pcase last-command-event - (`?_ (prolog-electric--underscore)) - (`?- (prolog-electric--dash)) - (`?: (prolog-electric--colon)) - ((or `?\( `?\; `?>) (prolog-electric--if-then-else)) - (`?. (prolog-electric--dot)))) + (?_ (prolog-electric--underscore)) + (?- (prolog-electric--dash)) + (?: (prolog-electric--colon)) + ((or ?\( ?\; ?>) (prolog-electric--if-then-else)) + (?. (prolog-electric--dot)))) (defun prolog-find-term (functor arity &optional prefix) "Go to the position at the start of the next occurrence of a term. diff --git a/lisp/progmodes/ruby-mode.el b/lisp/progmodes/ruby-mode.el index fad7bc1fb8..32130cee8e 100644 --- a/lisp/progmodes/ruby-mode.el +++ b/lisp/progmodes/ruby-mode.el @@ -612,7 +612,7 @@ ruby-smie-rules ;; For (invalid) code between switch and case. ;; (if (smie-parent-p "switch") 4) )) - (`(:before . ,(or `"(" `"[" `"{")) + (`(:before . ,(or "(" "[" "{")) (cond ((and (equal token "{") (not (smie-rule-prev-p "(" "{" "[" "," "=>" "=" "return" ";")) @@ -639,7 +639,7 @@ ruby-smie-rules (forward-char -1)) (smie-indent-virtual)) (t (smie-rule-parent)))))) - (`(:after . ,(or `"(" "[" "{")) + (`(:after . ,(or "(" "[" "{")) ;; FIXME: Shouldn't this be the default behavior of ;; `smie-indent-after-keyword'? (save-excursion @@ -660,7 +660,7 @@ ruby-smie-rules (smie-backward-sexp ".") (cons 'column (+ (current-column) ruby-indent-level)))) - (`(:before . ,(or `"else" `"then" `"elsif" `"rescue" `"ensure")) + (`(:before . ,(or "else" "then" "elsif" "rescue" "ensure")) (smie-rule-parent)) (`(:before . "when") ;; Align to the previous `when', but look up the virtual @@ -1544,8 +1544,8 @@ ruby-backward-sexp (cond ((looking-at "\\s)") (goto-char (scan-sexps (1+ (point)) -1)) (pcase (char-before) - (`?% (forward-char -1)) - ((or `?q `?Q `?w `?W `?r `?x) + (?% (forward-char -1)) + ((or ?q ?Q ?w ?W ?r ?x) (if (eq (char-before (1- (point))) ?%) (forward-char -2)))) nil) @@ -1562,13 +1562,13 @@ ruby-backward-sexp (forward-char 1) (while (progn (forward-word-strictly -1) (pcase (char-before) - (`?_ t) - (`?. (forward-char -1) t) - ((or `?$ `?@) + (?_ t) + (?. (forward-char -1) t) + ((or ?$ ?@) (forward-char -1) (and (eq (char-before) (char-after)) (forward-char -1))) - (`?: + (?: (forward-char -1) (eq (char-before) :))))) (if (looking-at ruby-block-end-re) diff --git a/lisp/progmodes/sh-script.el b/lisp/progmodes/sh-script.el index aaa86b5816..46c9e6ee65 100644 --- a/lisp/progmodes/sh-script.el +++ b/lisp/progmodes/sh-script.el @@ -959,8 +959,8 @@ sh--inside-noncommand-expression ;; ((...)) or $((...)) or $[...] or ${...}. Nested ;; parenthesis can occur inside the first of these forms, so ;; parse backward recursively. - (`?\( (eq ?\( (char-before))) - ((or `?\{ `?\[) (eq ?\$ (char-before)))) + (?\( (eq ?\( (char-before))) + ((or ?\{ ?\[) (eq ?\$ (char-before)))) (sh--inside-noncommand-expression (1- (point)))))))) (defun sh-font-lock-open-heredoc (start string eol) @@ -2038,7 +2038,7 @@ sh-smie-sh-rules (`(:elem . basic) sh-basic-offset) (`(:after . "case-)") (- (sh-var-value 'sh-indent-for-case-alt) (sh-var-value 'sh-indent-for-case-label))) - (`(:before . ,(or `"(" `"{" `"[" "while" "if" "for" "case")) + (`(:before . ,(or "(" "{" "[" "while" "if" "for" "case")) (if (not (smie-rule-prev-p "&&" "||" "|")) (when (smie-rule-hanging-p) (smie-rule-parent)) @@ -2047,11 +2047,11 @@ sh-smie-sh-rules `(column . ,(smie-indent-virtual))))) ;; FIXME: Maybe this handling of ;; should be made into ;; a smie-rule-terminator function that takes the substitute ";" as arg. - (`(:before . ,(or `";;" `";&" `";;&")) + (`(:before . ,(or ";;" ";&" ";;&")) (if (and (smie-rule-bolp) (looking-at ";;?&?[ \t]*\\(#\\|$\\)")) (cons 'column (smie-indent-keyword ";")) (smie-rule-separator kind))) - (`(:after . ,(or `";;" `";&" `";;&")) + (`(:after . ,(or ";;" ";&" ";;&")) (with-demoted-errors (smie-backward-sexp token) (cons 'column @@ -2062,7 +2062,7 @@ sh-smie-sh-rules (smie-rule-bolp)))) (current-column) (smie-indent-calculate))))) - (`(:before . ,(or `"|" `"&&" `"||")) + (`(:before . ,(or "|" "&&" "||")) (unless (smie-rule-parent-p token) (smie-backward-sexp token) `(column . ,(+ (funcall smie-rules-function :elem 'basic) @@ -2081,7 +2081,7 @@ sh-smie-sh-rules ;; sh-indent-after-done: aligned completely differently. (`(:after . "in") (sh-var-value 'sh-indent-for-case-label)) ;; sh-indent-for-continuation: Line continuations are handled differently. - (`(:after . ,(or `"(" `"{" `"[")) + (`(:after . ,(or "(" "{" "[")) (if (not (looking-at ".[ \t]*[^\n \t#]")) (sh-var-value 'sh-indent-after-open) (goto-char (1- (match-end 0))) @@ -2253,7 +2253,7 @@ sh-smie-rc-rules (save-excursion (when (sh-smie--rc-after-special-arg-p) `(column . ,(current-column))))) - (`(:before . ,(or `"(" `"{" `"[")) + (`(:before . ,(or "(" "{" "[")) (if (smie-rule-hanging-p) (smie-rule-parent))) ;; FIXME: SMIE parses "if (exp) cmd" as "(if ((exp) cmd))" so "cmd" is ;; treated as an arg to (exp) by default, which indents it all wrong. @@ -2262,7 +2262,7 @@ sh-smie-rc-rules ;; rule we have is the :list-intro hack, which we use here to align "cmd" ;; with "(exp)", which is rarely the right thing to do, but is better ;; than nothing. - (`(:list-intro . ,(or `"for" `"if" `"while")) t) + (`(:list-intro . ,(or "for" "if" "while")) t) ;; sh-indent-after-switch: handled implicitly by the default { rule. )) diff --git a/lisp/server.el b/lisp/server.el index 50684a20aa..d0a8ca313e 100644 --- a/lisp/server.el +++ b/lisp/server.el @@ -1112,16 +1112,16 @@ server-execute-continuation (while args-left (pcase (pop args-left) ;; -version CLIENT-VERSION: obsolete at birth. - (`"-version" (pop args-left)) + ("-version" (pop args-left)) ;; -nowait: Emacsclient won't wait for a result. - (`"-nowait" (setq nowait t)) + ("-nowait" (setq nowait t)) ;; -current-frame: Don't create frames. - (`"-current-frame" (setq use-current-frame t)) + ("-current-frame" (setq use-current-frame t)) ;; -frame-parameters: Set frame parameters - (`"-frame-parameters" + ("-frame-parameters" (let ((alist (pop args-left))) (if coding-system (setq alist (decode-coding-string alist coding-system))) @@ -1129,24 +1129,24 @@ server-execute-continuation ;; -display DISPLAY: ;; Open X frames on the given display instead of the default. - (`"-display" + ("-display" (setq display (pop args-left)) (if (zerop (length display)) (setq display nil))) ;; -parent-id ID: ;; Open X frame within window ID, via XEmbed. - (`"-parent-id" + ("-parent-id" (setq parent-id (pop args-left)) (if (zerop (length parent-id)) (setq parent-id nil))) ;; -window-system: Open a new X frame. - (`"-window-system" + ("-window-system" (if (fboundp 'x-create-frame) (setq dontkill t tty-name 'window-system))) ;; -resume: Resume a suspended tty frame. - (`"-resume" + ("-resume" (let ((terminal (process-get proc 'terminal))) (setq dontkill t) (push (lambda () @@ -1157,7 +1157,7 @@ server-execute-continuation ;; -suspend: Suspend the client's frame. (In case we ;; get out of sync, and a C-z sends a SIGTSTP to ;; emacsclient.) - (`"-suspend" + ("-suspend" (let ((terminal (process-get proc 'terminal))) (setq dontkill t) (push (lambda () @@ -1167,13 +1167,13 @@ server-execute-continuation ;; -ignore COMMENT: Noop; useful for debugging emacsclient. ;; (The given comment appears in the server log.) - (`"-ignore" + ("-ignore" (setq dontkill t) (pop args-left)) ;; -tty DEVICE-NAME TYPE: Open a new tty frame. ;; (But if we see -window-system later, use that.) - (`"-tty" + ("-tty" (setq tty-name (pop args-left) tty-type (pop args-left) dontkill (or dontkill @@ -1192,7 +1192,7 @@ server-execute-continuation ;; -position LINE[:COLUMN]: Set point to the given ;; position in the next file. - (`"-position" + ("-position" (if (not (string-match "\\+\\([0-9]+\\)\\(?::\\([0-9]+\\)\\)?" (car args-left))) (error "Invalid -position command in client args")) @@ -1203,7 +1203,7 @@ server-execute-continuation "")))))) ;; -file FILENAME: Load the given file. - (`"-file" + ("-file" (let ((file (pop args-left))) (if coding-system (setq file (decode-coding-string file coding-system))) @@ -1221,7 +1221,7 @@ server-execute-continuation (setq filepos nil)) ;; -eval EXPR: Evaluate a Lisp expression. - (`"-eval" + ("-eval" (if use-current-frame (setq use-current-frame 'always)) (let ((expr (pop args-left))) @@ -1232,14 +1232,14 @@ server-execute-continuation (setq filepos nil))) ;; -env NAME=VALUE: An environment variable. - (`"-env" + ("-env" (let ((var (pop args-left))) ;; XXX Variables should be encoded as in getenv/setenv. (process-put proc 'env (cons var (process-get proc 'env))))) ;; -dir DIRNAME: The cwd of the emacsclient process. - (`"-dir" + ("-dir" (setq dir (pop args-left)) (if coding-system (setq dir (decode-coding-string dir coding-system))) diff --git a/lisp/subr.el b/lisp/subr.el index 41dc9aa45f..aaf8909e0c 100644 --- a/lisp/subr.el +++ b/lisp/subr.el @@ -4815,7 +4815,7 @@ called-interactively-p i frame nextframe))) (pcase skip (`nil nil) - (`0 t) + (0 t) (_ (setq i (+ i skip -1)) (funcall get-next-frame))))))) ;; Now `frame' should be "the function from which we were called". (pcase (cons frame nextframe) diff --git a/lisp/textmodes/css-mode.el b/lisp/textmodes/css-mode.el index 31ce638b31..63c86317ee 100644 --- a/lisp/textmodes/css-mode.el +++ b/lisp/textmodes/css-mode.el @@ -1219,7 +1219,7 @@ css-smie-rules (`(:elem . basic) css-indent-offset) (`(:elem . arg) 0) ;; "" stands for BOB (bug#15467). - (`(:list-intro . ,(or `";" `"" `":-property")) t) + (`(:list-intro . ,(or ";" "" ":-property")) t) (`(:before . "{") (when (or (smie-rule-hanging-p) (smie-rule-bolp)) (smie-backward-sexp ";") diff --git a/test/lisp/emacs-lisp/pcase-tests.el b/test/lisp/emacs-lisp/pcase-tests.el index 774a488255..c706c1051e 100644 --- a/test/lisp/emacs-lisp/pcase-tests.el +++ b/test/lisp/emacs-lisp/pcase-tests.el @@ -53,7 +53,7 @@ pcase-tests-grep (should (pcase-tests-grep 'memq (macroexpand-all '(pcase x ((or 1 2 3) body))))) (should (pcase-tests-grep - 'member (macroexpand-all '(pcase x ((or '"a" '2 '3) body))))) + 'member (macroexpand-all '(pcase x ((or "a" 2 3) body))))) (should-not (pcase-tests-grep 'memq (macroexpand-all '(pcase x ((or "a" 2 3) body))))) (let ((exp (macroexpand-all -- 2.19.1 [-- Attachment #3: Type: text/plain, Size: 23 bytes --] Thanks, Michael. ^ permalink raw reply related [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-27 15:19 ` Michael Heerdegen @ 2018-10-27 16:56 ` Garreau, Alexandre 2018-10-27 22:37 ` Dmitry Gutov 2018-10-29 3:26 ` Replace trivial pcase occurrences in the Emacs sources Eli Zaretskii 2 siblings, 0 replies; 375+ messages in thread From: Garreau, Alexandre @ 2018-10-27 16:56 UTC (permalink / raw) To: Michael Heerdegen; +Cc: Eli Zaretskii, Stefan Monnier, emacs-devel On 2018-10-27 at 17:19, Michael Heerdegen wrote: > What's then left is the task to replace all pcase forms that can be > trivially rewritten by using case or cond/assoc. I must admit that > I'm very skeptical about this now. Not only that we would only > replace exactly these pcase occurrences that are really trivial to > read for anybody, which could be, at the end, counterproductive for > those people who dislike pcase because the pcase forms left are the > harder ones (Eli, I know you don't think like that). > > I also saw that people have very different likings, independent from > pcase. Say, we have one third of people who want to keep pcase in > these cases, one third who want to replace it with cl-case, and one > third who want cond or assoc instead. We have a clear majority > against pcase. But we also have a clear majority against cl-case, and > a majority against cond/assoc. First of all, on a practical ground, I’m not sure anything has been that democratic yet, or anybody has found a that-much democratic process to be useful (at least it is complex to, well, process)… But, as the question is raised, that recalls me a lot Arrow’s paradox: normally this is the moment I notice you that each one of these thirds may have a preference too about the two forms they dislike (or only like less; for instance I might be a fan of case but prefer cond and assoc to pcase (or the other way around)), so we might ask a list of preferences rather than a single preference, and Arrow’s paradox says this issue keep going as in the end the comparisons may be A > B > C > A. Fyi, one solution of this paradox, is to allow multiple equalities (such as giving preferences in the form A = B > C = D), and do a median rather than a average/direct-superiority-count-compare, or, in a more intuitive, developed and straightforward way: “in a ringle round, give a notation mark to each preference, then for each preference, take their median score, take the winner(s), and if several, the one who won by this score by more voices” (very unlikely to get equalities). More pretty interesting documentation on arrow paradox: <https://en.wikipedia.org/wiki/Arrow%27s_paradox> ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-27 15:19 ` Michael Heerdegen 2018-10-27 16:56 ` Garreau, Alexandre @ 2018-10-27 22:37 ` Dmitry Gutov 2018-10-28 0:21 ` Michael Heerdegen 2018-10-29 3:26 ` Replace trivial pcase occurrences in the Emacs sources Eli Zaretskii 2 siblings, 1 reply; 375+ messages in thread From: Dmitry Gutov @ 2018-10-27 22:37 UTC (permalink / raw) To: Michael Heerdegen, Eli Zaretskii; +Cc: Stefan Monnier, emacs-devel On 27.10.2018 18:19, Michael Heerdegen wrote: > Say, we have one third of people who want to keep pcase in these > cases, one third who want to replace it with cl-case, and one third who > want cond or assoc instead. We have a clear majority against pcase. > But we also have a clear majority against cl-case, and a majority > against cond/assoc. We could also assume that the silent majority is okay with the way things are. For example, I like pcase, even if more complex cases might look cryptic. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-27 22:37 ` Dmitry Gutov @ 2018-10-28 0:21 ` Michael Heerdegen 2018-10-28 2:07 ` Garreau, Alexandre 0 siblings, 1 reply; 375+ messages in thread From: Michael Heerdegen @ 2018-10-28 0:21 UTC (permalink / raw) To: Dmitry Gutov; +Cc: Eli Zaretskii, Stefan Monnier, emacs-devel Dmitry Gutov <dgutov@yandex.ru> writes: > We could also assume that the silent majority is okay with the way > things are. For example, I like pcase, even if more complex cases > might look cryptic. I also like it, and your assumption could be true. Who knows. Pcase was a big improvement to what can be expressed with Elisp. And I think its syntax and semantics are quite straightforward. I doubt we will find something more simplistic that has the same power. Probably the main problem was that the documentation was originally written in a quite terse academic style. Also, the recursive nature of ` that makes it possible to combine it with all other patter types is hard to get, but also very natural and powerful. It's just consistent that when backquote is used to construct complicated lists, it is also used to build complex patterns to match such lists. Nonetheless it seems that ` is one of the main reasons for the bad feelings some people have about pcase. Michael. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-28 0:21 ` Michael Heerdegen @ 2018-10-28 2:07 ` Garreau, Alexandre 2018-10-28 2:44 ` pcase ` meaning [Was: Re: Replace trivial pcase occurrences in the Emacs sources] Garreau, Alexandre 0 siblings, 1 reply; 375+ messages in thread From: Garreau, Alexandre @ 2018-10-28 2:07 UTC (permalink / raw) To: Michael Heerdegen Cc: Eli Zaretskii, emacs-devel, Stefan Monnier, Dmitry Gutov On 2018-10-28 at 02:21, Michael Heerdegen wrote: > Dmitry Gutov <dgutov@yandex.ru> writes: > >> We could also assume that the silent majority is okay with the way >> things are. For example, I like pcase, even if more complex cases >> might look cryptic. > > I also like it, and your assumption could be true. Who knows. > > Pcase was a big improvement to what can be expressed with Elisp. And I > think its syntax and semantics are quite straightforward. I doubt we > will find something more simplistic that has the same power. > > Probably the main problem was that the documentation was originally > written in a quite terse academic style. Also, the recursive nature of > ` that makes it possible to combine it with all other patter types is > hard to get, but also very natural and powerful. It's just consistent > that when backquote is used to construct complicated lists, it is also > used to build complex patterns to match such lists. Nonetheless it > seems that ` is one of the main reasons for the bad feelings some people > have about pcase. Isn’t ` needed in just the same cases you could as well use guard or predefined patterns? when you need to eval things? If there is some redundance or covering between both, maybe ` could be avoided so it confuses less? ^ permalink raw reply [flat|nested] 375+ messages in thread
* pcase ` meaning [Was: Re: Replace trivial pcase occurrences in the Emacs sources] 2018-10-28 2:07 ` Garreau, Alexandre @ 2018-10-28 2:44 ` Garreau, Alexandre 2018-10-28 4:45 ` How other pattern-matching lisps do [Was: Re: pcase ` meaning [Was: Re: Replace trivial pcase occurrences in the Emacs sources]] Garreau, Alexandre 2018-10-28 22:54 ` pcase ` meaning [Was: Re: Replace trivial pcase occurrences in the Emacs sources] Michael Heerdegen 0 siblings, 2 replies; 375+ messages in thread From: Garreau, Alexandre @ 2018-10-28 2:44 UTC (permalink / raw) To: Michael Heerdegen Cc: Eli Zaretskii, Dmitry Gutov, Stefan Monnier, emacs-devel On 2018-10-28 at 03:07, Garreau, Alexandre wrote: > On 2018-10-28 at 02:21, Michael Heerdegen wrote: >> Dmitry Gutov <dgutov@yandex.ru> writes: >> >>> We could also assume that the silent majority is okay with the way >>> things are. For example, I like pcase, even if more complex cases >>> might look cryptic. >> >> I also like it, and your assumption could be true. Who knows. >> >> Pcase was a big improvement to what can be expressed with Elisp. And I >> think its syntax and semantics are quite straightforward. I doubt we >> will find something more simplistic that has the same power. >> >> Probably the main problem was that the documentation was originally >> written in a quite terse academic style. Also, the recursive nature of >> ` that makes it possible to combine it with all other patter types is >> hard to get, but also very natural and powerful. It's just consistent >> that when backquote is used to construct complicated lists, it is also >> used to build complex patterns to match such lists. Nonetheless it >> seems that ` is one of the main reasons for the bad feelings some people >> have about pcase. > > Isn’t ` needed in just the same cases you could as well use guard or > predefined patterns? when you need to eval things? If there is some > redundance or covering between both, maybe ` could be avoided so it > confuses less? Nevermind, I just discovered that normally rar ` is mandatory for the main use case of pcase, pattern matching, which I find weird. So its normal syntax is what case should be, and its ` syntax is what pcase should be. Initially I expected this would have worked the same: #+BEGIN_SRC emacs-lisp (defun evaluate (exp env) (pcase exp (('add x y) (+ (evaluate x env) (evaluate y env))) (('call fun arg) (funcall (evaluate fun env) (evaluate arg env))) (('fn arg body) (lambda (val) (evaluate body (cons (cons arg val) env)))) ((pred numberp) exp) ((pred symbolp) (cdr (assq exp env))) (_ (error "Unknown expression %S" exp)))) #+END_SRC because intuitively, I thought what would apply to a raw top-level atom, would apply to it as a component of a sequence, but it seem I’m wrong. Which indeed is unreasonable, as it is incompatible with pcase non-pattern-matching own mini-language, which strangely seems to be more important to pcase than pattern matching. So know I understand why advocating for replacing case with pcase: pcase is not about pattern matching, it is just a correctly working case, except it only works for atoms, with an optional prevailing mini-language, and even more optional, additive and not straightforward pattern matching. Maybe that would make more sense if ` (and '?) were not part of pcase’s own mini-language, redefined by pcase, but if pcase actually truly eval’d its pattern, defining pred, guard, etc. as real functions, defined with a cl-letf, using lexical scoping so to prevailably define all these + user-defined patterns. But even then, “,” I feel like would barely make sense… it’s used the same way, but doesn’t mean the same thing. It doesn’t mean “eval”, as the thing after “,”, if not a function call, might be something not bound to a value, so it only means “undo the ‘`’, do like I didn’t do it”, which is inconsistent with general use of “`”. When seeing “,var”, I’m thinking “the actual value of var, or an error”, so as I don’t see var defined anywere, I feel like an error is coming, and as I know none is coming, I feel something is wrong. I don’t see how to eval ,var without getting an error, except by redefining how to eval, or rather how to get a symbol value. It even more feel wrong that, this, doesn’t work, for no reason (it can’t be incompatible with the minilanguage): #+BEGIN_SRC emacs-lisp (pcase [1 2] ([a b] (+ a b))) #+END_SRC Yet that’s the most intuitive and straightforward way of using pattern matching. ^ permalink raw reply [flat|nested] 375+ messages in thread
* How other pattern-matching lisps do [Was: Re: pcase ` meaning [Was: Re: Replace trivial pcase occurrences in the Emacs sources]] 2018-10-28 2:44 ` pcase ` meaning [Was: Re: Replace trivial pcase occurrences in the Emacs sources] Garreau, Alexandre @ 2018-10-28 4:45 ` Garreau, Alexandre 2018-10-28 13:44 ` Stefan Monnier 2018-10-28 23:16 ` Michael Heerdegen 2018-10-28 22:54 ` pcase ` meaning [Was: Re: Replace trivial pcase occurrences in the Emacs sources] Michael Heerdegen 1 sibling, 2 replies; 375+ messages in thread From: Garreau, Alexandre @ 2018-10-28 4:45 UTC (permalink / raw) To: Michael Heerdegen Cc: Eli Zaretskii, emacs-devel, Stefan Monnier, Dmitry Gutov On 2018-10-28 at 03:44, Garreau, Alexandre wrote: > Initially I expected this would have worked […] > > #+BEGIN_SRC emacs-lisp > (defun evaluate (exp env) > (pcase exp > (('add x y) (+ (evaluate x env) (evaluate y env))) > (('call fun arg) (funcall (evaluate fun env) (evaluate arg env))) > (('fn arg body) (lambda (val) > (evaluate body (cons (cons arg val) env)))) > ((pred numberp) exp) > ((pred symbolp) (cdr (assq exp env))) > (_ (error "Unknown expression %S" exp)))) > #+END_SRC > > […] > > It even more feel wrong that, this, doesn’t work, for no reason (it > can’t be incompatible with the minilanguage): > > #+BEGIN_SRC emacs-lisp > (pcase [1 2] > ([a b] (+ a b))) > #+END_SRC > > Yet that’s the most intuitive and straightforward way of using pattern > matching. Okay, so I went to search what is done in other pattern matching lisp form. The closer, yet quite straightforward, implementation of pattern matching I found is the one found in Guile [0], claimed to be used in most scheme implementation, which supports as well quasiquoting, but also raw lists and vectors, because, according its manual: > The names ‘quote’, ‘quasiquote’, ‘unquote’, ‘unquote-splicing’, ‘?’, > ‘_’, ‘$’, ‘and’, ‘or’, ‘not’, ‘set!’, ‘get!’, ‘...’, and ‘___’ cannot > be used as pattern variables. As you can see, it also supports `not', and some facilities for OOP. I also found a cl library named cl-match [1], which also use its minilanguage by default (but doesn’t support backquotes), so its solution stays compatible: it uses sequences constructors such as “cons”, “list”, “list*” (improper lists), or “array”/“vec” as patterns: #+BEGIN_SRC lisp (match (list 1 2) ((list x y) (+ x y))) #+END_SRC It has several interesting forms pcase doesn’t seem to have (at least not documented): such as “(as binding pattern)”, which matches `pattern', and binds it to `binding' (so you can keep a binding though binding subelement of it), or “(type type &optional pattern)” for matching if it’s a given type, also more specific (hence semantic) and shorter and simpler than “(and (pred typep) &optional pattern)”. Then all other cl implementations I found (named either “match”, either “unify”: the later is commutative, the former not) doesn’t do real successive pattern matching, but simple destructuring (without `and', `or', guards, or any minilanguage), yet unlike cl-destructuring-bind, in a simpler way (without lambda-list-like arguments), and rather than erroring out (making it unsuitable to successive tries of pattern matching), they return either an environment, or something such as 'fail. So it can be trivially used to make successive pattern-matching. Going in this direction there’s first optima [2], which of course match raw lists and such by default, but also have really interesting special patterns, such as “(places symbol)”, that will bind to symbol, but using symbol-macrolet, so that setf/cl-letf will work, or `(assoc 1 alist-pattern)' (so “(match '((1 . 2)) ((assoc 1 x) x))” returns 2), to match content of an alist, or “property” for plists. There are some others, generally a subset of what I described until then, such as cl-unification [3]. One of these, the simpler I found, is one I found in an lisp files archive annex [4] of a book that wasn’t freely available online /Lisp, Third Edition/: it doesn’t appear to be free software, but it’s trivial to understand: what it does is just match recursively plain conses (hence lists), not even arrays or string, since it does eql on anything else (just as case already wrongly do: what’s this fear of equal in common lisp?), but it uses the special list (? symbol) to bind symbols. Simply replacing “'?” per “'var”, make it work in emacs-lisp, but as it is not free there’s little interest in doing so. In the end, I believe, before to even support arbitrary lists for when the car is not a predefined pattern, it would be handy to support constructors (hence simple new predefined patterns) such as “list” or “vector”/“array”, that would make possible to remove all the confusing backquotes. However something such as (pcase-defmacro list (&rest args) ``(,@args)) (nor (pcase-defmacro list (&rest args) `(cons 'list args))) wouldn’t work because multiple backquotes doesn’t seem to work. [0] (info "(guile) Pattern Matching") [1] https://common-lisp.net/project/cl-match/doc/clmatch-api.htm [2] https://github.com/m2ym/optima [3] https://common-lisp.net/project/cl-unification/ [4] http://people.csail.mit.edu/phw/Books/lisp.zip ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: How other pattern-matching lisps do [Was: Re: pcase ` meaning [Was: Re: Replace trivial pcase occurrences in the Emacs sources]] 2018-10-28 4:45 ` How other pattern-matching lisps do [Was: Re: pcase ` meaning [Was: Re: Replace trivial pcase occurrences in the Emacs sources]] Garreau, Alexandre @ 2018-10-28 13:44 ` Stefan Monnier 2018-10-28 17:57 ` Garreau, Alexandre 2018-10-28 23:16 ` Michael Heerdegen 1 sibling, 1 reply; 375+ messages in thread From: Stefan Monnier @ 2018-10-28 13:44 UTC (permalink / raw) To: emacs-devel > Okay, so I went to search what is done in other pattern matching lisp > form. You missed Racket's `match` (https://docs.racket-lang.org/reference/match.html) Incidentally, I also missed it when I did the same search you did before embarking on the design and implementation of pcase. I later found Racket's `match` which was pretty close to the original design of pcase, but showed me how to add `pcase-defmacro` (mostly by adding the `app` pattern), which led to the "new pcase" where ` is a macro (and where ' was added for that macro to have something to expand to). The current `pcase` is pretty close to Racket's `match`. The main missing functionality is the negation, which Racket solves "easily" because its underlying language handles lambda much more efficiently (i.e. the code generated by `match` would work very poorly in Elisp unless we significantly improved the byte-compiler's handling of funcall). Stefan ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: How other pattern-matching lisps do [Was: Re: pcase ` meaning [Was: Re: Replace trivial pcase occurrences in the Emacs sources]] 2018-10-28 13:44 ` Stefan Monnier @ 2018-10-28 17:57 ` Garreau, Alexandre 0 siblings, 0 replies; 375+ messages in thread From: Garreau, Alexandre @ 2018-10-28 17:57 UTC (permalink / raw) To: Stefan Monnier; +Cc: emacs-devel On 2018-10-28 at 09:44, Stefan Monnier wrote: >> Okay, so I went to search what is done in other pattern matching lisp >> form. > > You missed Racket's `match` (https://docs.racket-lang.org/reference/match.html) Indeed! Thank you! I missed it because when reading guile reference (incidentelly already installed on my system, while I don’t even know if racket’s is installable as info, pdf, man or even html here), I naively thought if it said most schemes used the same, racket would too. And indeed, it seems pretty compatible, beside being interestingly way richer, having the `list', `vector', etc. patterns I found in cl-match… and I’m very happy the `var' I made out of “Lisp, 3rd ed” book annex I found happen to be just the same, compatible with racket: this easily paliates for binding all constructs which aren’t bindable in guile’s match (“((var list) foo)” to bind the symbol “list” as a first element). > Incidentally, I also missed it when I did the same search you did before > embarking on the design and implementation of pcase. I later found > Racket's `match` which was pretty close to the original design of pcase, > but showed me how to add `pcase-defmacro` (mostly by adding the `app` > pattern), which led to the "new pcase" where ` is a macro (and where > ' was added for that macro to have something to expand to). What was is initially? non-existing? > The current `pcase` is pretty close to Racket's `match`. The main > missing functionality is the negation, In terms of powerfulness, however, to come back to original discussion: confusion. The presence of type constructors (`list', `array'), the fact lists and arrays, otherwise (if not matching a defined pattern) work out of the box, and the `var' form, allow, if needed, to completely avoid the “`” syntax. And to me it’s like it appear that this syntax is confusing quite some people (and I understand why, except when in ,(foo) `foo' is a defined pattern, so it’s look like a function call). So avoiding this syntax in source code could be handy so to give a better image to pcase, which would understood more easily. > which Racket solves "easily" because its underlying language handles > lambda much more efficiently (i.e. the code generated by `match` would > work very poorly in Elisp unless we significantly improved the > byte-compiler's handling of funcall). From what I feel sometimes scheme’s byte-compiler are pretty handy, maybe less than some cl compilers, but… well maybe it is only that elisp byte-compiler doesn’t do that much, does it? ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: How other pattern-matching lisps do [Was: Re: pcase ` meaning [Was: Re: Replace trivial pcase occurrences in the Emacs sources]] 2018-10-28 4:45 ` How other pattern-matching lisps do [Was: Re: pcase ` meaning [Was: Re: Replace trivial pcase occurrences in the Emacs sources]] Garreau, Alexandre 2018-10-28 13:44 ` Stefan Monnier @ 2018-10-28 23:16 ` Michael Heerdegen 1 sibling, 0 replies; 375+ messages in thread From: Michael Heerdegen @ 2018-10-28 23:16 UTC (permalink / raw) To: Garreau, Alexandre Cc: Eli Zaretskii, emacs-devel, Stefan Monnier, Dmitry Gutov "Garreau, Alexandre" <galex-713@galex-713.eu> writes: > As you can see, it also supports `not', and some facilities for OOP. BTW, el-search supports `not'. AFAIK it would be trivial to add `not' to pcase, but Stefan wants to wait for an idea of how to do so efficiently. > or `(assoc 1 alist-pattern)' (so “(match '((1 . 2)) ((assoc 1 x) x))” > returns 2), to match content of an alist, or “property” for plists. Oh, there are some emacs libraries you need to load to get corresponding pcase macros. For example these: -- (eieio &rest FIELDS) Pcase patterns that match EIEIO object EXPVAL. -- (seq &rest PATTERNS) Build a `pcase' pattern that matches elements of SEQUENCE. -- (rx &rest REGEXPS) Build a `pcase' pattern matching `rx' REGEXPS in sexp form. -- (cl-struct TYPE &rest FIELDS) Pcase patterns that match cl-struct EXPVAL of type TYPE. -- (radix-tree-leaf VPAT) Build a `pcase' pattern that matches radix-tree leaf EXPVAL. VPAT is a `pcase' pattern to extract the value. -- (map &rest ARGS) Build a `pcase' pattern matching map elements. The last one supports matching alists conveniently. > However something such as (pcase-defmacro list (&rest args) ``(,@args)) The normal backquote macro recursively handles also the backquotes and unquotes that are meant for pcase, so you must avoid unwanted processing. I would write it as #+begin_src emacs-lisp (pcase-defmacro list (&rest args) `(,'\` ,(mapcar (lambda (thing) `(,'\, ,thing)) args))) #+end_src BTW, if you load "el-search-x.el", there is an `l' pattern defined, also for matching lists, which also avoids ``' but has a completely different semantics: it's more inspired by grep patterns, with the goal of allowing to use very short input to find function definitions and such. Michael. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: pcase ` meaning [Was: Re: Replace trivial pcase occurrences in the Emacs sources] 2018-10-28 2:44 ` pcase ` meaning [Was: Re: Replace trivial pcase occurrences in the Emacs sources] Garreau, Alexandre 2018-10-28 4:45 ` How other pattern-matching lisps do [Was: Re: pcase ` meaning [Was: Re: Replace trivial pcase occurrences in the Emacs sources]] Garreau, Alexandre @ 2018-10-28 22:54 ` Michael Heerdegen 2018-10-28 23:09 ` Garreau, Alexandre 1 sibling, 1 reply; 375+ messages in thread From: Michael Heerdegen @ 2018-10-28 22:54 UTC (permalink / raw) To: Garreau, Alexandre Cc: Eli Zaretskii, Dmitry Gutov, Stefan Monnier, emacs-devel "Garreau, Alexandre" <galex-713@galex-713.eu> writes: > So know I understand why advocating for replacing case with pcase: pcase > is not about pattern matching, it is just a correctly working case, > except it only works for atoms, with an optional prevailing > mini-language If you look at the definition of the ``' pcase macro you see that it is defined entirely in terms of the "things that only work for atoms" (it uses `app' on car and cdr). > Maybe that would make more sense if ` (and '?) were not part of pcase’s > own mini-language, redefined by pcase, but if pcase actually truly > eval’d its pattern, defining pred, guard, etc. as real functions, > defined with a cl-letf, using lexical scoping so to prevailably define > all these + user-defined patterns. I think it would also be an interesting approach. You would additionally need some magical thing that binds variables for the scope of the current clause, however. That doesn't fit into that simple approach. But not less than into pcase itself. I wonder if it could be similarly efficient as pcase. > It even more feel wrong that, this, doesn’t work, for no reason Well, there is a reason: it is wrong ;-) > #+BEGIN_SRC emacs-lisp > (pcase [1 2] > ([a b] (+ a b))) > #+END_SRC That should be #+begin_src emacs-lisp (pcase [1 2] (`[,a ,b] (+ a b))) #+end_src I'm sure you would have been able to find that after less than a minute when reading the pcase docstring. Michael. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: pcase ` meaning [Was: Re: Replace trivial pcase occurrences in the Emacs sources] 2018-10-28 22:54 ` pcase ` meaning [Was: Re: Replace trivial pcase occurrences in the Emacs sources] Michael Heerdegen @ 2018-10-28 23:09 ` Garreau, Alexandre 2018-10-28 23:57 ` Michael Heerdegen 2018-10-29 17:26 ` pcase ` meaning [Was: Re: Replace trivial pcase occurrences in the Emacs sources] Clément Pit-Claudel 0 siblings, 2 replies; 375+ messages in thread From: Garreau, Alexandre @ 2018-10-28 23:09 UTC (permalink / raw) To: Michael Heerdegen Cc: Eli Zaretskii, Dmitry Gutov, Stefan Monnier, emacs-devel Le 28/10/2018 à 23h54, Michael Heerdegen a écrit : > "Garreau, Alexandre" <galex-713@galex-713.eu> writes: >> Maybe that would make more sense if ` (and '?) were not part of pcase’s >> own mini-language, redefined by pcase, but if pcase actually truly >> eval’d its pattern, defining pred, guard, etc. as real functions, >> defined with a cl-letf, using lexical scoping so to prevailably define >> all these + user-defined patterns. > > I think it would also be an interesting approach. You would > additionally need some magical thing that binds variables for the scope > of the current clause, however. That doesn't fit into that simple > approach. But not less than into pcase itself. “(var name)”, as does racket and some common-lisp match/unify implementations. And so to integrate with “`”: “,(var name)” doesn’t disturb me, it is okay: will bind “name” to something, pretty straightforward. > I wonder if it could be similarly efficient as pcase. I’m almost sure it wouldn’t, or otherwise it would be awfully complex. But, if there were something to replace ` while not being counter-intuitive, I could live with ` not being efficient, but intuitive. >> It even more feel wrong that, this, doesn’t work, for no reason > > Well, there is a reason: it is wrong ;-) > >> #+BEGIN_SRC emacs-lisp >> (pcase [1 2] >> ([a b] (+ a b))) >> #+END_SRC > > That should be > > #+begin_src emacs-lisp > (pcase [1 2] > (`[,a ,b] (+ a b))) > #+end_src > > I'm sure you would have been able to find that after less than a minute > when reading the pcase docstring. I found that before sending the mail. But what I said I feel wrong, is that this is wrong, after current pcase rules. While it works for guile and racket match, as well as several common lisp match, with only some common-lisp match such as cl-match and optima as exceptions. What is confusing is [] can’t serve for the pattern language, so it feels wrong to disallow using it for pattern matching. Beside lisp, all pattern matching language make their feature serve one purpose: the pattern look like what the data should be. adding “`” and “,” destroy this feature, because the pattern no longer looks like what is matched. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: pcase ` meaning [Was: Re: Replace trivial pcase occurrences in the Emacs sources] 2018-10-28 23:09 ` Garreau, Alexandre @ 2018-10-28 23:57 ` Michael Heerdegen 2018-10-29 10:22 ` Garreau, Alexandre 2018-10-29 17:26 ` pcase ` meaning [Was: Re: Replace trivial pcase occurrences in the Emacs sources] Clément Pit-Claudel 1 sibling, 1 reply; 375+ messages in thread From: Michael Heerdegen @ 2018-10-28 23:57 UTC (permalink / raw) To: Garreau, Alexandre Cc: Eli Zaretskii, Dmitry Gutov, Stefan Monnier, emacs-devel "Garreau, Alexandre" <galex-713@galex-713.eu> writes: > “(var name)”, as does racket and some common-lisp match/unify > implementations. And so to integrate with “`”: “,(var name)” doesn’t > disturb me, it is okay: will bind “name” to something, pretty > straightforward. That would make totally sense to me. I often found it confusing that using a symbol which is already bound (outside of pcase) isn't turned into an equality test. Having an explicit `var' or `bind' for binding variables would be nice. > Beside lisp, all pattern matching language make their feature serve > one purpose: the pattern look like what the data should be. adding “`” > and “,” destroy this feature, because the pattern no longer looks like > what is matched. But with, for example, el-search, that suddenly looks very natural if you can, for example, transpose the first two arguments of all `foo' calls in your code with the rule. `(foo ,a ,b . ,rest) -> `(foo ,b ,a . ,rest) The pattern exactly looks like the matched data! Just with a different point of view. Using ``' is not what most people would naively use to implement destructuring, but I don't find it unnatural or not intuitive, no. The above pattern would look different if we would have to write it as `(foo ,(var a) ,(var b) . ,(var rest)) so the implicit binding feature of symbols also makes patterns much more readable in more complex cases, which is a big win. Michael. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: pcase ` meaning [Was: Re: Replace trivial pcase occurrences in the Emacs sources] 2018-10-28 23:57 ` Michael Heerdegen @ 2018-10-29 10:22 ` Garreau, Alexandre 2018-10-29 21:33 ` Michael Heerdegen 0 siblings, 1 reply; 375+ messages in thread From: Garreau, Alexandre @ 2018-10-29 10:22 UTC (permalink / raw) To: Michael Heerdegen Cc: Eli Zaretskii, Dmitry Gutov, Stefan Monnier, emacs-devel Le 29/10/2018 à 00h57, Michael Heerdegen a écrit : > "Garreau, Alexandre" <galex-713@galex-713.eu> writes: > >> “(var name)”, as does racket and some common-lisp match/unify >> implementations. And so to integrate with “`”: “,(var name)” doesn’t >> disturb me, it is okay: will bind “name” to something, pretty >> straightforward. > > That would make totally sense to me. I often found it confusing that > using a symbol which is already bound (outside of pcase) isn't turned > into an equality test. Having an explicit `var' or `bind' for binding > variables would be nice. Mmmh, that’s what I thought initially, and why I regretted cl-case didn’t eval its arguments, but in reality, neither pcase does, though it gives this impression, since it requires quoting symbols for equality. “var” is to make explicit bind variable bindings where it could not being done so otherwise, so to me ,(var name) looks less confusing, and, if lists and arrays out of the box matched lists and arrays, so that “(pcase (list 1 2 3) ((1 2 3) t))” was true, it would allow to bind a list first element when it’s also the name of a predefined pattern, like “(pcase (list 1 2 3) (((var and) 2 3) and))” would give “1” (it looks silly to use a such name for a variable, but we never know, and at least it makes pcase not unable to match some patterns (without ` I mean), like guile’s match). Also, as to speak about common pattern matching facilities, and how they make patterns look related to their match: all of them make normal, unbound identifier, lead to binding, instead of evaluation and replacement by their bound value. I (strangely, I realize no), see no facilities in pattern matching in non-lisp languages to match the value of an already bound variable… or am I wrong? do they allow that? Even in pcase I don’t see how to do that except manually using (and var (guard (equal var val))), which exactely looks like a cond, but more complex, embed in a, now uselessly complex pcase, which, then, defeat its purpose. And yet that’d been the behavior I’d imagine for ,var, in `, that’s why it’s confusing. However, I cannot suggest to change it to lead ,var to be evaluated to its value bound outside of pcase, because the way pcase bind ` seems to already be used by several other pattern matching facilities, so that’d break compatibility and bring confusion, too, sadly (maybe a definable pattern could change the default ` behavior, so people could experiment this behavior at least? yet their code could lead to confusion then). >> Beside lisp, all pattern matching language make their feature serve >> one purpose: the pattern look like what the data should be. adding “`” >> and “,” destroy this feature, because the pattern no longer looks like >> what is matched. > > But with, for example, el-search, that suddenly looks very natural if > you can, for example, transpose the first two arguments of all `foo' > calls in your code with the rule. > > `(foo ,a ,b . ,rest) -> `(foo ,b ,a . ,rest) No it doesn’t look natural: the transformation does, the reading is straightforward, the result is, but making the first pattern isn’t, because a and b aren’t bound to anything, so the “`” meaning is truly different (at least partially) than normal. > The pattern exactly looks like the matched data! Just with a different > point of view. Using ``' is not what most people would naively use to > implement destructuring, but I don't find it unnatural or not intuitive, > no. Afaik, the matched data, here, is “(foo <something> <something> . <something>)”, like “(foo 1 2 . 3)” (unquoted), or, when quoted “('foo 1 2 . 3)” (or “'(foo 1 2 . 3)” if you want, but if you ever changed to “`” here, you’d have to admit it doesn’t mean the same as in pcase, and, obviously: the fact you maybe used it in the data you want to match, doesn’t mean you need to use it in the pattern (because the reader removes it) so the purpose is defeated), that’s not what I call “look exactely like it”: “(foo 1 2 . 3)” is “exactely”, “('foo a b . rest)” would be enough. I find “`(foo ,(var a) ,(var b) . ,(var rest))” is still understandable and not that confusing, but it *doesn’t* look like the matched data, like it does in other languages, such as ocaml/haskell/rust/etc. > The above pattern would look different if we would have to write it as > > `(foo ,(var a) ,(var b) . ,(var rest)) > > so the implicit binding feature of symbols also makes patterns much more > readable in more complex cases, which is a big win. It is a big win only in terms of avoiding confusion (with “`”), and allowing otherwise impossible stuff (without “`”), but I wasn’t proposing it to make more readable, only more powerful and less confusing. What would make more readable are directly matching them when they don’t correspound an already defined pattern (such as (1 2 3), since no pattern is defined after a number, or absolutely all occurences of [], since no pattern is defined after an array), like guile’s and racket’s matches, and some common lisp matches, do, and, otherwise, pattern named after type constructor such as `vector' or `list', as you suggested in the other thread, to correct me: #+begin_src emacs-lisp (pcase-defmacro list (&rest args) `(,'\` ,(mapcar (lambda (thing) `(,'\, ,thing)) args))) #+end_src I tried to adapt for arrays: #+begin_src emacs-lisp (pcase-defmacro array (&rest args) `[,'\` ,(mapcar (lambda (thing) `(,'\, ,thing)) args)]) #+end_src But it doesn’t work x), that, plus my initial non-working “(pcase-defmacro list (&rest args) ``(,@args))”, I must find “`”, is, indeed, quite confusing (how is “,'” needed? how isn’t “,'\`” equivalent to “\`”?), even in real life (or maybe here it is because of pcase it is that complex?), when it get complex, like used directly recursively. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: pcase ` meaning [Was: Re: Replace trivial pcase occurrences in the Emacs sources] 2018-10-29 10:22 ` Garreau, Alexandre @ 2018-10-29 21:33 ` Michael Heerdegen 2018-10-29 23:00 ` pcase ` meaning Garreau, Alexandre 0 siblings, 1 reply; 375+ messages in thread From: Michael Heerdegen @ 2018-10-29 21:33 UTC (permalink / raw) To: Garreau, Alexandre Cc: Eli Zaretskii, Dmitry Gutov, Stefan Monnier, emacs-devel "Garreau, Alexandre" <galex-713@galex-713.eu> writes: > Even in pcase I don’t see how to do that except manually using (and var > (guard (equal var val))), You mean like (pred (equal val))? > #+begin_src emacs-lisp > (pcase-defmacro list (&rest args) > `(,'\` ,(mapcar (lambda (thing) `(,'\, ,thing)) args))) > #+end_src > > I tried to adapt for arrays: > > #+begin_src emacs-lisp > (pcase-defmacro array (&rest args) > `[,'\` ,(mapcar (lambda (thing) `(,'\, ,thing)) args)]) > #+end_src > But it doesn’t work x), that, plus my initial non-working > “(pcase-defmacro list (&rest args) ``(,@args))”, I must find “`”, is, > indeed, quite confusing (how is “,'” needed? how isn’t “,'\`” equivalent > to “\`”?), You want , to survive til after the macro expansion. Backquote can't know that it should ignore a , because you want it to be literally in the expansion. ,'\` let's backquote insert a literal , into the expansion, which is what you want. The underlying problem is that you want to use (of course you don't have to!) backquote to construct a backquote expression. That happens here and there when writing Lisp, it's not something special to pcase. For understanding the definition above note that ``' (synonymous for `backquote') is a (very normal) macro accepting one argument STRUCTURE, whereby we also have an abbreviating reader syntax `STRUCTURE == (` STRUCTURE). We also have the reader syntax ,THING == (, THING). Your pcase macro `array' could be defined like #+begin_src emacs-lisp (pcase-defmacro array (&rest args) `(,'\` [,@(mapcar (lambda (thing) `(,'\, ,thing)) args)])) #+end_src You could also write that without backquote (and also without the [] reader syntax). Michael. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: pcase ` meaning 2018-10-29 21:33 ` Michael Heerdegen @ 2018-10-29 23:00 ` Garreau, Alexandre 2018-10-29 23:57 ` Michael Heerdegen 0 siblings, 1 reply; 375+ messages in thread From: Garreau, Alexandre @ 2018-10-29 23:00 UTC (permalink / raw) To: Michael Heerdegen Cc: Eli Zaretskii, Dmitry Gutov, Stefan Monnier, emacs-devel Le 29/10/2018 à 22h33, Michael Heerdegen a écrit : > "Garreau, Alexandre" <galex-713@galex-713.eu> writes: > >> Even in pcase I don’t see how to do that except manually using (and var >> (guard (equal var val))), > > You mean like (pred (equal val))? Oh indeed! Still that defeat the purpose of pattern matching by requiring non-pattern matching stuff. >> #+begin_src emacs-lisp >> (pcase-defmacro list (&rest args) >> `(,'\` ,(mapcar (lambda (thing) `(,'\, ,thing)) args))) >> #+end_src >> >> I tried to adapt for arrays: >> >> #+begin_src emacs-lisp >> (pcase-defmacro array (&rest args) >> `[,'\` ,(mapcar (lambda (thing) `(,'\, ,thing)) args)]) >> #+end_src > >> But it doesn’t work x), that, plus my initial non-working >> “(pcase-defmacro list (&rest args) ``(,@args))”, I must find “`”, is, >> indeed, quite confusing (how is “,'” needed? how isn’t “,'\`” equivalent >> to “\`”?), > > You want , to survive til after the macro expansion. Backquote can't > know that it should ignore a , because you want it to be literally in > the expansion. ,'\` let's backquote insert a literal , into the > expansion, which is what you want. The underlying problem is that you > want to use (of course you don't have to!) backquote to construct a > backquote expression. That happens here and there when writing Lisp, > it's not something special to pcase. Yes I know, what I meant is `, in lisp, can generally lead to confusion unexperimented programmer. That’s one of the selling points of hygienic macros (standard and default in scheme). The fact pcase is not strictly treating ` as standard lisp’s reader does is only *adding* the the already existing confusion normal and standard ` introduces in lisp. > For understanding the definition above note that ``' (synonymous for > `backquote') is a (very normal) macro accepting one argument STRUCTURE, > whereby we also have an abbreviating reader syntax > `STRUCTURE == (` STRUCTURE). We also have the reader syntax > ,THING == (, THING). Indeed you’re right, but that doesn’t automagically explain to me how does exactely work the “,” macro, as it stays context dependant, not trivial, and to me, “,” meant either “eval” or “undo ‘`’” (the later is nearer to the meaning used in pcase btw). > Your pcase macro `array' could be defined like > > #+begin_src emacs-lisp > (pcase-defmacro array (&rest args) > `(,'\` [,@(mapcar (lambda (thing) `(,'\, ,thing)) args)])) > #+end_src > > You could also write that without backquote (and also without the [] > reader syntax). Ah okkkk! Backquotes may be difficult or confusing to master fully, but at least they’re consistent and simple enough to stay readable, I find, more easily than easily writable. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: pcase ` meaning 2018-10-29 23:00 ` pcase ` meaning Garreau, Alexandre @ 2018-10-29 23:57 ` Michael Heerdegen 2018-10-30 0:17 ` Garreau, Alexandre 0 siblings, 1 reply; 375+ messages in thread From: Michael Heerdegen @ 2018-10-29 23:57 UTC (permalink / raw) To: Garreau, Alexandre Cc: Eli Zaretskii, Dmitry Gutov, Stefan Monnier, emacs-devel "Garreau, Alexandre" <galex-713@galex-713.eu> writes: > > You mean like (pred (equal val))? > > Oh indeed! Still that defeat the purpose of pattern matching by > requiring non-pattern matching stuff. What in that pattern is non-pattern matching stuff? > The fact pcase is not strictly treating ` as standard lisp’s reader does > is only *adding* the the already existing confusion normal and standard > ` introduces in lisp. ` is a normal macro, it has nothing to do with the reader. Apart from the ` reader macro, which pcase doesn't touch at all. What it does is to give ` different semantics inside patterns. Like your `list' pattern gives new semantics to the symbol `list'. Oh my. > > For understanding the definition above note that ``' (synonymous for > > `backquote') is a (very normal) macro accepting one argument STRUCTURE, > > whereby we also have an abbreviating reader syntax > > `STRUCTURE == (` STRUCTURE). We also have the reader syntax > > ,THING == (, THING). > > Indeed you’re right, but that doesn’t automagically explain to me how > does exactely work the “,” macro, as it stays context dependant, not > trivial, and to me, “,” meant either “eval” or “undo ‘`’” (the later is > nearer to the meaning used in pcase btw). (, is not a macro, btw) Well, in pcase patterns it "means" something different. As `and' means something different in `rx'. You very often say that you expected something different. I dunno what I first expected, I read the docs to learn pcase, and it took 5 minutes. I think we can agree that we disagree - I just don't share your opinion. The thing is designed in a way that it matches how some, but not all people, like to think about pattern matching. Michael. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: pcase ` meaning 2018-10-29 23:57 ` Michael Heerdegen @ 2018-10-30 0:17 ` Garreau, Alexandre 2018-10-30 1:40 ` Michael Heerdegen 2018-10-30 16:05 ` Yuri Khan 0 siblings, 2 replies; 375+ messages in thread From: Garreau, Alexandre @ 2018-10-30 0:17 UTC (permalink / raw) To: Michael Heerdegen Cc: Eli Zaretskii, Dmitry Gutov, Stefan Monnier, emacs-devel On 2018/10/30 at 00:57, Michael Heerdegen wrote: > "Garreau, Alexandre" <galex-713@galex-713.eu> writes: > >> > You mean like (pred (equal val))? >> >> Oh indeed! Still that defeat the purpose of pattern matching by >> requiring non-pattern matching stuff. > > What in that pattern is non-pattern matching stuff? guards, pred, etc. are “pattern” in pcase parlance, but aren’t pattern-matching in general sense: they are only a (handy) extra way to specify arbitrary conditions in the middle of a pattern matching, in addition to matching the *pattern*, that is a structure that mimick what we want to match. >> The fact pcase is not strictly treating ` as standard lisp’s reader does >> is only *adding* the the already existing confusion normal and standard >> ` introduces in lisp. > > ` is a normal macro, it has nothing to do with the reader. Apart from > the ` reader macro, which pcase doesn't touch at all. They share a name, that’s enough. And to me it seems that this name sharing is here to (incompletely / incorrectly) borrow some of the semantics of the ` reader macro. > What it does is to give ` different semantics inside patterns. Like > your `list' pattern gives new semantics to the symbol `list'. Oh my. It’s not arbitrary random semantics, it base on the knowledge people might have of “`”, and of its use along with “,”. List, at the opposite, is pure pattern matching, since it is used as a list constructor, look: (pcase (list 1 2 3) ((list 1 2 3) t)) It just looks *exactely* the same. (pcase (list 1 2 3) ((list a b c) (+ a b c))) And here it’s *almost* the same, beside identifiers, to be bound. While: (pcase `(1 2 3) (`(1 2 3) t)) look the same, as well as: (pcase `(a b c) (`(a b c) t)) But not: (pcase `(1 2 3) (`(,a ,b ,c) (+ a b c))) >> > For understanding the definition above note that ``' (synonymous for >> > `backquote') is a (very normal) macro accepting one argument STRUCTURE, >> > whereby we also have an abbreviating reader syntax >> > `STRUCTURE == (` STRUCTURE). We also have the reader syntax >> > ,THING == (, THING). >> >> Indeed you’re right, but that doesn’t automagically explain to me how >> does exactely work the “,” macro, as it stays context dependant, not >> trivial, and to me, “,” meant either “eval” or “undo ‘`’” (the later is >> nearer to the meaning used in pcase btw). > > (, is not a macro, btw) Well, in pcase patterns it "means" something > different. As `and' means something different in `rx'. Yes. A different meaning for `and', is acceptable, and the first time I saw a complain about it I also immediatly thought to `rx'. But if `and' meaning change is acceptable it’s because “and” is already a word of english with an abstract, independant, general meaning per se. While “`” is almost never used as in lisp, except as *real* quotes, that match, as in `' in TeX (or docstrings), or `` in shellscript. > You very often say that you expected something different. I dunno what > I first expected, I read the docs to learn pcase, and it took 5 minutes. I sometimes exagerate in reguard to pcase understandability: I find its syntax confusive because it is actually inconsistent with outside-pcase-world, and I’m a perfectionist (that’s a defect that can be workaround, still). I do that because, though I’m not fond of pattern matching, I do think sometimes it’s handy, useful or even necessary, and then I’d like pcase to be the most easily understandable by the most possible people. > I think we can agree that we disagree - I just don't share your > opinion. The thing is designed in a way that it matches how some, but > not all people, like to think about pattern matching. Not that much I believe: you were enthusiast as well about the `var' pattern, and I’m pretty sure (and guess I’m not the only one) than borrowing some patterns from other lisps pattern matching facilities may allow less confusing pcase usages, as you initially wanted. The one I’d push the harder, and find the most important, is (a b c) (not quoted) to match a list, when no `a' pattern is defined, as it is done in schemes’ match, and the most naive and simple common-lisp match. Here I know pcase, currently, refuse it, but I didn’t yet hear people talk against it, but I may expect to be a minority to want this, or at least not to be a majority wanting it, or to have some people (Stefan?) against it. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: pcase ` meaning 2018-10-30 0:17 ` Garreau, Alexandre @ 2018-10-30 1:40 ` Michael Heerdegen 2018-10-30 16:05 ` Yuri Khan 1 sibling, 0 replies; 375+ messages in thread From: Michael Heerdegen @ 2018-10-30 1:40 UTC (permalink / raw) To: Garreau, Alexandre Cc: Eli Zaretskii, Dmitry Gutov, Stefan Monnier, emacs-devel "Garreau, Alexandre" <galex-713@galex-713.eu> writes: > > I think we can agree that we disagree - I just don't share your > > opinion. The thing is designed in a way that it matches how some, but > > not all people, like to think about pattern matching. > > Not that much I believe: you were enthusiast as well about the `var' > pattern Yeah, but only to see some lines later that what we have is better. The concept and implementation of pcase are more thought over than you think. Ok, I think I have said all I wanted, more than once: I like pcase, it is a very good solution of the task of pattern matching in my eyes. I like its use of backquote, etc...I think this thread has enough of my opinion so far, so I'll stop here until I have something really new to say. Michael. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: pcase ` meaning 2018-10-30 0:17 ` Garreau, Alexandre 2018-10-30 1:40 ` Michael Heerdegen @ 2018-10-30 16:05 ` Yuri Khan 1 sibling, 0 replies; 375+ messages in thread From: Yuri Khan @ 2018-10-30 16:05 UTC (permalink / raw) To: galex-713 Cc: Michael Heerdegen, Eli Zaretskii, Emacs developers, Stefan Monnier, Dmitry Gutov On Tue, Oct 30, 2018 at 7:18 AM Garreau, Alexandre <galex-713@galex-713.eu> wrote: > (pcase `(1 2 3) (`(1 2 3) t)) > > look the same, as well as: > > (pcase `(a b c) (`(a b c) t)) > > But not: > > (pcase `(1 2 3) (`(,a ,b ,c) (+ a b c))) IMO you’re giving too much attention to “looking the same”. You use identifiers a, b, and c in a pattern. The pattern matcher needs to know which of these you meant as placeholders to bind, and which as literal symbols to match against. (let ((c 42)) (pcase `(a x 42) (`(a ,b ,(pred (equal c))) t))) In an alternate world, you would color the parentheses, the spaces, and the literal symbol “a” yellow, and say these are the things to match literally. You would then color “b” and “c” white, and say these are placeholders. You might even color something green and say these are expressions whose values should be taken and matched. In that same world, you could draw nested boxes instead of these nested parentheses that make newbies so nervous about Lisp. However, in this world, we only encode Unicode characters in our source files, and add color only as an aid to understanding. So we use various funny characters such as parentheses to denote nesting, and ` and , to denote color. (Upthread, the idea of “holes” was mentioned. That is a very good analogy, both for pcase and for quoting/antiquoting in general.) ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: pcase ` meaning [Was: Re: Replace trivial pcase occurrences in the Emacs sources] 2018-10-28 23:09 ` Garreau, Alexandre 2018-10-28 23:57 ` Michael Heerdegen @ 2018-10-29 17:26 ` Clément Pit-Claudel 2018-10-30 0:27 ` pcase ` meaning Garreau, Alexandre 1 sibling, 1 reply; 375+ messages in thread From: Clément Pit-Claudel @ 2018-10-29 17:26 UTC (permalink / raw) To: emacs-devel On 28/10/2018 19.09, Garreau, Alexandre wrote: > the pattern look like what the data should be. adding “`” and “,” > destroy this feature, because the pattern no longer looks like what > is matched. Maybe it's a matter of perspective? Adding "`" and "," is precisely what makes the pattern look like the data: the invariant is that if you have a match, repeating the pattern produces the original data. Here's a concrete example: (pcase '(1 2 3 4) (`(,x ,y . ,z) `(,x ,y . ,z))) is a no-op. In other words, q-patterns are equations with multiple unknown variables (holes). When you write a q-pattern, you're asking "what values should the variables in this pattern take so that evaluating the pattern would return the matched data?" Clément. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: pcase ` meaning 2018-10-29 17:26 ` pcase ` meaning [Was: Re: Replace trivial pcase occurrences in the Emacs sources] Clément Pit-Claudel @ 2018-10-30 0:27 ` Garreau, Alexandre 2018-10-30 13:14 ` Stefan Monnier 0 siblings, 1 reply; 375+ messages in thread From: Garreau, Alexandre @ 2018-10-30 0:27 UTC (permalink / raw) To: Clément Pit-Claudel; +Cc: emacs-devel On 2018-10-29 at 13:26, Clément Pit-Claudel wrote: > On 28/10/2018 19.09, Garreau, Alexandre wrote: >> the pattern look like what the data should be. adding “`” and “,” >> destroy this feature, because the pattern no longer looks like what >> is matched. > > Maybe it's a matter of perspective? Adding "`" and "," is precisely > what makes the pattern look like the data: the invariant is that if > you have a match, repeating the pattern produces the original data. Oh, you mean “repeating *in the body*”? Didn’t notice that. Indeed, this is something I didn’t notice: that’s making me way more comfortable with “`” (as it is used this way in all schemes too, so its meaning couldn’t and won’t be changed). But normally, even if, as a side effect, pattern matching match in appearance what it’d be if you wanted to repeat the pattern, repeated, like here: #+BEGIN_SRC emacs-lisp (pcase `(1 2 3) (`(,a ,b ,c) `(,a ,b ,c))) #+END_SRC (or may appear also as '(1 2 3), or (list 1 2 3)) #+BEGIN_SRC ocaml match [1;2;3] with [a;b;c] -> [a;b;c] #+END_SRC But this is a non-primordial side effect. Notice how in the later case the matched data *always* look the same as the pattern (beside replacing a number per an identifier): *that’s* the purpose of pattern matching. While in the lisp case you got those extra “,”. Of course, these might not cause problem if, incidentally, you were to use them in matched data too (but it’d be odd): #+BEGIN_SRC emacs-lisp (pcase `(,x ,y ,z) (`(,a ,b ,c) `(,a ,b ,c))) #+END_SRC But that will rarely happen, as it is somewhat redundant. > Here's a concrete example: (pcase '(1 2 3 4) (`(,x ,y . ,z) `(,x ,y > . ,z))) is a no-op. In other words, q-patterns are equations with > multiple unknown variables (holes). When you write a q-pattern, > you're asking "what values should the variables in this pattern take > so that evaluating the pattern would return the matched data?" Normally, the pattern isn’t made related to the reuse of its var, but related to the matched data, to look like it. Only then, by implication, you got it to look like what you would do to reconstruct it in the body. But that is a really interesting perspective I missed. Thank you for sharing it. This is the kind of implicit “logical” intuitive ideas that make designs meaningful that are kept unwritten, while they should, I believe, be advertised so to explain why a specific design is handy or natural (if ever newcomers found it unnatural). ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: pcase ` meaning 2018-10-30 0:27 ` pcase ` meaning Garreau, Alexandre @ 2018-10-30 13:14 ` Stefan Monnier 2018-10-31 23:13 ` Garreau, Alexandre 0 siblings, 1 reply; 375+ messages in thread From: Stefan Monnier @ 2018-10-30 13:14 UTC (permalink / raw) To: emacs-devel > #+BEGIN_SRC ocaml > match [1;2;3] with [a;b;c] -> [a;b;c] > #+END_SRC > > But this is a non-primordial side effect. Notice how in the later case > the matched data *always* look the same as the pattern (beside replacing > a number per an identifier): *that’s* the purpose of pattern matching. > While in the lisp case you got those extra “,”. That's for a very simple reason: OCaml doesn't have Lisp's symbols, so its [a;b;c] can't mean "a list containing the symbols a, b, and c". OCaml still has to distinguish between variables and data constructors, but instead of using a "," to distinguish the two cases, they force constructors to be capitalized. Stefan ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: pcase ` meaning 2018-10-30 13:14 ` Stefan Monnier @ 2018-10-31 23:13 ` Garreau, Alexandre 2018-11-01 13:22 ` Clément Pit-Claudel 0 siblings, 1 reply; 375+ messages in thread From: Garreau, Alexandre @ 2018-10-31 23:13 UTC (permalink / raw) To: Stefan Monnier; +Cc: emacs-devel On 2018-10-30 at 09:14, Stefan Monnier wrote: >> #+BEGIN_SRC ocaml >> match [1;2;3] with [a;b;c] -> [a;b;c] >> #+END_SRC >> >> But this is a non-primordial side effect. Notice how in the later case >> the matched data *always* look the same as the pattern (beside replacing >> a number per an identifier): *that’s* the purpose of pattern matching. >> While in the lisp case you got those extra “,”. > > That's for a very simple reason: OCaml doesn't have Lisp's symbols, so > its [a;b;c] can't mean "a list containing the symbols a, b, and c". In lisp I would have prefered to be able to directly quote each symbol, and have this to work, eg: “(pcase (list 1 2 3) (('a 'b 'c) t))” to return nil, and “(pcase (list 'a 'b 'c) (('a 'b 'c) t))” to return t (and this is like many other lisp pattern-matching implementations already work). In current pcase, pattern “(a b c)” does *not* mean “with symbols 'a, 'b and 'c”. “('(a b c) t)” (or same with “`”) seems okay to me, but as “(`(,a ,b ,c) t)” *may* be confusing (the intended, actual and current meaning must be intuitive under some definition of “intuitive” too since others independantly do it too), I’d prefer “((a b c) t)” to work. > OCaml still has to distinguish between variables and data constructors, > but instead of using a "," to distinguish the two cases, they force > constructors to be capitalized. Oh… yet another (disappointing) reason why they did what (incredibly limited) they did (though afaik it’s nothing new, it have to come from Smalltalk, and I’m not that much opposed to identifiers names/meaning intermeddling). ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: pcase ` meaning 2018-10-31 23:13 ` Garreau, Alexandre @ 2018-11-01 13:22 ` Clément Pit-Claudel 2018-11-01 14:11 ` Garreau, Alexandre 0 siblings, 1 reply; 375+ messages in thread From: Clément Pit-Claudel @ 2018-11-01 13:22 UTC (permalink / raw) To: emacs-devel On 31/10/2018 19.13, Garreau, Alexandre wrote: > In lisp I would have prefered to be able to directly quote each symbol, > and have this to work, eg: “(pcase (list 1 2 3) (('a 'b 'c) t))” to > return nil, and “(pcase (list 'a 'b 'c) (('a 'b 'c) t))” to return t > (and this is like many other lisp pattern-matching implementations > already work). In current pcase, pattern “(a b c)” does *not* mean > “with symbols 'a, 'b and 'c”. But remember that this breaks the pattern-body symmetry: (pcase (list 'a 'b 'c) (('a 'b 'c) ('a 'b 'c))) would match, but the body would raise an error. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: pcase ` meaning 2018-11-01 13:22 ` Clément Pit-Claudel @ 2018-11-01 14:11 ` Garreau, Alexandre 0 siblings, 0 replies; 375+ messages in thread From: Garreau, Alexandre @ 2018-11-01 14:11 UTC (permalink / raw) To: Clément Pit-Claudel; +Cc: emacs-devel On 2018-11-01 at 09:22, Clément Pit-Claudel wrote: > On 31/10/2018 19.13, Garreau, Alexandre wrote: >> In lisp I would have prefered to be able to directly quote each symbol, >> and have this to work, eg: “(pcase (list 1 2 3) (('a 'b 'c) t))” to >> return nil, and “(pcase (list 'a 'b 'c) (('a 'b 'c) t))” to return t >> (and this is like many other lisp pattern-matching implementations >> already work). In current pcase, pattern “(a b c)” does *not* mean >> “with symbols 'a, 'b and 'c”. > > But remember that this breaks the pattern-body symmetry: > (pcase (list 'a 'b 'c) (('a 'b 'c) ('a 'b 'c))) > would match, but the body would raise an error. Then if it’s important to you, don’t do that, it’s a question of tastes and style. Other implementations allow to do that. You may as well quote the list, or, better imho, use a list constructor (list 'a 'b 'c) as a pattern. Which also exists in other implementations. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-27 15:19 ` Michael Heerdegen 2018-10-27 16:56 ` Garreau, Alexandre 2018-10-27 22:37 ` Dmitry Gutov @ 2018-10-29 3:26 ` Eli Zaretskii 2018-10-29 21:46 ` Michael Heerdegen 2 siblings, 1 reply; 375+ messages in thread From: Eli Zaretskii @ 2018-10-29 3:26 UTC (permalink / raw) To: Michael Heerdegen; +Cc: monnier, emacs-devel > From: Michael Heerdegen <michael_heerdegen@web.de> > Cc: Stefan Monnier <monnier@iro.umontreal.ca>, emacs-devel@gnu.org > Date: Sat, 27 Oct 2018 17:19:02 +0200 > > Is the commit message ok as it is? Or should I list the changed files > to say "All callers changed" every time? I'd prefer this format: * lisp/char-fold.el: * lisp/dired.el: * lisp/emacs-lisp/derived.el: * lisp/emacs-lisp/easy-mmode.el: Don't quote self-quoting 'pcase' patterns. IOW, a list of all changed files, with the description at the end. Thanks. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-29 3:26 ` Replace trivial pcase occurrences in the Emacs sources Eli Zaretskii @ 2018-10-29 21:46 ` Michael Heerdegen 2018-10-30 0:36 ` What `case' have done you? [Was: Re: Replace trivial pcase occurrences in the Emacs sources] Garreau, Alexandre 2018-10-30 6:31 ` Replace trivial pcase occurrences in the Emacs sources Eli Zaretskii 0 siblings, 2 replies; 375+ messages in thread From: Michael Heerdegen @ 2018-10-29 21:46 UTC (permalink / raw) To: Eli Zaretskii; +Cc: monnier, emacs-devel [-- Attachment #1: Type: text/plain, Size: 430 bytes --] Eli Zaretskii <eliz@gnu.org> writes: > I'd prefer this format: > > * lisp/char-fold.el: > * lisp/dired.el: > * lisp/emacs-lisp/derived.el: > * lisp/emacs-lisp/easy-mmode.el: Don't quote self-quoting 'pcase' > patterns. > > IOW, a list of all changed files, with the description at the end. Ok, done. I kept the description as commit message however, since I need one. Ok to install (the patch itself is unchanged)? [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #2: 0001-Don-t-quote-self-quoting-pcase-patterns.patch --] [-- Type: text/x-diff, Size: 39685 bytes --] From 656f77b1233388ef713ca84904c1ffbddf49c002 Mon Sep 17 00:00:00 2001 From: Michael Heerdegen <michael_heerdegen@web.de> Date: Sat, 27 Oct 2018 01:48:35 +0200 Subject: [PATCH] Don't quote self-quoting pcase patterns * admin/bzrmerge.el: * lisp/char-fold.el: * lisp/dired.el: * lisp/emacs-lisp/derived.el: * lisp/emacs-lisp/easy-mmode.el: * lisp/emacs-lisp/easymenu.el: * lisp/emacs-lisp/eieio-core.el: * lisp/emacs-lisp/package.el: * lisp/emacs-lisp/smie.el: * lisp/faces.el: * lisp/filesets.el: * lisp/progmodes/modula2.el: * lisp/progmodes/octave.el: * lisp/progmodes/opascal.el: * lisp/progmodes/perl-mode.el: * lisp/progmodes/prolog.el: * lisp/progmodes/ruby-mode.el: * lisp/progmodes/sh-script.el: * lisp/server.el: * lisp/subr.el: * lisp/textmodes/css-mode.el: * test/lisp/emacs-lisp/pcase-tests.el: Don't quote self-quoting 'pcase' patterns. --- admin/bzrmerge.el | 6 +-- lisp/char-fold.el | 2 +- lisp/dired.el | 8 ++-- lisp/emacs-lisp/derived.el | 8 ++-- lisp/emacs-lisp/easy-mmode.el | 62 ++++++++++++++--------------- lisp/emacs-lisp/easymenu.el | 28 ++++++------- lisp/emacs-lisp/eieio-core.el | 6 +-- lisp/emacs-lisp/package.el | 22 +++++----- lisp/emacs-lisp/smie.el | 4 +- lisp/faces.el | 22 +++++----- lisp/filesets.el | 2 +- lisp/progmodes/modula2.el | 22 +++++----- lisp/progmodes/octave.el | 36 ++++++++--------- lisp/progmodes/opascal.el | 14 +++---- lisp/progmodes/perl-mode.el | 4 +- lisp/progmodes/prolog.el | 14 +++---- lisp/progmodes/ruby-mode.el | 18 ++++----- lisp/progmodes/sh-script.el | 18 ++++----- lisp/server.el | 32 +++++++-------- lisp/subr.el | 2 +- lisp/textmodes/css-mode.el | 2 +- test/lisp/emacs-lisp/pcase-tests.el | 2 +- 22 files changed, 167 insertions(+), 167 deletions(-) diff --git a/admin/bzrmerge.el b/admin/bzrmerge.el index cedb625fb0..d54ba330f9 100644 --- a/admin/bzrmerge.el +++ b/admin/bzrmerge.el @@ -150,12 +150,12 @@ bzrmerge-missing (format "%s: Skip (y/n/N/q/%s)? " str (key-description (vector help-char))) '(?y ?n ?N ?q))) - (`?y (setq skip t)) - (`?q (keyboard-quit)) + (?y (setq skip t)) + (?q (keyboard-quit)) ;; A single log entry can match skip-regexp multiple ;; times. If you are sure you don't want to skip it, ;; you don't want to be asked multiple times. - (`?N (setq skip 'no)))))) + (?N (setq skip 'no)))))) (if (eq skip t) (push revno skipped) (push revno revnos))))) diff --git a/lisp/char-fold.el b/lisp/char-fold.el index 86bd6038e3..907d49e4f2 100644 --- a/lisp/char-fold.el +++ b/lisp/char-fold.el @@ -170,7 +170,7 @@ char-fold-to-regexp ;; need to keep them grouped together like this: "\\( \\|[ ...][ ...]\\)". (while (< i end) (pcase (aref string i) - (`?\s (setq spaces (1+ spaces))) + (?\s (setq spaces (1+ spaces))) (c (when (> spaces 0) (push (char-fold--make-space-string spaces) out) (setq spaces 0)) diff --git a/lisp/dired.el b/lisp/dired.el index 5c7bb9599c..f2f2b76eb7 100644 --- a/lisp/dired.el +++ b/lisp/dired.el @@ -3046,10 +3046,10 @@ dired-delete-file ("no" ?n "skip to next") ("all" ?! "delete all remaining directories with no more questions") ("quit" ?q "exit"))) - ('"all" (setq recursive 'always dired-recursive-deletes recursive)) - ('"yes" (if (eq recursive 'top) (setq recursive 'always))) - ('"no" (setq recursive nil)) - ('"quit" (keyboard-quit)) + ("all" (setq recursive 'always dired-recursive-deletes recursive)) + ("yes" (if (eq recursive 'top) (setq recursive 'always))) + ("no" (setq recursive nil)) + ("quit" (keyboard-quit)) (_ (keyboard-quit))))) ; catch all unknown answers (setq recursive nil)) ; Empty dir or recursive is nil. (delete-directory file recursive trash)))) diff --git a/lisp/emacs-lisp/derived.el b/lisp/emacs-lisp/derived.el index 6b47ffea07..483d6fbfa4 100644 --- a/lisp/emacs-lisp/derived.el +++ b/lisp/emacs-lisp/derived.el @@ -193,10 +193,10 @@ define-derived-mode ;; Process the keyword args. (while (keywordp (car body)) (pcase (pop body) - (`:group (setq group (pop body))) - (`:abbrev-table (setq abbrev (pop body)) (setq declare-abbrev nil)) - (`:syntax-table (setq syntax (pop body)) (setq declare-syntax nil)) - (`:after-hook (setq after-hook (pop body))) + (:group (setq group (pop body))) + (:abbrev-table (setq abbrev (pop body)) (setq declare-abbrev nil)) + (:syntax-table (setq syntax (pop body)) (setq declare-syntax nil)) + (:after-hook (setq after-hook (pop body))) (_ (pop body)))) (setq docstring (derived-mode-make-docstring diff --git a/lisp/emacs-lisp/easy-mmode.el b/lisp/emacs-lisp/easy-mmode.el index 4d8a502026..d74c3ddb97 100644 --- a/lisp/emacs-lisp/easy-mmode.el +++ b/lisp/emacs-lisp/easy-mmode.el @@ -217,30 +217,30 @@ define-minor-mode (while (keywordp (setq keyw (car body))) (setq body (cdr body)) (pcase keyw - (`:init-value (setq init-value (pop body))) - (`:lighter (setq lighter (purecopy (pop body)))) - (`:global (setq globalp (pop body)) - (when (and globalp (symbolp mode)) - (setq setter `(setq-default ,mode)) - (setq getter `(default-value ',mode)))) - (`:extra-args (setq extra-args (pop body))) - (`:set (setq set (list :set (pop body)))) - (`:initialize (setq initialize (list :initialize (pop body)))) - (`:group (setq group (nconc group (list :group (pop body))))) - (`:type (setq type (list :type (pop body)))) - (`:require (setq require (pop body))) - (`:keymap (setq keymap (pop body))) - (`:variable (setq variable (pop body)) - (if (not (and (setq tmp (cdr-safe variable)) - (or (symbolp tmp) - (functionp tmp)))) - ;; PLACE is not of the form (GET . SET). - (progn - (setq setter `(setf ,variable)) - (setq getter variable)) - (setq getter (car variable)) - (setq setter `(funcall #',(cdr variable))))) - (`:after-hook (setq after-hook (pop body))) + (:init-value (setq init-value (pop body))) + (:lighter (setq lighter (purecopy (pop body)))) + (:global (setq globalp (pop body)) + (when (and globalp (symbolp mode)) + (setq setter `(setq-default ,mode)) + (setq getter `(default-value ',mode)))) + (:extra-args (setq extra-args (pop body))) + (:set (setq set (list :set (pop body)))) + (:initialize (setq initialize (list :initialize (pop body)))) + (:group (setq group (nconc group (list :group (pop body))))) + (:type (setq type (list :type (pop body)))) + (:require (setq require (pop body))) + (:keymap (setq keymap (pop body))) + (:variable (setq variable (pop body)) + (if (not (and (setq tmp (cdr-safe variable)) + (or (symbolp tmp) + (functionp tmp)))) + ;; PLACE is not of the form (GET . SET). + (progn + (setq setter `(setf ,variable)) + (setq getter variable)) + (setq getter (car variable)) + (setq setter `(funcall #',(cdr variable))))) + (:after-hook (setq after-hook (pop body))) (_ (push keyw extra-keywords) (push (pop body) extra-keywords)))) (setq keymap-sym (if (and keymap (symbolp keymap)) keymap @@ -407,8 +407,8 @@ define-globalized-minor-mode (while (keywordp (setq keyw (car keys))) (setq keys (cdr keys)) (pcase keyw - (`:group (setq group (nconc group (list :group (pop keys))))) - (`:global (setq keys (cdr keys))) + (:group (setq group (nconc group (list :group (pop keys))))) + (:global (setq keys (cdr keys))) (_ (push keyw extra-keywords) (push (pop keys) extra-keywords)))) (unless group @@ -533,11 +533,11 @@ easy-mmode-define-keymap (let ((key (pop args)) (val (pop args))) (pcase key - (`:name (setq name val)) - (`:dense (setq dense val)) - (`:inherit (setq inherit val)) - (`:suppress (setq suppress val)) - (`:group) + (:name (setq name val)) + (:dense (setq dense val)) + (:inherit (setq inherit val)) + (:suppress (setq suppress val)) + (:group) (_ (message "Unknown argument %s in defmap" key))))) (unless (keymapp m) (setq bs (append m bs)) diff --git a/lisp/emacs-lisp/easymenu.el b/lisp/emacs-lisp/easymenu.el index 94d035f374..403829ac46 100644 --- a/lisp/emacs-lisp/easymenu.el +++ b/lisp/emacs-lisp/easymenu.el @@ -226,14 +226,14 @@ easy-menu-create-menu (let ((arg (cadr menu-items))) (setq menu-items (cddr menu-items)) (pcase keyword - (`:filter + (:filter (setq filter (lambda (menu) (easy-menu-filter-return (funcall arg menu) menu-name)))) - ((or `:enable `:active) (setq enable (or arg ''nil))) - (`:label (setq label arg)) - (`:help (setq help arg)) - ((or `:included `:visible) (setq visible (or arg ''nil)))))) + ((or :enable :active) (setq enable (or arg ''nil))) + (:label (setq label arg)) + (:help (setq help arg)) + ((or :included :visible) (setq visible (or arg ''nil)))))) (if (equal visible ''nil) nil ; Invisible menu entry, return nil. (if (and visible (not (easy-menu-always-true-p visible))) @@ -325,15 +325,15 @@ easy-menu-convert-item-1 (setq arg (aref item (1+ count))) (setq count (+ 2 count)) (pcase keyword - ((or `:included `:visible) (setq visible (or arg ''nil))) - (`:key-sequence (setq cache arg cache-specified t)) - (`:keys (setq keys arg no-name nil)) - (`:label (setq label arg)) - ((or `:active `:enable) (setq active (or arg ''nil))) - (`:help (setq prop (cons :help (cons arg prop)))) - (`:suffix (setq suffix arg)) - (`:style (setq style arg)) - (`:selected (setq selected (or arg ''nil))))) + ((or :included :visible) (setq visible (or arg ''nil))) + (:key-sequence (setq cache arg cache-specified t)) + (:keys (setq keys arg no-name nil)) + (:label (setq label arg)) + ((or :active :enable) (setq active (or arg ''nil))) + (:help (setq prop (cons :help (cons arg prop)))) + (:suffix (setq suffix arg)) + (:style (setq style arg)) + (:selected (setq selected (or arg ''nil))))) (if suffix (setq label (if (stringp suffix) diff --git a/lisp/emacs-lisp/eieio-core.el b/lisp/emacs-lisp/eieio-core.el index e5ea33c003..e5c4f198f5 100644 --- a/lisp/emacs-lisp/eieio-core.el +++ b/lisp/emacs-lisp/eieio-core.el @@ -388,9 +388,9 @@ eieio-defclass-internal ;; Clean up the meaning of protection. (setq prot (pcase prot - ((or 'nil 'public ':public) nil) - ((or 'protected ':protected) 'protected) - ((or 'private ':private) 'private) + ((or 'nil 'public :public) nil) + ((or 'protected :protected) 'protected) + ((or 'private :private) 'private) (_ (signal 'invalid-slot-type (list :protection prot))))) ;; The default type specifier is supposed to be t, meaning anything. diff --git a/lisp/emacs-lisp/package.el b/lisp/emacs-lisp/package.el index 9c4c3e9fe7..f2ffef8da7 100644 --- a/lisp/emacs-lisp/package.el +++ b/lisp/emacs-lisp/package.el @@ -2911,17 +2911,17 @@ package-menu--print-info-simple Return (PKG-DESC [NAME VERSION STATUS DOC])." (let* ((status (package-desc-status pkg)) (face (pcase status - (`"built-in" 'package-status-built-in) - (`"external" 'package-status-external) - (`"available" 'package-status-available) - (`"avail-obso" 'package-status-avail-obso) - (`"new" 'package-status-new) - (`"held" 'package-status-held) - (`"disabled" 'package-status-disabled) - (`"installed" 'package-status-installed) - (`"dependency" 'package-status-dependency) - (`"unsigned" 'package-status-unsigned) - (`"incompat" 'package-status-incompat) + ("built-in" 'package-status-built-in) + ("external" 'package-status-external) + ("available" 'package-status-available) + ("avail-obso" 'package-status-avail-obso) + ("new" 'package-status-new) + ("held" 'package-status-held) + ("disabled" 'package-status-disabled) + ("installed" 'package-status-installed) + ("dependency" 'package-status-dependency) + ("unsigned" 'package-status-unsigned) + ("incompat" 'package-status-incompat) (_ 'font-lock-warning-face)))) ; obsolete. (list pkg `[(,(symbol-name (package-desc-name pkg)) diff --git a/lisp/emacs-lisp/smie.el b/lisp/emacs-lisp/smie.el index c01a40172b..4b82172984 100644 --- a/lisp/emacs-lisp/smie.el +++ b/lisp/emacs-lisp/smie.el @@ -1856,9 +1856,9 @@ smie-setup (let ((k (pop keywords)) (v (pop keywords))) (pcase k - (`:forward-token + (:forward-token (set (make-local-variable 'smie-forward-token-function) v)) - (`:backward-token + (:backward-token (set (make-local-variable 'smie-backward-token-function) v)) (_ (message "smie-setup: ignoring unknown keyword %s" k))))) (let ((ca (cdr (assq :smie-closer-alist grammar)))) diff --git a/lisp/faces.el b/lisp/faces.el index 18b821a0b6..a8c1546d5a 100644 --- a/lisp/faces.el +++ b/lisp/faces.el @@ -1084,27 +1084,27 @@ face-valid-attribute-values an integer value." (let ((valid (pcase attribute - (`:family + (:family (if (window-system frame) (mapcar (lambda (x) (cons x x)) (font-family-list)) ;; Only one font on TTYs. (list (cons "default" "default")))) - (`:foundry + (:foundry (list nil)) - (`:width + (:width (mapcar #'(lambda (x) (cons (symbol-name (aref x 1)) (aref x 1))) font-width-table)) - (`:weight + (:weight (mapcar #'(lambda (x) (cons (symbol-name (aref x 1)) (aref x 1))) font-weight-table)) - (`:slant + (:slant (mapcar #'(lambda (x) (cons (symbol-name (aref x 1)) (aref x 1))) font-slant-table)) - (`:inverse-video + (:inverse-video (mapcar #'(lambda (x) (cons (symbol-name x) x)) (internal-lisp-face-attribute-values attribute))) - ((or `:underline `:overline `:strike-through `:box) + ((or :underline :overline :strike-through :box) (if (window-system frame) (nconc (mapcar #'(lambda (x) (cons (symbol-name x) x)) (internal-lisp-face-attribute-values attribute)) @@ -1112,12 +1112,12 @@ face-valid-attribute-values (defined-colors frame))) (mapcar #'(lambda (x) (cons (symbol-name x) x)) (internal-lisp-face-attribute-values attribute)))) - ((or `:foreground `:background) + ((or :foreground :background) (mapcar #'(lambda (c) (cons c c)) (defined-colors frame))) - (`:height + (:height 'integerp) - (`:stipple + (:stipple (and (memq (window-system frame) '(x ns)) ; No stipple on w32 (mapcar #'list (apply #'nconc @@ -1126,7 +1126,7 @@ face-valid-attribute-values (file-directory-p dir) (directory-files dir))) x-bitmap-file-path))))) - (`:inherit + (:inherit (cons '("none" . nil) (mapcar #'(lambda (c) (cons (symbol-name c) c)) (face-list)))) diff --git a/lisp/filesets.el b/lisp/filesets.el index c1e6ef10d5..8ccfa570e3 100644 --- a/lisp/filesets.el +++ b/lisp/filesets.el @@ -1559,7 +1559,7 @@ filesets-file-close (defun filesets-get-fileset-from-name (name &optional mode) "Get fileset definition for NAME." (pcase mode - ((or `:ingroup `:tree) name) + ((or :ingroup :tree) name) (_ (assoc name filesets-data)))) diff --git a/lisp/progmodes/modula2.el b/lisp/progmodes/modula2.el index 582e495a2b..ef12352457 100644 --- a/lisp/progmodes/modula2.el +++ b/lisp/progmodes/modula2.el @@ -232,11 +232,11 @@ m2-smie-refine-semi ;; FIXME: "^." are two tokens, not one. (defun m2-smie-forward-token () (pcase (smie-default-forward-token) - (`"VAR" (if (zerop (car (syntax-ppss))) "VAR" "VAR-arg")) - (`"CONST" (if (zerop (car (syntax-ppss))) "CONST" "CONST-arg")) - (`";" (save-excursion (m2-smie-refine-semi))) - (`"OF" (save-excursion (forward-char -2) (m2-smie-refine-of))) - (`":" (save-excursion (forward-char -1) (m2-smie-refine-colon))) + ("VAR" (if (zerop (car (syntax-ppss))) "VAR" "VAR-arg")) + ("CONST" (if (zerop (car (syntax-ppss))) "CONST" "CONST-arg")) + (";" (save-excursion (m2-smie-refine-semi))) + ("OF" (save-excursion (forward-char -2) (m2-smie-refine-of))) + (":" (save-excursion (forward-char -1) (m2-smie-refine-colon))) ;; (`"END" (if (and (looking-at "[ \t\n]*\\(\\(?:\\sw\\|\\s_\\)+\\)") ;; (not (assoc (match-string 1) m2-smie-grammar))) ;; "END-proc" "END")) @@ -244,11 +244,11 @@ m2-smie-forward-token (defun m2-smie-backward-token () (pcase (smie-default-backward-token) - (`"VAR" (if (zerop (car (syntax-ppss))) "VAR" "VAR-arg")) - (`"CONST" (if (zerop (car (syntax-ppss))) "CONST" "CONST-arg")) - (`";" (save-excursion (forward-char 1) (m2-smie-refine-semi))) - (`"OF" (save-excursion (m2-smie-refine-of))) - (`":" (save-excursion (m2-smie-refine-colon))) + ("VAR" (if (zerop (car (syntax-ppss))) "VAR" "VAR-arg")) + ("CONST" (if (zerop (car (syntax-ppss))) "CONST" "CONST-arg")) + (";" (save-excursion (forward-char 1) (m2-smie-refine-semi))) + ("OF" (save-excursion (m2-smie-refine-of))) + (":" (save-excursion (m2-smie-refine-colon))) ;; (`"END" (if (and (looking-at "\\sw+[ \t\n]+\\(\\(?:\\sw\\|\\s_\\)+\\)") ;; (not (assoc (match-string 1) m2-smie-grammar))) ;; "END-proc" "END")) @@ -272,7 +272,7 @@ m2-smie-rules (pcase (cons kind token) (`(:elem . basic) m2-indent) (`(:after . ":=") (or m2-indent smie-indent-basic)) - (`(:after . ,(or `"CONST" `"VAR" `"TYPE")) + (`(:after . ,(or "CONST" "VAR" "TYPE")) (or m2-indent smie-indent-basic)) ;; (`(:before . ,(or `"VAR" `"TYPE" `"CONST")) ;; (if (smie-rule-parent-p "PROCEDURE") 0)) diff --git a/lisp/progmodes/octave.el b/lisp/progmodes/octave.el index 13510eef80..cce5e17e79 100644 --- a/lisp/progmodes/octave.el +++ b/lisp/progmodes/octave.el @@ -1065,8 +1065,8 @@ octave-goto-function-definition (unless found (goto-char orig)) found)))) (pcase (and buffer-file-name (file-name-extension buffer-file-name)) - (`"cc" (funcall search - "\\_<DEFUN\\(?:_DLD\\)?\\s-*(\\s-*\\(\\(?:\\sw\\|\\s_\\)+\\)" 1)) + ("cc" (funcall search + "\\_<DEFUN\\(?:_DLD\\)?\\s-*(\\s-*\\(\\(?:\\sw\\|\\s_\\)+\\)" 1)) (_ (funcall search octave-function-header-regexp 3))))) (defun octave-function-file-p () @@ -1135,19 +1135,19 @@ octave-sync-function-file-names (read-char-choice "Which name to use? (a/b/q) " '(?a ?b ?q)))))) (pcase c - (`?a (let ((newname (expand-file-name - (concat func (file-name-extension - buffer-file-name t))))) - (when (or (not (file-exists-p newname)) - (yes-or-no-p - (format "Target file %s exists; proceed? " newname))) - (when (file-exists-p buffer-file-name) - (rename-file buffer-file-name newname t)) - (set-visited-file-name newname)))) - (`?b (save-excursion - (goto-char name-start) - (delete-region name-start name-end) - (insert file))))))))) + (?a (let ((newname (expand-file-name + (concat func (file-name-extension + buffer-file-name t))))) + (when (or (not (file-exists-p newname)) + (yes-or-no-p + (format "Target file %s exists; proceed? " newname))) + (when (file-exists-p buffer-file-name) + (rename-file buffer-file-name newname t)) + (set-visited-file-name newname)))) + (?b (save-excursion + (goto-char name-start) + (delete-region name-start name-end) + (insert file))))))))) (defun octave-update-function-file-comment (beg end) "Query replace function names in function file comment." @@ -1801,19 +1801,19 @@ octave-find-definition-filename-function (defun octave-find-definition-default-filename (name) "Default value for `octave-find-definition-filename-function'." (pcase (file-name-extension name) - (`"oct" + ("oct" (octave-find-definition-default-filename (concat "libinterp/dldfcn/" (file-name-sans-extension (file-name-nondirectory name)) ".cc"))) - (`"cc" + ("cc" (let ((file (or (locate-file name (octave-source-directories)) (locate-file (file-name-nondirectory name) (octave-source-directories))))) (or (and file (file-exists-p file)) (error "File `%s' not found" name)) file)) - (`"mex" + ("mex" (if (yes-or-no-p (format-message "File `%s' may be binary; open? " (file-name-nondirectory name))) name diff --git a/lisp/progmodes/opascal.el b/lisp/progmodes/opascal.el index 4606621951..7d055b735d 100644 --- a/lisp/progmodes/opascal.el +++ b/lisp/progmodes/opascal.el @@ -393,17 +393,17 @@ opascal-literal-kind (if (null (nth 8 ppss)) (when (looking-at opascal--literal-start-re) (pcase (char-after) - (`?/ 'comment-single-line) - (`?\{ 'comment-multi-line-1) - (`?\( 'comment-multi-line-2) - (`?\' 'string) - (`?\" 'double-quoted-string))) + (?/ 'comment-single-line) + (?\{ 'comment-multi-line-1) + (?\( 'comment-multi-line-2) + (?\' 'string) + (?\" 'double-quoted-string))) (if (nth 3 ppss) ;String. (if (eq (nth 3 ppss) ?\") 'double-quoted-string 'string) (pcase (nth 7 ppss) - (`2 'comment-single-line) - (`1 'comment-multi-line-2) + (2 'comment-single-line) + (1 'comment-multi-line-2) (_ 'comment-multi-line-1)))))))) (defun opascal-literal-start-pattern (literal-kind) diff --git a/lisp/progmodes/perl-mode.el b/lisp/progmodes/perl-mode.el index b96aad7a6e..a61d1adcb7 100644 --- a/lisp/progmodes/perl-mode.el +++ b/lisp/progmodes/perl-mode.el @@ -323,8 +323,8 @@ perl-syntax-propertize-function (cons (car (string-to-syntax "< c")) ;; Remember the names of heredocs found on this line. (cons (cons (pcase (aref name 0) - (`?\\ (substring name 1)) - ((or `?\" `?\' `?\`) (substring name 1 -1)) + (?\\ (substring name 1)) + ((or ?\" ?\' ?\`) (substring name 1 -1)) (_ name)) indented) (cdr st))))))) diff --git a/lisp/progmodes/prolog.el b/lisp/progmodes/prolog.el index 3bcc9bebcd..b530c61f97 100644 --- a/lisp/progmodes/prolog.el +++ b/lisp/progmodes/prolog.el @@ -954,9 +954,9 @@ prolog-smie-rules ;; -> thenrule ;; ; elserule ;; ) - (`(:before . ,(or `"->" `";")) + (`(:before . ,(or "->" ";")) (and (smie-rule-bolp) (smie-rule-parent-p "(") (smie-rule-parent 0))) - (`(:after . ,(or `"->" `"*->")) + (`(:after . ,(or "->" "*->")) ;; We distinguish ;; ;; (a -> @@ -3247,11 +3247,11 @@ prolog-electric--underscore (defun prolog-post-self-insert () (pcase last-command-event - (`?_ (prolog-electric--underscore)) - (`?- (prolog-electric--dash)) - (`?: (prolog-electric--colon)) - ((or `?\( `?\; `?>) (prolog-electric--if-then-else)) - (`?. (prolog-electric--dot)))) + (?_ (prolog-electric--underscore)) + (?- (prolog-electric--dash)) + (?: (prolog-electric--colon)) + ((or ?\( ?\; ?>) (prolog-electric--if-then-else)) + (?. (prolog-electric--dot)))) (defun prolog-find-term (functor arity &optional prefix) "Go to the position at the start of the next occurrence of a term. diff --git a/lisp/progmodes/ruby-mode.el b/lisp/progmodes/ruby-mode.el index fad7bc1fb8..32130cee8e 100644 --- a/lisp/progmodes/ruby-mode.el +++ b/lisp/progmodes/ruby-mode.el @@ -612,7 +612,7 @@ ruby-smie-rules ;; For (invalid) code between switch and case. ;; (if (smie-parent-p "switch") 4) )) - (`(:before . ,(or `"(" `"[" `"{")) + (`(:before . ,(or "(" "[" "{")) (cond ((and (equal token "{") (not (smie-rule-prev-p "(" "{" "[" "," "=>" "=" "return" ";")) @@ -639,7 +639,7 @@ ruby-smie-rules (forward-char -1)) (smie-indent-virtual)) (t (smie-rule-parent)))))) - (`(:after . ,(or `"(" "[" "{")) + (`(:after . ,(or "(" "[" "{")) ;; FIXME: Shouldn't this be the default behavior of ;; `smie-indent-after-keyword'? (save-excursion @@ -660,7 +660,7 @@ ruby-smie-rules (smie-backward-sexp ".") (cons 'column (+ (current-column) ruby-indent-level)))) - (`(:before . ,(or `"else" `"then" `"elsif" `"rescue" `"ensure")) + (`(:before . ,(or "else" "then" "elsif" "rescue" "ensure")) (smie-rule-parent)) (`(:before . "when") ;; Align to the previous `when', but look up the virtual @@ -1544,8 +1544,8 @@ ruby-backward-sexp (cond ((looking-at "\\s)") (goto-char (scan-sexps (1+ (point)) -1)) (pcase (char-before) - (`?% (forward-char -1)) - ((or `?q `?Q `?w `?W `?r `?x) + (?% (forward-char -1)) + ((or ?q ?Q ?w ?W ?r ?x) (if (eq (char-before (1- (point))) ?%) (forward-char -2)))) nil) @@ -1562,13 +1562,13 @@ ruby-backward-sexp (forward-char 1) (while (progn (forward-word-strictly -1) (pcase (char-before) - (`?_ t) - (`?. (forward-char -1) t) - ((or `?$ `?@) + (?_ t) + (?. (forward-char -1) t) + ((or ?$ ?@) (forward-char -1) (and (eq (char-before) (char-after)) (forward-char -1))) - (`?: + (?: (forward-char -1) (eq (char-before) :))))) (if (looking-at ruby-block-end-re) diff --git a/lisp/progmodes/sh-script.el b/lisp/progmodes/sh-script.el index aaa86b5816..46c9e6ee65 100644 --- a/lisp/progmodes/sh-script.el +++ b/lisp/progmodes/sh-script.el @@ -959,8 +959,8 @@ sh--inside-noncommand-expression ;; ((...)) or $((...)) or $[...] or ${...}. Nested ;; parenthesis can occur inside the first of these forms, so ;; parse backward recursively. - (`?\( (eq ?\( (char-before))) - ((or `?\{ `?\[) (eq ?\$ (char-before)))) + (?\( (eq ?\( (char-before))) + ((or ?\{ ?\[) (eq ?\$ (char-before)))) (sh--inside-noncommand-expression (1- (point)))))))) (defun sh-font-lock-open-heredoc (start string eol) @@ -2038,7 +2038,7 @@ sh-smie-sh-rules (`(:elem . basic) sh-basic-offset) (`(:after . "case-)") (- (sh-var-value 'sh-indent-for-case-alt) (sh-var-value 'sh-indent-for-case-label))) - (`(:before . ,(or `"(" `"{" `"[" "while" "if" "for" "case")) + (`(:before . ,(or "(" "{" "[" "while" "if" "for" "case")) (if (not (smie-rule-prev-p "&&" "||" "|")) (when (smie-rule-hanging-p) (smie-rule-parent)) @@ -2047,11 +2047,11 @@ sh-smie-sh-rules `(column . ,(smie-indent-virtual))))) ;; FIXME: Maybe this handling of ;; should be made into ;; a smie-rule-terminator function that takes the substitute ";" as arg. - (`(:before . ,(or `";;" `";&" `";;&")) + (`(:before . ,(or ";;" ";&" ";;&")) (if (and (smie-rule-bolp) (looking-at ";;?&?[ \t]*\\(#\\|$\\)")) (cons 'column (smie-indent-keyword ";")) (smie-rule-separator kind))) - (`(:after . ,(or `";;" `";&" `";;&")) + (`(:after . ,(or ";;" ";&" ";;&")) (with-demoted-errors (smie-backward-sexp token) (cons 'column @@ -2062,7 +2062,7 @@ sh-smie-sh-rules (smie-rule-bolp)))) (current-column) (smie-indent-calculate))))) - (`(:before . ,(or `"|" `"&&" `"||")) + (`(:before . ,(or "|" "&&" "||")) (unless (smie-rule-parent-p token) (smie-backward-sexp token) `(column . ,(+ (funcall smie-rules-function :elem 'basic) @@ -2081,7 +2081,7 @@ sh-smie-sh-rules ;; sh-indent-after-done: aligned completely differently. (`(:after . "in") (sh-var-value 'sh-indent-for-case-label)) ;; sh-indent-for-continuation: Line continuations are handled differently. - (`(:after . ,(or `"(" `"{" `"[")) + (`(:after . ,(or "(" "{" "[")) (if (not (looking-at ".[ \t]*[^\n \t#]")) (sh-var-value 'sh-indent-after-open) (goto-char (1- (match-end 0))) @@ -2253,7 +2253,7 @@ sh-smie-rc-rules (save-excursion (when (sh-smie--rc-after-special-arg-p) `(column . ,(current-column))))) - (`(:before . ,(or `"(" `"{" `"[")) + (`(:before . ,(or "(" "{" "[")) (if (smie-rule-hanging-p) (smie-rule-parent))) ;; FIXME: SMIE parses "if (exp) cmd" as "(if ((exp) cmd))" so "cmd" is ;; treated as an arg to (exp) by default, which indents it all wrong. @@ -2262,7 +2262,7 @@ sh-smie-rc-rules ;; rule we have is the :list-intro hack, which we use here to align "cmd" ;; with "(exp)", which is rarely the right thing to do, but is better ;; than nothing. - (`(:list-intro . ,(or `"for" `"if" `"while")) t) + (`(:list-intro . ,(or "for" "if" "while")) t) ;; sh-indent-after-switch: handled implicitly by the default { rule. )) diff --git a/lisp/server.el b/lisp/server.el index 50684a20aa..d0a8ca313e 100644 --- a/lisp/server.el +++ b/lisp/server.el @@ -1112,16 +1112,16 @@ server-execute-continuation (while args-left (pcase (pop args-left) ;; -version CLIENT-VERSION: obsolete at birth. - (`"-version" (pop args-left)) + ("-version" (pop args-left)) ;; -nowait: Emacsclient won't wait for a result. - (`"-nowait" (setq nowait t)) + ("-nowait" (setq nowait t)) ;; -current-frame: Don't create frames. - (`"-current-frame" (setq use-current-frame t)) + ("-current-frame" (setq use-current-frame t)) ;; -frame-parameters: Set frame parameters - (`"-frame-parameters" + ("-frame-parameters" (let ((alist (pop args-left))) (if coding-system (setq alist (decode-coding-string alist coding-system))) @@ -1129,24 +1129,24 @@ server-execute-continuation ;; -display DISPLAY: ;; Open X frames on the given display instead of the default. - (`"-display" + ("-display" (setq display (pop args-left)) (if (zerop (length display)) (setq display nil))) ;; -parent-id ID: ;; Open X frame within window ID, via XEmbed. - (`"-parent-id" + ("-parent-id" (setq parent-id (pop args-left)) (if (zerop (length parent-id)) (setq parent-id nil))) ;; -window-system: Open a new X frame. - (`"-window-system" + ("-window-system" (if (fboundp 'x-create-frame) (setq dontkill t tty-name 'window-system))) ;; -resume: Resume a suspended tty frame. - (`"-resume" + ("-resume" (let ((terminal (process-get proc 'terminal))) (setq dontkill t) (push (lambda () @@ -1157,7 +1157,7 @@ server-execute-continuation ;; -suspend: Suspend the client's frame. (In case we ;; get out of sync, and a C-z sends a SIGTSTP to ;; emacsclient.) - (`"-suspend" + ("-suspend" (let ((terminal (process-get proc 'terminal))) (setq dontkill t) (push (lambda () @@ -1167,13 +1167,13 @@ server-execute-continuation ;; -ignore COMMENT: Noop; useful for debugging emacsclient. ;; (The given comment appears in the server log.) - (`"-ignore" + ("-ignore" (setq dontkill t) (pop args-left)) ;; -tty DEVICE-NAME TYPE: Open a new tty frame. ;; (But if we see -window-system later, use that.) - (`"-tty" + ("-tty" (setq tty-name (pop args-left) tty-type (pop args-left) dontkill (or dontkill @@ -1192,7 +1192,7 @@ server-execute-continuation ;; -position LINE[:COLUMN]: Set point to the given ;; position in the next file. - (`"-position" + ("-position" (if (not (string-match "\\+\\([0-9]+\\)\\(?::\\([0-9]+\\)\\)?" (car args-left))) (error "Invalid -position command in client args")) @@ -1203,7 +1203,7 @@ server-execute-continuation "")))))) ;; -file FILENAME: Load the given file. - (`"-file" + ("-file" (let ((file (pop args-left))) (if coding-system (setq file (decode-coding-string file coding-system))) @@ -1221,7 +1221,7 @@ server-execute-continuation (setq filepos nil)) ;; -eval EXPR: Evaluate a Lisp expression. - (`"-eval" + ("-eval" (if use-current-frame (setq use-current-frame 'always)) (let ((expr (pop args-left))) @@ -1232,14 +1232,14 @@ server-execute-continuation (setq filepos nil))) ;; -env NAME=VALUE: An environment variable. - (`"-env" + ("-env" (let ((var (pop args-left))) ;; XXX Variables should be encoded as in getenv/setenv. (process-put proc 'env (cons var (process-get proc 'env))))) ;; -dir DIRNAME: The cwd of the emacsclient process. - (`"-dir" + ("-dir" (setq dir (pop args-left)) (if coding-system (setq dir (decode-coding-string dir coding-system))) diff --git a/lisp/subr.el b/lisp/subr.el index 41dc9aa45f..aaf8909e0c 100644 --- a/lisp/subr.el +++ b/lisp/subr.el @@ -4815,7 +4815,7 @@ called-interactively-p i frame nextframe))) (pcase skip (`nil nil) - (`0 t) + (0 t) (_ (setq i (+ i skip -1)) (funcall get-next-frame))))))) ;; Now `frame' should be "the function from which we were called". (pcase (cons frame nextframe) diff --git a/lisp/textmodes/css-mode.el b/lisp/textmodes/css-mode.el index 31ce638b31..63c86317ee 100644 --- a/lisp/textmodes/css-mode.el +++ b/lisp/textmodes/css-mode.el @@ -1219,7 +1219,7 @@ css-smie-rules (`(:elem . basic) css-indent-offset) (`(:elem . arg) 0) ;; "" stands for BOB (bug#15467). - (`(:list-intro . ,(or `";" `"" `":-property")) t) + (`(:list-intro . ,(or ";" "" ":-property")) t) (`(:before . "{") (when (or (smie-rule-hanging-p) (smie-rule-bolp)) (smie-backward-sexp ";") diff --git a/test/lisp/emacs-lisp/pcase-tests.el b/test/lisp/emacs-lisp/pcase-tests.el index 774a488255..c706c1051e 100644 --- a/test/lisp/emacs-lisp/pcase-tests.el +++ b/test/lisp/emacs-lisp/pcase-tests.el @@ -53,7 +53,7 @@ pcase-tests-grep (should (pcase-tests-grep 'memq (macroexpand-all '(pcase x ((or 1 2 3) body))))) (should (pcase-tests-grep - 'member (macroexpand-all '(pcase x ((or '"a" '2 '3) body))))) + 'member (macroexpand-all '(pcase x ((or "a" 2 3) body))))) (should-not (pcase-tests-grep 'memq (macroexpand-all '(pcase x ((or "a" 2 3) body))))) (let ((exp (macroexpand-all -- 2.19.1 [-- Attachment #3: Type: text/plain, Size: 20 bytes --] Thanks, Michael. ^ permalink raw reply related [flat|nested] 375+ messages in thread
* What `case' have done you? [Was: Re: Replace trivial pcase occurrences in the Emacs sources] 2018-10-29 21:46 ` Michael Heerdegen @ 2018-10-30 0:36 ` Garreau, Alexandre 2018-10-30 1:45 ` Michael Heerdegen 2018-10-30 6:31 ` Replace trivial pcase occurrences in the Emacs sources Eli Zaretskii 1 sibling, 1 reply; 375+ messages in thread From: Garreau, Alexandre @ 2018-10-30 0:36 UTC (permalink / raw) To: monnier, Eli Zaretskii; +Cc: Michael Heerdegen, emacs-devel On 2018-10-29 at 22:46, Michael Heerdegen wrote: > + (?y (setq skip t)) > + (?q (keyboard-quit)) > + (?N (setq skip 'no)))))) > + (:group (setq group (pop body))) > + (:abbrev-table (setq abbrev (pop body)) (setq declare-abbrev nil)) > + (:syntax-table (setq syntax (pop body)) (setq declare-syntax nil)) > + ((or 'nil 'public :public) nil) > + ((or 'protected :protected) 'protected) > + ((or 'private :private) 'private) There are quite some (long) cases where only matching characters or symbols: is it really that problematic to use `case' (though, in such common functions body, I wouldn’t find cond+assoc natural either)? I’m uncomfortable to make elisp, like ocaml, the kind of language where if you want the equivalent of a switch, etc. you’d need the pattern matching facility. That’s excessive promotion of pattern matching I find. And `case' wasn’t invented for no purpose: it already existed in common lisp and many lisps, and would perfectly fit there, why invisibilizing it so much, even for cases it works? Why is everybody banning so much that hard `case' from elisp common usage? ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: What `case' have done you? [Was: Re: Replace trivial pcase occurrences in the Emacs sources] 2018-10-30 0:36 ` What `case' have done you? [Was: Re: Replace trivial pcase occurrences in the Emacs sources] Garreau, Alexandre @ 2018-10-30 1:45 ` Michael Heerdegen 0 siblings, 0 replies; 375+ messages in thread From: Michael Heerdegen @ 2018-10-30 1:45 UTC (permalink / raw) To: Garreau, Alexandre; +Cc: Eli Zaretskii, monnier, emacs-devel "Garreau, Alexandre" <galex-713@galex-713.eu> writes: > There are quite some (long) cases where only matching characters or > symbols: is it really that problematic to use `case' (though, in such > common functions body, I wouldn’t find cond+assoc natural either)? That's what we discuss here. However, the suggested patch isn't meant to answer this question. I only want to clear up some pcase occurrences. If developers later decide to replace such occurrences with case or whatever, I can still do it. Michael. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-29 21:46 ` Michael Heerdegen 2018-10-30 0:36 ` What `case' have done you? [Was: Re: Replace trivial pcase occurrences in the Emacs sources] Garreau, Alexandre @ 2018-10-30 6:31 ` Eli Zaretskii 2018-10-30 15:47 ` Michael Heerdegen 1 sibling, 1 reply; 375+ messages in thread From: Eli Zaretskii @ 2018-10-30 6:31 UTC (permalink / raw) To: Michael Heerdegen; +Cc: monnier, emacs-devel > From: Michael Heerdegen <michael_heerdegen@web.de> > Cc: monnier@iro.umontreal.ca, emacs-devel@gnu.org > Date: Mon, 29 Oct 2018 22:46:54 +0100 > > > IOW, a list of all changed files, with the description at the end. > > Ok, done. I kept the description as commit message however, since I > need one. I never meant to say you should discard one. > Ok to install (the patch itself is unchanged)? Fine with me, thanks. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-30 6:31 ` Replace trivial pcase occurrences in the Emacs sources Eli Zaretskii @ 2018-10-30 15:47 ` Michael Heerdegen 2018-10-30 17:29 ` Eli Zaretskii 0 siblings, 1 reply; 375+ messages in thread From: Michael Heerdegen @ 2018-10-30 15:47 UTC (permalink / raw) To: Eli Zaretskii; +Cc: monnier, emacs-devel Eli Zaretskii <eliz@gnu.org> writes: > > Ok to install (the patch itself is unchanged)? > > Fine with me, thanks. Installed as 049bd5d2 "Don't quote self-quoting pcase patterns". Shall I now work on the `DOESNT-UNQUOTE -> 'DOESNT-UNQUOTE patch? Michael. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-30 15:47 ` Michael Heerdegen @ 2018-10-30 17:29 ` Eli Zaretskii 2018-10-30 22:09 ` Michael Heerdegen 0 siblings, 1 reply; 375+ messages in thread From: Eli Zaretskii @ 2018-10-30 17:29 UTC (permalink / raw) To: Michael Heerdegen; +Cc: monnier, emacs-devel > From: Michael Heerdegen <michael_heerdegen@web.de> > Cc: monnier@iro.umontreal.ca, emacs-devel@gnu.org > Date: Tue, 30 Oct 2018 16:47:45 +0100 > > Shall I now work on the `DOESNT-UNQUOTE -> 'DOESNT-UNQUOTE patch? Yes, I think so. TIA ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-30 17:29 ` Eli Zaretskii @ 2018-10-30 22:09 ` Michael Heerdegen 2018-10-31 15:59 ` Eli Zaretskii 0 siblings, 1 reply; 375+ messages in thread From: Michael Heerdegen @ 2018-10-30 22:09 UTC (permalink / raw) To: Eli Zaretskii; +Cc: monnier, emacs-devel Eli Zaretskii <eliz@gnu.org> writes: > > Shall I now work on the `DOESNT-UNQUOTE -> 'DOESNT-UNQUOTE patch? > Yes, I think so. I noticed that only about a half of these are pcase patterns. All other occurrences are in "normal" code. I wonder if I should fix them all at once (would be a bit less work for me)? We speak about somewhat over 1000 occurrences. BTW, while preparing the first patch I already found tons of unnecessary quotes outside of pcase patterns: quotes quoting self-evaluating objects like strings and numbers. Michael. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-30 22:09 ` Michael Heerdegen @ 2018-10-31 15:59 ` Eli Zaretskii 2018-10-31 19:37 ` Stefan Monnier 2018-10-31 20:31 ` Michael Heerdegen 0 siblings, 2 replies; 375+ messages in thread From: Eli Zaretskii @ 2018-10-31 15:59 UTC (permalink / raw) To: Michael Heerdegen; +Cc: monnier, emacs-devel > From: Michael Heerdegen <michael_heerdegen@web.de> > Cc: monnier@iro.umontreal.ca, emacs-devel@gnu.org > Date: Tue, 30 Oct 2018 23:09:47 +0100 > > Eli Zaretskii <eliz@gnu.org> writes: > > > > Shall I now work on the `DOESNT-UNQUOTE -> 'DOESNT-UNQUOTE patch? > > Yes, I think so. > > I noticed that only about a half of these are pcase patterns. All other > occurrences are in "normal" code. I wonder if I should fix them all at > once (would be a bit less work for me)? We speak about somewhat over > 1000 occurrences. Not sure I follow: fixing _all_ of them will be _less_ work for you? I'm okay with only fixing pcase usage at this time, if you feel that would be enough for one changeset. > BTW, while preparing the first patch I already found tons of unnecessary > quotes outside of pcase patterns: quotes quoting self-evaluating objects > like strings and numbers. Really? Can you show a few examples? Maybe there's something wrong with our documentation if people make such mistakes. Thanks. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-31 15:59 ` Eli Zaretskii @ 2018-10-31 19:37 ` Stefan Monnier 2018-10-31 20:31 ` Michael Heerdegen 1 sibling, 0 replies; 375+ messages in thread From: Stefan Monnier @ 2018-10-31 19:37 UTC (permalink / raw) To: Eli Zaretskii; +Cc: Michael Heerdegen, emacs-devel > Really? Can you show a few examples? Maybe there's something wrong > with our documentation if people make such mistakes. I don't think calling them mistakes is right. It might just be a stylistic preference on the part of the author, or it can be the result of evolution of code (where the data started as non-self-quoting and the quote wasn't removed when the data changed), but it still perfectly valid. Stefan ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-31 15:59 ` Eli Zaretskii 2018-10-31 19:37 ` Stefan Monnier @ 2018-10-31 20:31 ` Michael Heerdegen 2018-10-31 23:33 ` Garreau, Alexandre ` (3 more replies) 1 sibling, 4 replies; 375+ messages in thread From: Michael Heerdegen @ 2018-10-31 20:31 UTC (permalink / raw) To: Eli Zaretskii; +Cc: monnier, emacs-devel [-- Attachment #1: Type: text/plain, Size: 1243 bytes --] Eli Zaretskii <eliz@gnu.org> writes: > > I noticed that only about a half of these are pcase patterns. All > > other occurrences are in "normal" code. I wonder if I should fix > > them all at once (would be a bit less work for me)? We speak about > > somewhat over 1000 occurrences. > > Not sure I follow: fixing _all_ of them will be _less_ work for you? I mean less work in summa. > I'm okay with only fixing pcase usage at this time, if you feel that > would be enough for one changeset. It would be ok for me to do both at once if that's also ok for you. > > BTW, while preparing the first patch I already found tons of > > unnecessary quotes outside of pcase patterns: quotes quoting > > self-evaluating objects like strings and numbers. > > Really? Can you show a few examples? Maybe there's something wrong > with our documentation if people make such mistakes. Here is the result of a quick search. As Stefan said, I don't say we should fix (all of) these. But some really look strange. There are many quoted strings - I wonder if these quotes change the behavior of the compiler or so? I tiny fraction of the matches may be cases where the quote is significant, e.g. when located in a quoted structure, like in '('1). [-- Attachment #2: un-quoted.txt --] [-- Type: text/plain, Size: 15416 bytes --] ;;; ** Search the Emacs Elisp sources for `',(or (pred keywordp) (pred numberp) (pred stringp)) ;;; ** 509 matches in 50 files: ;;; *** /home/micha/software/emacs/lisp/allout.el (1 match) ;;;; Line 5138 ': ;;; *** /home/micha/software/emacs/lisp/cus-edit.el (2 matches) ;;;; Line 4711 ':style ;;;; Line 4712 ':selected ;;; *** /home/micha/software/emacs/lisp/cus-load.el (154 matches) ;;;; Line 929 '"20.4" ;;;; Line 931 '"21.1" ;;;; Line 933 '"21.1" ;;;; Line 941 '"23.1" ;;;; Line 943 '"21.1" ;;;; Line 945 '"21.1" ;;;; Line 947 '"20.3" ;;;; Line 949 '"22.1" ;;;; Line 951 '"20.3" ;;;; Line 953 '"22.1" ;;;; Line 955 '"21.1" ;;;; Line 957 '"21.1" ;;;; Line 959 '"22.2" ;;;; Line 961 '"20" ;;;; Line 964 '"20" ;;;; Line 967 '"20" ;;;; Line 970 '"20" ;;;; Line 973 '"20" ;;;; Line 976 '"20" ;;;; Line 979 '"20" ;;;; Line 982 '"20" ;;;; Line 985 '"20" ;;;; Line 988 '"20" ;;;; Line 991 '"20" ;;;; Line 993 '"21.1" ;;;; Line 995 '"21.1" ;;;; Line 997 '"24.1" ;;;; Line 999 '"23.1" ;;;; Line 1001 '"23.1" ;;;; Line 1003 '"23.1" ;;;; Line 1006 '"24.3" ;;;; Line 1008 '"24.3" ;;;; Line 1010 '"21.1" ;;;; Line 1015 '"21.1" ;;;; Line 1017 '"25.1" ;;;; Line 1019 '"22.1" ;;;; Line 1021 '"23.1" ;;;; Line 1023 '"21.1" ;;;; Line 1025 '"21.1" ;;;; Line 1027 '"20.3" ;;;; Line 1029 '"23.2" ;;;; Line 1031 '"23.2" ;;;; Line 1033 '"23.2" ;;;; Line 1035 '"20.3" ;;;; Line 1037 '"21.1" ;;;; Line 1039 '"22.1" ;;;; Line 1041 '"21.1" ;;;; Line 1043 '"25.1" ;;;; Line 1045 '"22.1" ;;;; Line 1047 '"22.1" ;;;; Line 1049 '"24.4" ;;;; Line 1051 '"24.4" ;;;; Line 1053 '"24.3" ;;;; Line 1055 '"22.1" ;;;; Line 1057 '"22.1" ;;;; Line 1059 '"24.1" ;;;; Line 1061 '"24.1" ;;;; Line 1063 '"22.1" ;;;; Line 1065 '"22.1" ;;;; Line 1070 '"22.1" ;;;; Line 1072 '"22.1" ;;;; Line 1074 '"21.1" ;;;; Line 1076 '"22.1" ;;;; Line 1078 '"22.1" ;;;; Line 1080 '"21.1" ;;;; Line 1082 '"26.1" ;;;; Line 1084 '"21.1" ;;;; Line 1086 '"21.1" ;;;; Line 1088 '"21.1" ;;;; Line 1090 '"21.1" ;;;; Line 1092 '"20.3" ;;;; Line 1094 '"21.1" ;;;; Line 1096 '"23.1" ;;;; Line 1098 '"20.3" ;;;; Line 1100 '"22.1" ;;;; Line 1102 '"25.1" ;;;; Line 1104 '"25.1" ;;;; Line 1106 '"24.4" ;;;; Line 1108 '"24.2" ;;;; Line 1111 '"24.4" ;;;; Line 1114 '"24.4" ;;;; Line 1117 '"24.4" ;;;; Line 1120 '"22.1" ;;;; Line 1126 '"24.1" ;;;; Line 1128 '"21.1" ;;;; Line 1130 '"21.1" ;;;; Line 1132 '"24.1" ;;;; Line 1134 '"20" ;;;; Line 1137 '"22.1" ;;;; Line 1140 '"24.3" ;;;; Line 1142 '"24.3" ;;;; Line 1144 '"25.1" ;;;; Line 1146 '"20" ;;;; Line 1148 '"20" ;;;; Line 1151 '"20" ;;;; Line 1154 '"20" ;;;; Line 1157 '"20" ;;;; Line 1160 '"20" ;;;; Line 1163 '"20" ;;;; Line 1166 '"20" ;;;; Line 1169 '"20" ;;;; Line 1172 '"20" ;;;; Line 1175 '"20" ;;;; Line 1178 '"20" ;;;; Line 1181 '"20" ;;;; Line 1184 '"24.3" ;;;; Line 1186 '"26.1" ;;;; Line 1188 '"21.1" ;;;; Line 1190 '"22.1" ;;;; Line 1192 '"21.1" ;;;; Line 1194 '"25.1" ;;;; Line 1196 '"23.1" ;;;; Line 1198 '"21.1" ;;;; Line 1200 '"21.1" ;;;; Line 1203 '"21.1" ;;;; Line 1205 '"21.1" ;;;; Line 1207 '"22.1" ;;;; Line 1209 '"22.1" ;;;; Line 1211 '"21.1" ;;;; Line 1214 '"25.1" ;;;; Line 1216 '"22.1" ;;;; Line 1218 '"20.4" ;;;; Line 1220 '"24.1" ;;;; Line 1222 '"22.2" ;;;; Line 1224 '"22.1" ;;;; Line 1229 '"22.1" ;;;; Line 1232 '"21.1" ;;;; Line 1234 '"22.1" ;;;; Line 1236 '"21.1" ;;;; Line 1238 '"24.4" ;;;; Line 1240 '"24.4" ;;;; Line 1242 '"24.4" ;;;; Line 1244 '"24.4" ;;;; Line 1246 '"24.4" ;;;; Line 1248 '"24.4" ;;;; Line 1250 '"22.1" ;;;; Line 1252 '"22.1" ;;;; Line 1254 '"22.1" ;;;; Line 1256 '"22.2" ;;;; Line 1258 '"24.1" ;;;; Line 1260 '"24.1" ;;;; Line 1262 '"24.1" ;;;; Line 1264 '"24.1" ;;;; Line 1266 '"24.1" ;;;; Line 1268 '"24.1" ;;;; Line 1270 '"25.1" ;;;; Line 1272 '"24.1" ;;;; Line 1274 '"22.2" ;;;; Line 1276 '"22.2" ;;;; Line 1278 '"22.1" ;;;; Line 1280 '"22.1" ;;;; Line 1282 '"23.1" ;;;; Line 1284 '"21.1" ;;;; Line 1286 '"25.1" ;;; *** /home/micha/software/emacs/lisp/descr-text.el (1 match) ;;;; Line 684 '#xa0 ;;; *** /home/micha/software/emacs/lisp/ezimage.el (1 match) ;;;; Line 105 ':file ;;; *** /home/micha/software/emacs/lisp/filesets.el (45 matches) ;;;; Line 184 ':test ;;;; Line 1151 ':dirs ;;;; Line 1153 ':files ;;;; Line 1220 ':files ;;;; Line 1236 ':constraintp ;;;; Line 1237 ':constraint-flag ;;;; Line 1289 ':ignore-on-open-all ;;;; Line 1290 ':ignore-on-read-text ;;;; Line 1317 ':capture-output ;;;; Line 1318 ':open-hook ;;;; Line 1319 ':args ;;;; Line 1471 ':open ;;;; Line 1478 ':save ;;;; Line 1482 ':files ;;;; Line 1488 ':files ;;;; Line 1492 ':verbosity ;;;; Line 1496 ':file ;;;; Line 1501 ':pattern ;;;; Line 1517 ':tree ;;;; Line 1521 ':dormant-p ;;;; Line 1524 ':dormant-flag ;;;; Line 1528 ':filter-dirs-flag ;;;; Line 1532 ':tree-max-level ;;;; Line 1536 ':ingroup ;;;; Line 1622 ':ingroup ;;;; Line 1623 ':tree ;;;; Line 1734 ':files ;;;; Line 1741 ':files ;;;; Line 1822 ':files ;;;; Line 1847 ':files ;;;; Line 1860 ':pattern ;;;; Line 1978 ':pattern ;;;; Line 2057 ':pattern ;;;; Line 2058 ':name ;;;; Line 2059 ':preprocess ;;;; Line 2060 ':match-number ;;;; Line 2062 ':scan-depth ;;;; Line 2063 ':case-sensitive ;;;; Line 2065 ':get-file-name ;;;; Line 2066 ':stubp ;;;; Line 2067 ':stub-flag ;;;; Line 2141 ':ingroup ;;;; Line 2155 ':ingroup ;;;; Line 2193 ':tree ;;;; Line 2228 ':tree ;;; *** /home/micha/software/emacs/lisp/info.el (1 match) ;;;; Line 5163 '"(dir)top" ;;; *** /home/micha/software/emacs/lisp/ldefs-boot.el (57 matches) ;;;; Line 393 '3 ;;;; Line 395 '2 ;;;; Line 1993 '1 ;;;; Line 2003 '1 ;;;; Line 2613 '"25.1" ;;;; Line 2680 '"25.1" ;;;; Line 2704 '"25.1" ;;;; Line 2724 '"25.1" ;;;; Line 2744 '"25.1" ;;;; Line 2786 '"25.1" ;;;; Line 3311 '3 ;;;; Line 4378 '3 ;;;; Line 7031 '4 ;;;; Line 8151 '2 ;;;; Line 8182 '2 ;;;; Line 8210 '1 ;;;; Line 8218 '1 ;;;; Line 10217 '"24.5" ;;;; Line 10678 '"25.1" ;;;; Line 11050 '3 ;;;; Line 11052 '2 ;;;; Line 11380 '"25.1" ;;;; Line 11404 '"25.1" ;;;; Line 11428 '"25.1" ;;;; Line 11450 '"25.1" ;;;; Line 11478 '"27.1" ;;;; Line 11501 '"27.1" ;;;; Line 11516 '"25.1" ;;;; Line 12626 '1 ;;;; Line 13969 '1 ;;;; Line 13971 '7 ;;;; Line 14001 '"24.4" ;;;; Line 15482 '2 ;;;; Line 15492 '1 ;;;; Line 15517 '2 ;;;; Line 16855 '1 ;;;; Line 16857 '2 ;;;; Line 16899 '2 ;;;; Line 16901 '3 ;;;; Line 16919 '2 ;;;; Line 16921 '2 ;;;; Line 17811 '3 ;;;; Line 18694 '3 ;;;; Line 19704 '1 ;;;; Line 20396 '"24.1" ;;;; Line 22221 '"23.1" ;;;; Line 25032 '1 ;;;; Line 25040 '1 ;;;; Line 25050 '2 ;;;; Line 25061 '1 ;;;; Line 25073 '1 ;;;; Line 25080 '1 ;;;; Line 25092 '2 ;;;; Line 25094 '3 ;;;; Line 30787 '2 ;;;; Line 37769 '"this function has no effect." ;;;; Line 37769 '"24.1" ;;; *** /home/micha/software/emacs/lisp/loaddefs.el (57 matches) ;;;; Line 393 '3 ;;;; Line 395 '2 ;;;; Line 1993 '1 ;;;; Line 2003 '1 ;;;; Line 2613 '"25.1" ;;;; Line 2680 '"25.1" ;;;; Line 2704 '"25.1" ;;;; Line 2724 '"25.1" ;;;; Line 2744 '"25.1" ;;;; Line 2786 '"25.1" ;;;; Line 3311 '3 ;;;; Line 4378 '3 ;;;; Line 7031 '4 ;;;; Line 8151 '2 ;;;; Line 8182 '2 ;;;; Line 8210 '1 ;;;; Line 8218 '1 ;;;; Line 10217 '"24.5" ;;;; Line 10678 '"25.1" ;;;; Line 11050 '3 ;;;; Line 11052 '2 ;;;; Line 11380 '"25.1" ;;;; Line 11404 '"25.1" ;;;; Line 11428 '"25.1" ;;;; Line 11450 '"25.1" ;;;; Line 11478 '"27.1" ;;;; Line 11501 '"27.1" ;;;; Line 11516 '"25.1" ;;;; Line 12626 '1 ;;;; Line 13969 '1 ;;;; Line 13971 '7 ;;;; Line 14001 '"24.4" ;;;; Line 15482 '2 ;;;; Line 15492 '1 ;;;; Line 15517 '2 ;;;; Line 16855 '1 ;;;; Line 16857 '2 ;;;; Line 16899 '2 ;;;; Line 16901 '3 ;;;; Line 16919 '2 ;;;; Line 16921 '2 ;;;; Line 17811 '3 ;;;; Line 18694 '3 ;;;; Line 19704 '1 ;;;; Line 20396 '"24.1" ;;;; Line 22221 '"23.1" ;;;; Line 25035 '1 ;;;; Line 25043 '1 ;;;; Line 25053 '2 ;;;; Line 25065 '1 ;;;; Line 25078 '1 ;;;; Line 25089 '1 ;;;; Line 25101 '2 ;;;; Line 25103 '3 ;;;; Line 30796 '2 ;;;; Line 37778 '"this function has no effect." ;;;; Line 37778 '"24.1" ;;; *** /home/micha/software/emacs/lisp/xwidget.el (1 match) ;;;; Line 63 ':xwidget ;;; *** /home/micha/software/emacs/lisp/calc/calc-aent.el (2 matches) ;;;; Line 718 '?\. ;;;; Line 721 '?_ ;;; *** /home/micha/software/emacs/lisp/calc/calc-prog.el (1 match) ;;;; Line 1959 ': ;;; *** /home/micha/software/emacs/lisp/cedet/ede/project-am.el (2 matches) ;;;; Line 576 ':default-value ;;;; Line 579 ':default-value ;;; *** /home/micha/software/emacs/lisp/cedet/semantic/bovine/c-by.el (1 match) ;;;; Line 2063 ':pure-virtual-flag ;;; *** /home/micha/software/emacs/lisp/emacs-lisp/cl-extra.el (9 matches) ;;;; Line 479 '8388608e0 ;;;; Line 505 '2e1 ;;;; Line 506 '2e0 ;;;; Line 530 '1e0 ;;;; Line 531 '1e0 ;;;; Line 531 '1e0 ;;;; Line 533 '1e0 ;;;; Line 534 '1e0 ;;;; Line 534 '1e0 ;;; *** /home/micha/software/emacs/lisp/emacs-lisp/cl-loaddefs.el (39 matches) ;;;; Line 317 '3 ;;;; Line 319 '2 ;;;; Line 328 '3 ;;;; Line 330 '2 ;;;; Line 354 '3 ;;;; Line 356 '2 ;;;; Line 370 '2 ;;;; Line 380 '1 ;;;; Line 400 '1 ;;;; Line 408 '1 ;;;; Line 419 '1 ;;;; Line 427 '1 ;;;; Line 441 '1 ;;;; Line 458 '1 ;;;; Line 516 '2 ;;;; Line 541 '2 ;;;; Line 551 '1 ;;;; Line 561 '1 ;;;; Line 595 '1 ;;;; Line 602 '1 ;;;; Line 621 '2 ;;;; Line 637 '1 ;;;; Line 645 '1 ;;;; Line 658 '1 ;;;; Line 666 '1 ;;;; Line 675 '1 ;;;; Line 687 '2 ;;;; Line 698 '1 ;;;; Line 710 '1 ;;;; Line 763 '1 ;;;; Line 772 '1 ;;;; Line 781 '2 ;;;; Line 789 '3 ;;;; Line 801 '2 ;;;; Line 823 '2 ;;;; Line 825 '1 ;;;; Line 875 '2 ;;;; Line 896 '3 ;;;; Line 898 '2 ;;; *** /home/micha/software/emacs/lisp/emacs-lisp/cl-macs.el (1 match) ;;;; Line 2917 ':read-only ;;; *** /home/micha/software/emacs/lisp/emacs-lisp/cl-seq.el (1 match) ;;;; Line 78 (quote :allow-other-keys) ;;; *** /home/micha/software/emacs/lisp/emacs-lisp/eieio-loaddefs.el (7 matches) ;;;; Line 27 '3 ;;;; Line 29 '"25.1" ;;;; Line 59 '3 ;;;; Line 61 '"25.1" ;;;; Line 78 '"24.1" ;;;; Line 85 '"24.1" ;;;; Line 92 '"25.1" ;;; *** /home/micha/software/emacs/lisp/emacs-lisp/ert.el (3 matches) ;;;; Line 121 ':passed ;;;; Line 959 ':failed ;;;; Line 965 ':passed ;;; *** /home/micha/software/emacs/lisp/emacs-lisp/rx.el (4 matches) ;;;; Line 356 ': ;;;; Line 382 ': ;;;; Line 695 ': ;;;; Line 706 ': ;;; *** /home/micha/software/emacs/lisp/erc/erc-stamp.el (1 match) ;;;; Line 265 ':align-to ;;; *** /home/micha/software/emacs/lisp/eshell/esh-module.el (4 matches) ;;;; Line 69 ':tag ;;;; Line 75 ':tag ;;;; Line 77 ':link ;;;; Line 78 ':doc ;;; *** /home/micha/software/emacs/lisp/eshell/esh-opt.el (6 matches) ;;;; Line 106 ':preserve-args ;;;; Line 135 ':show-usage ;;;; Line 149 ':usage ;;;; Line 150 ':external ;;;; Line 151 ':post-usage ;;;; Line 228 ':external ;;; *** /home/micha/software/emacs/lisp/gnus/gnus.el (2 matches) ;;;; Line 2495 ':interactive ;;;; Line 2504 ':interactive ;;; *** /home/micha/software/emacs/lisp/gnus/mail-source.el (2 matches) ;;;; Line 577 ':password ;;;; Line 579 ':password ;;; *** /home/micha/software/emacs/lisp/gnus/nnmail.el (1 match) ;;;; Line 1387 ': ;;; *** /home/micha/software/emacs/lisp/mail/rmail.el (1 match) ;;;; Line 457 ':value ;;; *** /home/micha/software/emacs/lisp/mh-e/mh-e.el (1 match) ;;;; Line 688 ':package-version ;;; *** /home/micha/software/emacs/lisp/mh-e/mh-xface.el (4 matches) ;;;; Line 104 ':data ;;;; Line 110 ':data ;;;; Line 122 ':data ;;;; Line 415 ':data ;;; *** /home/micha/software/emacs/lisp/net/eudc-vars.el (2 matches) ;;;; Line 70 ':tag ;;;; Line 85 ':tag ;;; *** /home/micha/software/emacs/lisp/net/eudc.el (1 match) ;;;; Line 320 ':tag ;;; *** /home/micha/software/emacs/lisp/net/shr.el (1 match) ;;;; Line 1338 ':xlink:href ;;; *** /home/micha/software/emacs/lisp/obsolete/cl-compat.el (3 matches) ;;;; Line 125 ':test-not ;;;; Line 126 ':test ;;;; Line 127 ':key ;;; *** /home/micha/software/emacs/lisp/obsolete/lmenu.el (5 matches) ;;;; Line 95 ':active ;;;; Line 100 ':suffix ;;;; Line 103 ':keys ;;;; Line 106 ':style ;;;; Line 109 ':selected ;;; *** /home/micha/software/emacs/lisp/org/org-loaddefs.el (6 matches) ;;;; Line 149 '1 ;;;; Line 158 '1 ;;;; Line 167 '1 ;;;; Line 176 '1 ;;;; Line 1722 '2 ;;;; Line 1758 '2 ;;; *** /home/micha/software/emacs/lisp/progmodes/ada-prj.el (6 matches) ;;;; Line 553 ':prj-field ;;;; Line 575 ':prj-field ;;;; Line 585 ':prj-field ;;;; Line 601 ':prj-field ;;;; Line 602 ':prj-field ;;;; Line 673 ':prj-field ;;; *** /home/micha/software/emacs/lisp/progmodes/idlwave.el (5 matches) ;;;; Line 4117 ':size ;;;; Line 4117 ':test ;;;; Line 4127 ':size ;;;; Line 4127 ':test ;;;; Line 7126 ':activate-callback ;;; *** /home/micha/software/emacs/lisp/progmodes/ruby-mode.el (3 matches) ;;;; Line 98 '"\\(def\\|class\\|module\\)" ;;;; Line 472 '?w ;;;; Line 476 '?w ;;; *** /home/micha/software/emacs/lisp/progmodes/vhdl-mode.el (46 matches) ;;;; Line 2624 '87 ;;;; Line 3714 '87 ;;;; Line 3716 '87 ;;;; Line 3719 '93 ;;;; Line 3721 '93 ;;;; Line 3724 '08 ;;;; Line 3726 '08 ;;;; Line 5355 '08 ;;;; Line 5361 '08 ;;;; Line 5368 '08 ;;;; Line 5383 '08 ;;;; Line 5388 '08 ;;;; Line 5392 '08 ;;;; Line 5723 '08 ;;;; Line 8863 '87 ;;;; Line 8939 '87 ;;;; Line 8996 '87 ;;;; Line 9055 '87 ;;;; Line 9059 '87 ;;;; Line 9233 '87 ;;;; Line 9274 '87 ;;;; Line 9353 '87 ;;;; Line 9392 '87 ;;;; Line 9398 '87 ;;;; Line 9492 '87 ;;;; Line 9592 '87 ;;;; Line 9837 '87 ;;;; Line 9886 '87 ;;;; Line 9907 '87 ;;;; Line 9945 '08 ;;;; Line 9966 '87 ;;;; Line 10098 '87 ;;;; Line 10312 '87 ;;;; Line 10684 '87 ;;;; Line 10685 '93 ;;;; Line 10686 '08 ;;;; Line 11965 '87 ;;;; Line 11988 '87 ;;;; Line 11991 '87 ;;;; Line 12360 '87 ;;;; Line 12438 '87 ;;;; Line 12696 '87 ;;;; Line 16209 '87 ;;;; Line 16247 '87 ;;;; Line 16254 '87 ;;;; Line 16698 '87 ;;; *** /home/micha/software/emacs/lisp/textmodes/enriched.el (2 matches) ;;;; Line 484 ':foreground ;;;; Line 490 ':background ;;; *** /home/micha/software/emacs/lisp/textmodes/texinfmt.el (1 match) ;;;; Line 1371 '\: ;;; *** /home/micha/software/emacs/lisp/vc/smerge-mode.el (2 matches) ;;;; Line 1121 '?c ;;;; Line 1127 '?c ;;; *** /home/micha/software/emacs/test/lisp/subr-tests.el (4 matches) ;;;; Line 38 (quote 10) ;;;; Line 39 (quote 25) ;;;; Line 47 (quote 25) ;;;; Line 59 (quote "\\<\\(?:\\(?:fals\\|tru\\)e\\)\\>") ;;; *** /home/micha/software/emacs/test/lisp/emacs-lisp/ert-tests.el (2 matches) ;;;; Line 367 ':passed ;;;; Line 429 ':failed ;;; *** /home/micha/software/emacs/test/lisp/emacs-lisp/map-tests.el (1 match) ;;;; Line 77 '2 ;;; *** /home/micha/software/emacs/test/lisp/emacs-lisp/nadvice-tests.el (3 matches) ;;;; Line 54 '5 ;;;; Line 57 '5 ;;;; Line 59 '5 ;;; *** /home/micha/software/emacs/test/lisp/emacs-lisp/pcase-tests.el (2 matches) ;;;; Line 29 '2 ;;;; Line 29 '1 ;;; *** /home/micha/software/emacs/test/lisp/emacs-lisp/package-resources/macro-problem-package-2.0/macro-problem.el (1 match) ;;;; Line 18 '1 ;;; *** /home/micha/software/emacs/test/src/data-tests.el (1 match) ;;;; Line 523 '2 [-- Attachment #3: Type: text/plain, Size: 12 bytes --] Michael. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-31 20:31 ` Michael Heerdegen @ 2018-10-31 23:33 ` Garreau, Alexandre 2018-10-31 23:44 ` Garreau, Alexandre ` (2 subsequent siblings) 3 siblings, 0 replies; 375+ messages in thread From: Garreau, Alexandre @ 2018-10-31 23:33 UTC (permalink / raw) To: Michael Heerdegen; +Cc: Eli Zaretskii, monnier, emacs-devel On 2018-10-31 at 15:37, Stefan Monnier wrote: >> Really? Can you show a few examples? Maybe there's something wrong >> with our documentation if people make such mistakes. > > I don't think calling them mistakes is right. It might just be > a stylistic preference on the part of the author, […] On 2018-10-31 at 21:31, Michael Heerdegen wrote: > Eli Zaretskii <eliz@gnu.org> writes: >> > BTW, while preparing the first patch I already found tons of >> > unnecessary quotes outside of pcase patterns: quotes quoting >> > self-evaluating objects like strings and numbers. >> >> Really? Can you show a few examples? Maybe there's something wrong >> with our documentation if people make such mistakes. > > Here is the result of a quick search. As Stefan said, I don't say we > should fix (all of) these. But some really look strange. There are > many quoted strings - I wonder if these quotes change the behavior of > the compiler or so? I want to notice this kind of questionment is exactly the kind of reasons why such “author stylistic preference” usage should be avoided: because unless a such “stylistic preference”, along with its reason, meanings, and use cases, is formally made explicit somewhere so that its meaning (and use) is clear (but then we will end with yet another non-self-quoting semantic formatting usage (just as “((alist cons key) . (alist cons value list))” and “((alist cons key) alist cons value list)”)) then people will begin to really (hence unacknoweldgly, irrationally, and thus inconsistently) believe this may be kind of special low-level optimization wizard trick, and recopy that without understanding, so that supposed “meaningful stylistic preference” will end up in inconsistent garbage random obfuscation everywhere (I’m exagerating but this is a useless risk). ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-31 20:31 ` Michael Heerdegen 2018-10-31 23:33 ` Garreau, Alexandre @ 2018-10-31 23:44 ` Garreau, Alexandre 2018-10-31 23:58 ` Michael Heerdegen 2018-11-01 4:15 ` Eli Zaretskii 2018-11-01 12:30 ` Stefan Monnier 3 siblings, 1 reply; 375+ messages in thread From: Garreau, Alexandre @ 2018-10-31 23:44 UTC (permalink / raw) To: Michael Heerdegen; +Cc: Eli Zaretskii, monnier, emacs-devel On 2018-10-31 at 21:31, Michael Heerdegen wrote: > ;;; ** Search the Emacs Elisp sources for > `',(or > (pred keywordp) > (pred numberp) > (pred stringp)) > > ;;; ** 509 matches in 50 files: > I believe a “few examples” contexts might be useful: > ;;; *** /home/micha/software/emacs/lisp/allout.el (1 match) > > ;;;; Line 5138 > ': Context: > (cond ((eq curr-elem '*) (allout-show-current-subtree) > (if (> allout-recent-end-of-subtree max-pos) > (setq max-pos allout-recent-end-of-subtree))) > ((eq curr-elem '+) > (if (not (allout-hidden-p)) > (save-excursion (allout-hide-current-subtree t))) > (allout-show-current-branches) > (if (> allout-recent-end-of-subtree max-pos) > (setq max-pos allout-recent-end-of-subtree))) > ((eq curr-elem '-) (allout-show-current-entry)) > ((eq curr-elem ':) > (setq stay t) > ;; Expand the `repeat' spec to an explicit version, > ;; w.r.t. remaining siblings: > ;;; *** /home/micha/software/emacs/lisp/cus-edit.el (2 matches) > > ;;;; Line 4711 > ':style Context: > (widget-put (get 'boolean 'widget-type) > :custom-menu (lambda (_widget symbol) > (vector (custom-unlispify-menu-entry symbol) > `(customize-variable ',symbol) > ':style 'toggle > ':selected symbol))) > ;;; *** /home/micha/software/emacs/lisp/cus-load.el (154 matches) > > ;;;; Line 929 > '"20.4" > > ;;;; Line 931 > '"21.1" Context: > (custom-put-if-not 'SQL 'custom-version '"20.4") > […] > (custom-put-if-not 'align 'custom-version '"21.1") And so on… > ;;; *** /home/micha/software/emacs/lisp/descr-text.el (1 match) > > ;;;; Line 684 > '#xa0 > ((and nobreak-char-display char (eq char '#xa0)) > 'nobreak-space) > ;;; *** /home/micha/software/emacs/lisp/info.el (1 match) > > ;;;; Line 5163 > '"(dir)top" Context: > (setq completions > (Info-speedbar-fetch-file-nodes (or node '"(dir)top")))) > ;;; *** /home/micha/software/emacs/lisp/ldefs-boot.el (57 matches) > > ;;;; Line 393 > '3 Context: > (function-put 'defadvice 'doc-string-elt '3) > ;;; *** /home/micha/software/emacs/lisp/calc/calc-aent.el (2 matches) > > ;;;; Line 718 > '?\. > > ;;;; Line 721 > '?_ Context: > (and (eq ch '?\.) > (eq (string-match "\\.[0-9]" math-exp-str math-exp-pos) > math-exp-pos)) > (and (eq ch '?_) > (eq (string-match "_\\.?[0-9]" math-exp-str math-exp-pos) > math-exp-pos) All the rest is alike. In the end I believe the maximally useful and compact presentation would be one example per type, with context along (most often upper sexp is enough, maybe some lines around too). Suggesting that for el-search. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-31 23:44 ` Garreau, Alexandre @ 2018-10-31 23:58 ` Michael Heerdegen 0 siblings, 0 replies; 375+ messages in thread From: Michael Heerdegen @ 2018-10-31 23:58 UTC (permalink / raw) To: Garreau, Alexandre; +Cc: Eli Zaretskii, monnier, emacs-devel "Garreau, Alexandre" <galex-713@galex-713.eu> writes: > In the end I believe the maximally useful and compact presentation I guess that could also just be a patch with the quotes removed, in this case. Then it's trivial to browse all the occurrences in the files you are interested in. Michael. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-31 20:31 ` Michael Heerdegen 2018-10-31 23:33 ` Garreau, Alexandre 2018-10-31 23:44 ` Garreau, Alexandre @ 2018-11-01 4:15 ` Eli Zaretskii 2018-11-01 12:30 ` Stefan Monnier 3 siblings, 0 replies; 375+ messages in thread From: Eli Zaretskii @ 2018-11-01 4:15 UTC (permalink / raw) To: Michael Heerdegen; +Cc: monnier, emacs-devel > From: Michael Heerdegen <michael_heerdegen@web.de> > Cc: monnier@iro.umontreal.ca, emacs-devel@gnu.org > Date: Wed, 31 Oct 2018 21:31:55 +0100 > > > Not sure I follow: fixing _all_ of them will be _less_ work for you? > > I mean less work in summa. > > > I'm okay with only fixing pcase usage at this time, if you feel that > > would be enough for one changeset. > > It would be ok for me to do both at once if that's also ok for you. It's fine. > > Really? Can you show a few examples? Maybe there's something wrong > > with our documentation if people make such mistakes. > > Here is the result of a quick search. As Stefan said, I don't say we > should fix (all of) these. But some really look strange. There are > many quoted strings - I wonder if these quotes change the behavior of > the compiler or so? I tiny fraction of the matches may be cases where > the quote is significant, e.g. when located in a quoted structure, like > in '('1). I agree that we should fix those. I'm surprised we have so many of them. Thanks. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-31 20:31 ` Michael Heerdegen ` (2 preceding siblings ...) 2018-11-01 4:15 ` Eli Zaretskii @ 2018-11-01 12:30 ` Stefan Monnier 2018-11-01 14:14 ` Michael Heerdegen 3 siblings, 1 reply; 375+ messages in thread From: Stefan Monnier @ 2018-11-01 12:30 UTC (permalink / raw) To: Michael Heerdegen; +Cc: Eli Zaretskii, emacs-devel > ;;; *** /home/micha/software/emacs/lisp/cus-load.el (154 matches) This is a generated file. Stefan ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-11-01 12:30 ` Stefan Monnier @ 2018-11-01 14:14 ` Michael Heerdegen 2018-11-01 14:18 ` Noam Postavsky 0 siblings, 1 reply; 375+ messages in thread From: Michael Heerdegen @ 2018-11-01 14:14 UTC (permalink / raw) To: Stefan Monnier; +Cc: Eli Zaretskii, emacs-devel Stefan Monnier <monnier@IRO.UMontreal.CA> writes: > > ;;; *** /home/micha/software/emacs/lisp/cus-load.el (154 matches) > > This is a generated file. Did you check if it is the only one? Should I just do git clean -xf before preparing the patch? Michael. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-11-01 14:14 ` Michael Heerdegen @ 2018-11-01 14:18 ` Noam Postavsky 2018-11-01 14:20 ` Michael Heerdegen 0 siblings, 1 reply; 375+ messages in thread From: Noam Postavsky @ 2018-11-01 14:18 UTC (permalink / raw) To: Michael Heerdegen; +Cc: Eli Zaretskii, Stefan Monnier, Emacs developers On Thu, 1 Nov 2018 at 10:15, Michael Heerdegen <michael_heerdegen@web.de> wrote: > > Stefan Monnier <monnier@IRO.UMontreal.CA> writes: > > > > ;;; *** /home/micha/software/emacs/lisp/cus-load.el (154 matches) > > > > This is a generated file. > > Did you check if it is the only one? Should I just do git clean -xf > before preparing the patch? I'm pretty sure the *-loaddefs files are also generated. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-11-01 14:18 ` Noam Postavsky @ 2018-11-01 14:20 ` Michael Heerdegen 2018-11-05 1:43 ` Michael Heerdegen 0 siblings, 1 reply; 375+ messages in thread From: Michael Heerdegen @ 2018-11-01 14:20 UTC (permalink / raw) To: Noam Postavsky; +Cc: Eli Zaretskii, Stefan Monnier, Emacs developers Noam Postavsky <npostavs@gmail.com> writes: > I'm pretty sure the *-loaddefs files are also generated. Oh, indeed. But git clean -xf or so should all remove these - right? Michael. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-11-01 14:20 ` Michael Heerdegen @ 2018-11-05 1:43 ` Michael Heerdegen 2018-11-05 1:46 ` Michael Heerdegen 2018-11-05 16:06 ` Eli Zaretskii 0 siblings, 2 replies; 375+ messages in thread From: Michael Heerdegen @ 2018-11-05 1:43 UTC (permalink / raw) To: Emacs developers; +Cc: Eli Zaretskii, Stefan Monnier, Noam Postavsky Michael Heerdegen <michael_heerdegen@web.de> writes: > > I'm pretty sure the *-loaddefs files are also generated. > > Oh, indeed. But git clean -xf or so should all remove these - right? Ok, I did that in my repo to exclude the generated files. I also kept in mind that some files are distributed via Gnu Elpa and 'SOMETHING may not be used there as a pcase pattern. I decided to not perform the 'DOESNT-HAVE-TO-BE-QUOTED replacement: while browsing the matches, I found that this seems to touch personal preferences and personal styles in too many cases. I wouldn't want that somebody would treat my code in such a way. The `DOESNT-UNQUOTE thing is a bit different. It also touches stylistic reasoning, but OTOH confuses people because when the backquote is followed by a list than it's not clear that it's actually just a constant list and not something constructed. Replacing the backquote with a quote can improve readability. OTOH, some people seem to prefer that the body of a macro is always a backquote expression. And that, also recursively in unquoted parts that need to be quoted. Likewise, there are lots of backquoted :type defcustom expressions, and lots of backquoted menu specifications. Of course, lots were also pcase patterns. I tried to filter out those very few cases that could not be replaced with quotes. Hope I found all. For now, I attach a patch were I replaced nearly everything where it was possible. Comments welcome. If we are sure which changes we want to keep, I'll do the final fine-tuning (fixing indentation and comments, if some were shifted, etc.) BTW, some files use backquotes very excessively, mainly lisp/progmodes/verilog-mode.el. I guess verilog consists mainly of backquotes? There were some backquoted function names and lambdas. I replaced the backquote with #' (symbols), and most of the time nothing (lambdas in lexical binding files). I was very conservative with lambdas in files that didn't use lexbind. Finally, the thing I found in lisp/calendar/time-date.el looked like a bug to me I found by accident. I'm attaching the patch. Michael. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-11-05 1:43 ` Michael Heerdegen @ 2018-11-05 1:46 ` Michael Heerdegen 2018-11-05 16:06 ` Eli Zaretskii 1 sibling, 0 replies; 375+ messages in thread From: Michael Heerdegen @ 2018-11-05 1:46 UTC (permalink / raw) To: Emacs developers; +Cc: Eli Zaretskii, Stefan Monnier, Noam Postavsky [-- Attachment #1: Type: text/plain, Size: 206 bytes --] Michael Heerdegen <michael_heerdegen@web.de> writes: > I'm attaching the patch. Gnus refused the send the attachment, it complained about multibyte characters. Trying again with the patch in a tarball. [-- Attachment #2: replace-backquote-patch.tar --] [-- Type: application/x-tar, Size: 368640 bytes --] ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-11-05 1:43 ` Michael Heerdegen 2018-11-05 1:46 ` Michael Heerdegen @ 2018-11-05 16:06 ` Eli Zaretskii 2018-11-06 1:04 ` Michael Heerdegen 1 sibling, 1 reply; 375+ messages in thread From: Eli Zaretskii @ 2018-11-05 16:06 UTC (permalink / raw) To: Michael Heerdegen; +Cc: npostavs, monnier, emacs-devel > From: Michael Heerdegen <michael_heerdegen@web.de> > Cc: Eli Zaretskii <eliz@gnu.org>, Stefan Monnier <monnier@iro.umontreal.ca>, Noam Postavsky <npostavs@gmail.com> > Date: Mon, 05 Nov 2018 02:43:56 +0100 > > For now, I attach a patch were I replaced nearly everything where it was > possible. Comments welcome. If we are sure which changes we want to > keep, I'll do the final fine-tuning (fixing indentation and comments, if > some were shifted, etc.) > > BTW, some files use backquotes very excessively, mainly > lisp/progmodes/verilog-mode.el. I guess verilog consists mainly of > backquotes? > > There were some backquoted function names and lambdas. I replaced the > backquote with #' (symbols), and most of the time nothing (lambdas in > lexical binding files). I was very conservative with lambdas in files > that didn't use lexbind. > > Finally, the thing I found in lisp/calendar/time-date.el looked like a > bug to me I found by accident. > > I'm attaching the patch. I obviously didn't proofread all of the changes, but what I did looked good. Thanks. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-11-05 16:06 ` Eli Zaretskii @ 2018-11-06 1:04 ` Michael Heerdegen 2018-11-25 20:36 ` Michael Heerdegen 0 siblings, 1 reply; 375+ messages in thread From: Michael Heerdegen @ 2018-11-06 1:04 UTC (permalink / raw) To: Eli Zaretskii; +Cc: npostavs, monnier, emacs-devel Eli Zaretskii <eliz@gnu.org> writes: > I obviously didn't proofread all of the changes, but what I did looked > good. Thanks. I'll wait some more days to see whether there are more comments. BTW, I think I'll revert the apparent fix in diff --git a/lisp/calendar/time-date.el b/lisp/calendar/time-date.el index c3898e0257..bb54ad46e3 100644 --- a/lisp/calendar/time-date.el +++ b/lisp/calendar/time-date.el @@ -109,7 +109,7 @@ with-decoded-time-value ,(append `(setq ,pico 0) (when type `(,type 2))))) (type - `(setq type 2)))) + `(setq ,type 2)))) ,(append `(setq ,micro 0) (when pico `(,pico 0)) (when type `(,type 1))))) The affected macro 'with-decoded-time-value' has been obsolete since 25.1, so I would prefer to just leave it as is. It's not used anywhere in Emacs. Michael. ^ permalink raw reply related [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-11-06 1:04 ` Michael Heerdegen @ 2018-11-25 20:36 ` Michael Heerdegen 2018-11-25 20:42 ` Nicolas Goaziou 0 siblings, 1 reply; 375+ messages in thread From: Michael Heerdegen @ 2018-11-25 20:36 UTC (permalink / raw) To: Eli Zaretskii; +Cc: emacs-devel, npostavs, monnier Michael Heerdegen <michael_heerdegen@web.de> writes: > Thanks. I'll wait some more days to see whether there are more > comments. I installed the commit into master. Is there anything else here for me to do? Michael. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-11-25 20:36 ` Michael Heerdegen @ 2018-11-25 20:42 ` Nicolas Goaziou 2018-11-25 21:46 ` Michael Heerdegen 0 siblings, 1 reply; 375+ messages in thread From: Nicolas Goaziou @ 2018-11-25 20:42 UTC (permalink / raw) To: Michael Heerdegen; +Cc: Eli Zaretskii, npostavs, monnier, emacs-devel Hello, Michael Heerdegen <michael_heerdegen@web.de> writes: > Michael Heerdegen <michael_heerdegen@web.de> writes: > >> Thanks. I'll wait some more days to see whether there are more >> comments. > > I installed the commit into master. > > Is there anything else here for me to do? I though you said you were not going to change Org since it was developed out of tree. The problem here is that we still support Emacs 24.4, and correct me if I'm wrong, it still requires ` instead of '. If I'm correct, would it be possible to discard changes made to the Org base? Thank you. Regards, -- Nicolas Goaziou ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-11-25 20:42 ` Nicolas Goaziou @ 2018-11-25 21:46 ` Michael Heerdegen 2018-11-26 3:35 ` Eli Zaretskii 0 siblings, 1 reply; 375+ messages in thread From: Michael Heerdegen @ 2018-11-25 21:46 UTC (permalink / raw) To: Nicolas Goaziou; +Cc: Eli Zaretskii, npostavs, monnier, emacs-devel Nicolas Goaziou <mail@nicolasgoaziou.fr> writes: > I though you said you were not going to change Org since it was > developed out of tree. AFAIR I asked but got no answer, so I thought I was wrong. > The problem here is that we still support Emacs 24.4, and correct me > if I'm wrong, it still requires ` instead of '. If I'm correct, would > it be possible to discard changes made to the Org base? Do all agree that I should revert change for the affected org files? Michael. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-11-25 21:46 ` Michael Heerdegen @ 2018-11-26 3:35 ` Eli Zaretskii 2018-11-26 20:57 ` Michael Heerdegen 0 siblings, 1 reply; 375+ messages in thread From: Eli Zaretskii @ 2018-11-26 3:35 UTC (permalink / raw) To: Michael Heerdegen; +Cc: monnier, npostavs, mail, emacs-devel > From: Michael Heerdegen <michael_heerdegen@web.de> > Cc: Eli Zaretskii <eliz@gnu.org>, emacs-devel@gnu.org, npostavs@gmail.com, monnier@iro.umontreal.ca > Date: Sun, 25 Nov 2018 22:46:42 +0100 > > > The problem here is that we still support Emacs 24.4, and correct me > > if I'm wrong, it still requires ` instead of '. If I'm correct, would > > it be possible to discard changes made to the Org base? > > Do all agree that I should revert change for the affected org files? If that will cause problems in Emacs 24, yes. Thanks. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-11-26 3:35 ` Eli Zaretskii @ 2018-11-26 20:57 ` Michael Heerdegen 2018-11-26 22:05 ` Nicolas Goaziou 2018-11-27 5:35 ` Eli Zaretskii 0 siblings, 2 replies; 375+ messages in thread From: Michael Heerdegen @ 2018-11-26 20:57 UTC (permalink / raw) To: Eli Zaretskii; +Cc: emacs-devel, monnier, mail, npostavs Eli Zaretskii <eliz@gnu.org> writes: > > Do all agree that I should revert change for the affected org files? > > If that will cause problems in Emacs 24, yes. Ok, done in d28118940c "Revert "Replace insignificant backquotes" for Org files". Thanks, Michael. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-11-26 20:57 ` Michael Heerdegen @ 2018-11-26 22:05 ` Nicolas Goaziou 2018-11-27 5:35 ` Eli Zaretskii 1 sibling, 0 replies; 375+ messages in thread From: Nicolas Goaziou @ 2018-11-26 22:05 UTC (permalink / raw) To: Michael Heerdegen; +Cc: Eli Zaretskii, npostavs, monnier, emacs-devel Hello, Michael Heerdegen <michael_heerdegen@web.de> writes: > Eli Zaretskii <eliz@gnu.org> writes: > >> > Do all agree that I should revert change for the affected org files? >> >> If that will cause problems in Emacs 24, yes. > > Ok, done in d28118940c "Revert "Replace insignificant backquotes" for > Org files". Thank you. Regards, -- Nicolas Goaziou ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-11-26 20:57 ` Michael Heerdegen 2018-11-26 22:05 ` Nicolas Goaziou @ 2018-11-27 5:35 ` Eli Zaretskii 1 sibling, 0 replies; 375+ messages in thread From: Eli Zaretskii @ 2018-11-27 5:35 UTC (permalink / raw) To: Michael Heerdegen; +Cc: emacs-devel, monnier, mail, npostavs > From: Michael Heerdegen <michael_heerdegen@web.de> > Cc: monnier@iro.umontreal.ca, npostavs@gmail.com, mail@nicolasgoaziou.fr, emacs-devel@gnu.org > Date: Mon, 26 Nov 2018 21:57:15 +0100 > > Eli Zaretskii <eliz@gnu.org> writes: > > > > Do all agree that I should revert change for the affected org files? > > > > If that will cause problems in Emacs 24, yes. > > Ok, done in d28118940c "Revert "Replace insignificant backquotes" for > Org files". Thanks, and thanks again for working on these cleanups. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-24 15:03 ` Replace trivial pcase occurrences in the Emacs sources Eli Zaretskii 2018-10-24 15:30 ` Michael Heerdegen @ 2018-10-24 15:47 ` Clément Pit-Claudel 2018-10-24 16:00 ` Eli Zaretskii 2018-10-24 16:12 ` Alan Mackenzie 2018-10-24 20:52 ` Stefan Monnier 3 siblings, 1 reply; 375+ messages in thread From: Clément Pit-Claudel @ 2018-10-24 15:47 UTC (permalink / raw) To: emacs-devel On 24/10/2018 11.03, Eli Zaretskii wrote: > Is it because people are too lazy to write (eq a b) as part of 'cond'? > Or is there something else I'm missing? I think some of us (me, at least), just like the forms you posted better :) It's not a matter of lazyness, just preference. The repetition of "eq" in each "cond" branch just looks redundant to me, and I have no trouble reading the pcase forms. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-24 15:47 ` Clément Pit-Claudel @ 2018-10-24 16:00 ` Eli Zaretskii 2018-10-24 19:00 ` Clément Pit-Claudel 0 siblings, 1 reply; 375+ messages in thread From: Eli Zaretskii @ 2018-10-24 16:00 UTC (permalink / raw) To: Clément Pit-Claudel; +Cc: emacs-devel > From: Clément Pit-Claudel <cpitclaudel@gmail.com> > Date: Wed, 24 Oct 2018 11:47:03 -0400 > > On 24/10/2018 11.03, Eli Zaretskii wrote: > > Is it because people are too lazy to write (eq a b) as part of 'cond'? > > Or is there something else I'm missing? > I think some of us (me, at least), just like the forms you posted better :) Which forms? with or without the mistakes? ;-) > The repetition of "eq" in each "cond" branch just looks redundant to me If that's what bugs you, then how about (setq foo (assoc bar '((1 . one) (2 . two) ...))) ? > and I have no trouble reading the pcase forms. Please don't forget those who will read your code. A code is written once, but read many times. It should be readable and self-explanatory. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-24 16:00 ` Eli Zaretskii @ 2018-10-24 19:00 ` Clément Pit-Claudel 2018-10-24 19:09 ` Eli Zaretskii 0 siblings, 1 reply; 375+ messages in thread From: Clément Pit-Claudel @ 2018-10-24 19:00 UTC (permalink / raw) To: Eli Zaretskii; +Cc: emacs-devel On 24/10/2018 12.00, Eli Zaretskii wrote: >> From: Clément Pit-Claudel <cpitclaudel@gmail.com> >> The repetition of "eq" in each "cond" branch just looks redundant to me > > If that's what bugs you, then how about > > (setq foo (assoc bar '((1 . one) (2 . two) ...))) This only works for constant branch bodies, and I find it marginally harder to read (especially if a default value is specified). But I agree that it's not a bad solution when the branch body is constant. For large collections, I imagine you would use a hashtable? Is that how the switch bytecode is implemented? IIUC, cond and pcase will be translated to a switch, but not assoc, even with a constant association list. >> and I have no trouble reading the pcase forms. > > Please don't forget those who will read your code. A code is written > once, but read many times. It should be readable and > self-explanatory. Of course. Note that I mentioned reading the pcase forms, not writing them. I'm just pointing out that there are readers who find pcase more readable than either assoc or cond with eq tests. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-24 19:00 ` Clément Pit-Claudel @ 2018-10-24 19:09 ` Eli Zaretskii 0 siblings, 0 replies; 375+ messages in thread From: Eli Zaretskii @ 2018-10-24 19:09 UTC (permalink / raw) To: Clément Pit-Claudel; +Cc: emacs-devel > Cc: emacs-devel@gnu.org > From: Clément Pit-Claudel <cpitclaudel@gmail.com> > Date: Wed, 24 Oct 2018 15:00:46 -0400 > > For large collections, I imagine you would use a hashtable? I doubt that you will see in practice collections that are so long that assoc is too slow. > > Please don't forget those who will read your code. A code is written > > once, but read many times. It should be readable and > > self-explanatory. > > Of course. Note that I mentioned reading the pcase forms, not writing them. I'm just pointing out that there are readers who find pcase more readable than either assoc or cond with eq tests. I think the complicated quoting (frequently used incorrectly) of pcase makes it harder to read for at least some, if nothing else, because they need to waste time trying to understand what is the reason for using those quotes. I know it happened to me. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-24 15:03 ` Replace trivial pcase occurrences in the Emacs sources Eli Zaretskii 2018-10-24 15:30 ` Michael Heerdegen 2018-10-24 15:47 ` Clément Pit-Claudel @ 2018-10-24 16:12 ` Alan Mackenzie 2018-10-24 20:52 ` Stefan Monnier 3 siblings, 0 replies; 375+ messages in thread From: Alan Mackenzie @ 2018-10-24 16:12 UTC (permalink / raw) To: Eli Zaretskii; +Cc: Stefan Monnier, emacs-devel Hello, Eli. On Wed, Oct 24, 2018 at 18:03:26 +0300, Eli Zaretskii wrote: > > From: Stefan Monnier <monnier@iro.umontreal.ca> > > Date: Tue, 23 Oct 2018 14:12:34 -0400 > > > I think so too, but it seems the majority of developers has a different > > > option, at least in this (old) thread. > > So I guess I'm gonna have to try and argue my case. > > OK, here are the advantages I see for `cl-case`: > FWIW, my main problem is not even with cl-case, it's with 'cond'. It > seems like we have some 'pcase' epidemic, whose first symptom is that > people stop using 'cond' and start using 'pcase' instead. A few > examples: [ .... ] > My favorite is imap.el, which does something like the above in 3 > nested levels. I will spare you the code, you can look it up. > Is it because people are too lazy to write (eq a b) as part of 'cond'? > Or is there something else I'm missing? > You may wonder why I'm bothered by such uses. It's because people are > evidently confused by 'pcase's arcane syntax, and therefore produce > obfuscated code even in the simple usage. For example: [ .... ] I'm somebody else who doesn't like pcase. I don't like the way it has purloined symbols which previously had a strong fixed meaning (``', `,', `and', `or', and possibly more) and rendered them vague and with several context dependent meanings. For an Emacs Lisp beginner, `and' and `or' used to be easy to grasp, once past the concept of short-circuit evaluation. ``' and `,' were somewhat more difficult. Now, given the ambiguity introduced by pcase, they are all much more difficult to understand. The documentation for pcase is now good, but it still gives me a headache to trundle through it. Unless it's changed very recently, that for pcase variants such as pcase-let is still inadequate. I find pcase uses hard to understand, and definitely prefer cond. [ .... ] > We have dozens of such fragments in our codebase, which just makes the > sources harder to read, especially for people who aren't fluent with > 'pcase' (which seems to be the case with many of us). > So I think we should begin by rewriting all of such uses as simple > 'cond', and ask contributors not to use 'pcase' where a simple 'cond' > will do. +1. -- Alan Mackenzie (Nuremberg, Germany). ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-24 15:03 ` Replace trivial pcase occurrences in the Emacs sources Eli Zaretskii ` (2 preceding siblings ...) 2018-10-24 16:12 ` Alan Mackenzie @ 2018-10-24 20:52 ` Stefan Monnier 2018-10-25 7:17 ` Stephen Berman 2018-10-25 14:47 ` Eli Zaretskii 3 siblings, 2 replies; 375+ messages in thread From: Stefan Monnier @ 2018-10-24 20:52 UTC (permalink / raw) To: emacs-devel > (pcase this-param > ('edit (todo-edit-item--text)) > ('header (todo-edit-item--text 'include-header)) > ('multiline (todo-edit-item--text 'multiline)) > ('add/edit (todo-edit-item--text 'comment-edit)) > ('delete (todo-edit-item--text 'comment-delete)) > ('diary (todo-edit-item--diary-inclusion)) > ('nonmarking (todo-edit-item--diary-inclusion 'nonmarking)) > [...] Is the below any better? (cond ((eq this-param 'edit) (todo-edit-item--text)) ((eq this-param 'header) (todo-edit-item--text 'include-header)) ((eq this-param 'multiline) (todo-edit-item--text 'multiline)) ((eq this-paran 'add/edit) (todo-edit-item--text 'comment-edit)) ((eq this-parom 'delete) (todo-edit-item--text 'comment-delete)) ((eq this-param 'diary) (todo-edit-item--diary-inclusion)) ((eq this-param 'nonmarking) (todo-edit-item--diary-inclusion 'nonmarking)) [...] To me, it's more verbose and more complex because you need to double check that the same var is tested each time before you can know that it's equivalent to a C-style `switch`. IOW, I consider rewriting the `cond` to use `pcase` to be a form of "common sub-expression elimination", or reduction of copy&paste. I think rewriting those pcase uses into cond+eq would be equivalent for me to rewriting dolists into while+pop loops (where you similarly can't tell whether the loop advances by a single element each time without consulting the loop body looking for all assignments to the temp var on which the iteration is performed). I prefer pcase to cl-case but I even much more strongly prefer cl-case over cond+eq. > My favorite is imap.el, which does something like the above in 3 > nested levels. I will spare you the code, you can look it up. We clearly have very different programming backgrounds: to me the "case style" is much nicer and easier to read, closer to what I think in my head, whereas the "cond+eq style" is like a "assembly-language" version of the same. > Is it because people are too lazy to write (eq a b) as part of 'cond'? > Or is there something else I'm missing? As a researcher in programming languages, I consider that my job is to design and bring to practitioners tools that let them write in ways that are closer to how they think than to how the machine thinks (while still being able to turn it into something the machine can run efficiently). The above argument of "too lazy to write ..." reminds me of the resistance against the introduction of "high-level languages" instead of the use of assembly language. > You may wonder why I'm bothered by such uses. It's because people are > evidently confused by 'pcase's arcane syntax, and therefore produce > obfuscated code even in the simple usage. For example: > > apropos.el: > > (pcase (car-safe x) > ;; (autoload (push (cdr x) autoloads)) > (`require (push (cdr x) requires)) > (`provide (push (cdr x) provides)) > (`t nil) ; Skip "was an autoload" entries. > ;; FIXME: Print information about each individual method: both > ;; its docstring and specializers (bug#21422). > (`cl-defmethod (push (cadr x) provides)) > (_ (push (or (cdr-safe x) x) symbols)))) > > (Quick: what's the difference between `require and 'require in this > case?) Same difference as between 'require and `require in normal Elisp code. Why is that a problem in pcase and not in the rest of Elisp? [ The story behind this is that the first version of pcase only supported the ` syntax and the syntax was added to provide a "target" for the expansion of ` when ` was made into a pcase-macro rather than a core pcase functionality. ] > easy-mmode.el: > > (pcase keyw > (`:group (setq group (nconc group (list :group (pop keys))))) > (`:global (setq keys (cdr keys))) > (_ (push keyw extra-keywords) (push (pop keys) extra-keywords)))) > > (Aren't keywords supposed to be self-quoting? then why they are > explicitly quoted?) Same reason why keyaords might be (back)quoted in some Elisp code? [ Or maybe also because keywords were originally not self-quoting in pcase macros? ] > So I think we should begin by rewriting all of such uses as simple > 'cond', and ask contributors not to use 'pcase' where a simple 'cond' > will do. From where I stand it would be a very sad step backward. Rewriting those to use ' quoting (or no quoting at all when not needed) is fine (tho not important), but the cond form is clearly inferior IMO. Stefan ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-24 20:52 ` Stefan Monnier @ 2018-10-25 7:17 ` Stephen Berman 2018-10-25 14:47 ` Eli Zaretskii 1 sibling, 0 replies; 375+ messages in thread From: Stephen Berman @ 2018-10-25 7:17 UTC (permalink / raw) To: Stefan Monnier; +Cc: emacs-devel On Wed, 24 Oct 2018 16:52:23 -0400 Stefan Monnier <monnier@iro.umontreal.ca> wrote: >> (pcase this-param >> ('edit (todo-edit-item--text)) >> ('header (todo-edit-item--text 'include-header)) >> ('multiline (todo-edit-item--text 'multiline)) >> ('add/edit (todo-edit-item--text 'comment-edit)) >> ('delete (todo-edit-item--text 'comment-delete)) >> ('diary (todo-edit-item--diary-inclusion)) >> ('nonmarking (todo-edit-item--diary-inclusion 'nonmarking)) >> [...] > > Is the below any better? > > (cond > ((eq this-param 'edit) (todo-edit-item--text)) > ((eq this-param 'header) (todo-edit-item--text 'include-header)) > ((eq this-param 'multiline) (todo-edit-item--text 'multiline)) > ((eq this-paran 'add/edit) (todo-edit-item--text 'comment-edit)) > ((eq this-parom 'delete) (todo-edit-item--text 'comment-delete)) > ((eq this-param 'diary) (todo-edit-item--diary-inclusion)) > ((eq this-param 'nonmarking) (todo-edit-item--diary-inclusion 'nonmarking)) > [...] > > To me, it's more verbose and more complex because you need to double > check that the same var is tested each time before you can know that it's > equivalent to a C-style `switch`. > > IOW, I consider rewriting the `cond` to use `pcase` to be a form of > "common sub-expression elimination", or reduction of copy&paste. FWIW, this is basically the reason I used pcase instead of cond in the above code, it wasn't just to jump on the pcase bandwagon (and it didn't occur to me at the time to use cl-case). Steve Berman ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-24 20:52 ` Stefan Monnier 2018-10-25 7:17 ` Stephen Berman @ 2018-10-25 14:47 ` Eli Zaretskii 2018-10-25 15:32 ` Stefan Monnier 2018-10-27 17:48 ` Garreau, Alexandre 1 sibling, 2 replies; 375+ messages in thread From: Eli Zaretskii @ 2018-10-25 14:47 UTC (permalink / raw) To: Stefan Monnier; +Cc: emacs-devel > From: Stefan Monnier <monnier@iro.umontreal.ca> > Date: Wed, 24 Oct 2018 16:52:23 -0400 > > > (pcase this-param > > ('edit (todo-edit-item--text)) > > ('header (todo-edit-item--text 'include-header)) > > ('multiline (todo-edit-item--text 'multiline)) > > ('add/edit (todo-edit-item--text 'comment-edit)) > > ('delete (todo-edit-item--text 'comment-delete)) > > ('diary (todo-edit-item--diary-inclusion)) > > ('nonmarking (todo-edit-item--diary-inclusion 'nonmarking)) > > [...] > > Is the below any better? > > (cond > ((eq this-param 'edit) (todo-edit-item--text)) > ((eq this-param 'header) (todo-edit-item--text 'include-header)) > ((eq this-param 'multiline) (todo-edit-item--text 'multiline)) > ((eq this-paran 'add/edit) (todo-edit-item--text 'comment-edit)) > ((eq this-parom 'delete) (todo-edit-item--text 'comment-delete)) > ((eq this-param 'diary) (todo-edit-item--diary-inclusion)) > ((eq this-param 'nonmarking) (todo-edit-item--diary-inclusion 'nonmarking)) > [...] Yes (modulo the typos). > To me, it's more verbose and more complex because you need to double > check that the same var is tested each time before you can know that it's > equivalent to a C-style `switch`. But it isn't equivalent to C-style 'switch': it doesn't compare like C does, and it doesn't dispatch like C does. (I find it generally not useful to think in C concepts when programming in Lisp, because it might cause confusion and mistakes.) > IOW, I consider rewriting the `cond` to use `pcase` to be a form of > "common sub-expression elimination", or reduction of copy&paste. Unfortunately, it makes the code more subtle and less self-explanatory. Not for you and me, perhaps, but for quite a few people who aren't as familiar with these macros, it seems. > I think rewriting those pcase uses into cond+eq would be equivalent for > me to rewriting dolists into while+pop loops IMO, it isn't equivalent, because dolist doesn't invent new syntax, not as much as pcase does. > I prefer pcase to cl-case but I even much more strongly prefer cl-case > over cond+eq. The thing is, both cl-case and pcase are subtly different from the "boring" cond, and from each other. E.g., cl-case uses eql to compare, so works with floats, but not with strings; pcase decides what predicate to use according to the data, so works with strings, but strangely doesn't work with floats. Again, perhaps this is not a problem for you and me, but newcomers might well stumble on these subtleties, and at the very least will have to consult the docs to know for sure. By contrast, with cond everything is explicit and self-explanatory. The programmer decides which equality to use. Yes, that does come for a price, but copy-yanking is cheap and fast, as is "M-/", and also avoids typos. > We clearly have very different programming backgrounds: to me the "case > style" is much nicer and easier to read, closer to what I think in > my head, whereas the "cond+eq style" is like a "assembly-language" > version of the same. This isn't about style, this is about using macro facilities to significantly change the syntax of a language. E.g., what do you think about people who use cpp to define macros BEGIN and END that expand into braces? One could argue that it is "closer to what one thinks in their head", or being "higher-level", and yet such practices are generally discouraged. > > (Quick: what's the difference between `require and 'require in this > > case?) > > Same difference as between 'require and `require in normal Elisp code. > Why is that a problem in pcase and not in the rest of Elisp? Because people stumble on this and are likely to waste time trying to understand what kind of magic hides behind this. Worse, they might copy this without understanding (as we already see in our sources), thus proliferating the obfuscation. Mind you: I'm not against pcase where its power is needed. It is IMO needed where using the underlying core facilities would produce something that is hard to follow and even harder to understand. Simple comparisons against a collection of fixed values doesn't fit that bill, IMO. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-25 14:47 ` Eli Zaretskii @ 2018-10-25 15:32 ` Stefan Monnier 2018-10-26 15:34 ` Stefan Monnier 2018-10-27 17:48 ` Garreau, Alexandre 1 sibling, 1 reply; 375+ messages in thread From: Stefan Monnier @ 2018-10-25 15:32 UTC (permalink / raw) To: Eli Zaretskii; +Cc: emacs-devel > Unfortunately, it makes the code more subtle and less > self-explanatory. Not for you and me, perhaps, but for quite a few > people who aren't as familiar with these macros, it seems. I can see why someone would feel this way when looking at a destructuring pcase macro. But for something like: (pcase this-param ('edit (todo-edit-item--text)) ('header (todo-edit-item--text 'include-header)) ('multiline (todo-edit-item--text 'multiline)) ('add/edit (todo-edit-item--text 'comment-edit)) ('delete (todo-edit-item--text 'comment-delete)) I have a hard time believing that there are more users who find it less clear than its cond+eq expansion. > The thing is, both cl-case and pcase are subtly different from the > "boring" cond, and from each other. E.g., cl-case uses eql to > compare, so works with floats, but not with strings; Right. > pcase decides what predicate to use according to the data, No: it uses `equal` (the implementation may optimize it to something else, but the documented behavior is that it compares with `equal` for all patterns of the form 'VAL and for the corresponding accepted shorthands (i.e. non-quoted strings, keywords and integers)). > so works with strings, but strangely doesn't work with floats. Actually it does for a pattern like '4.5 What it doesn't currently is provide the non-quoted shorthand for floats. Maybe it can be considered strange, but at least it rejects such a pattern upfront with an error. Of course, it's trivial to change it to accept non-quoted floats if we want to do it. > Again, perhaps this is not a problem for you and me, but newcomers > might well stumble on these subtleties, and at the very least will > have to consult the docs to know for sure. When reading pcase code, all they need to know is that comparison is done with `equal`, which AFAIK is always the most obvious and natural behavior. Restrictions like non-quoted floats only impact those rare people which will *write* a pcase pattern in which they want to put a float. > By contrast, with cond everything is explicit and self-explanatory. Every *step* is self-explanatory, but the overall goal is not: as a reader, I have to scrutinize every condition to see if the overall goal was indeed to "dispatch based on the value of X". >> We clearly have very different programming backgrounds: to me the "case >> style" is much nicer and easier to read, closer to what I think in >> my head, whereas the "cond+eq style" is like a "assembly-language" >> version of the same. > This isn't about style, this is about using macro facilities to > significantly change the syntax of a language. `pcase` doesn't just change the syntax of cond+eq, like your BEGIN/END example. Instead it provides a new abstraction. Stefan ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-25 15:32 ` Stefan Monnier @ 2018-10-26 15:34 ` Stefan Monnier 0 siblings, 0 replies; 375+ messages in thread From: Stefan Monnier @ 2018-10-26 15:34 UTC (permalink / raw) To: Eli Zaretskii; +Cc: emacs-devel > (pcase this-param > ('edit (todo-edit-item--text)) > ('header (todo-edit-item--text 'include-header)) > ('multiline (todo-edit-item--text 'multiline)) > ('add/edit (todo-edit-item--text 'comment-edit)) > ('delete (todo-edit-item--text 'comment-delete)) > > I have a hard time believing that there are more users who find it less > clear than its cond+eq expansion. BTW, I just bumped into another benefit of `pcase` for such code: When I converted a particular cond+eq thingy yesterday, pcase gave me a warning about redundant pattern, because indeed one of the original `cond` branches was unreachable. Stefan ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-25 14:47 ` Eli Zaretskii 2018-10-25 15:32 ` Stefan Monnier @ 2018-10-27 17:48 ` Garreau, Alexandre 1 sibling, 0 replies; 375+ messages in thread From: Garreau, Alexandre @ 2018-10-27 17:48 UTC (permalink / raw) To: Eli Zaretskii; +Cc: Stefan Monnier, emacs-devel On 2018-10-25 at 17:47, Eli Zaretskii wrote: >> From: Stefan Monnier <monnier@iro.umontreal.ca> >> Date: Wed, 24 Oct 2018 16:52:23 -0400 > >> To me, it's more verbose and more complex because you need to double >> check that the same var is tested each time before you can know that it's >> equivalent to a C-style `switch`. > > But it isn't equivalent to C-style 'switch': it doesn't compare like C > does, and it doesn't dispatch like C does. Is this about the fact you need “break” in C to get the same behavior? Then a lot of programmers “as a good style” put it at the end of each case, because they don’t even know they can do otherwise, and what does that actually mean. > (I find it generally not useful to think in C concepts when > programming in Lisp, because it might cause confusion and mistakes.) Maybe it’s more a matter of programming habits than of C concepts. And factorizing conditionals seems to be a pretty common thing. > By contrast, with cond everything is explicit and self-explanatory. > The programmer decides which equality to use. Yes, that does come for > a price, but copy-yanking is cheap and fast, as is "M-/", and also > avoids typos. People also have a habit of defining macros to factorize code so that to match their thinking and expression of what they want to achieve: that’s why I and many others end writing new personal conditional such as case*. But these not being standard, they’re way less explicit and self-explanatory, as each re-definition will potentially loose unaware people, be incompatible with others, and will be more of a burden for readers of programs using them. While encouraging mainline and standard forms for common subexpressions elimination make people use them instead of making up their own, and therefore make their software easier to read. >> We clearly have very different programming backgrounds: to me the "case >> style" is much nicer and easier to read, closer to what I think in >> my head, whereas the "cond+eq style" is like a "assembly-language" >> version of the same. > > This isn't about style, this is about using macro facilities to > significantly change the syntax of a language. > > E.g., what do you think about people who use cpp to define macros > BEGIN and END that expand into braces? One could argue that it is > "closer to what one thinks in their head", or being "higher-level", > and yet such practices are generally discouraged. Because each one of these have real advantages as well as disadvantages, and, more importantly, neither of them is more clearly expressible as a composition of the other, compared to the other way around (eg. you can translate BEGIN END to { } or the other way around, none of both is more simple, natural or straightforward than the other). While this is clearly the case for pcase, cl-case, and finally cond, as each one of them can be more easily defined on top of, respectively, case, cond, and if. So the former are higher-level while the later are lower-level. Level is more a question of abstraction rather than (subjective) thinking. >> I prefer pcase to cl-case but I even much more strongly prefer cl-case >> over cond+eq. > > The thing is, both cl-case and pcase are subtly different from the > "boring" cond, and from each other. E.g., cl-case uses eql to > compare, so works with floats, but not with strings; >> > (Quick: what's the difference between `require and 'require in this >> > case?) >> >> Same difference as between 'require and `require in normal Elisp code. >> Why is that a problem in pcase and not in the rest of Elisp? > > Because people stumble on this and are likely to waste time trying to > understand what kind of magic hides behind this. Worse, they might > copy this without understanding (as we already see in our sources), > thus proliferating the obfuscation. > > Mind you: I'm not against pcase where its power is needed. It is IMO > needed where using the underlying core facilities would produce > something that is hard to follow and even harder to understand. > Simple comparisons against a collection of fixed values doesn't fit > that bill, IMO. cl-case does, imho. I’d appreciate, as well as others, I think, an official version with equal (case-equal, or casequal maybe?), or even a more general version (with as second argument the test function to use): either named case* (I recall having seen somewhere the convention of appending a “*” for the general version (that asked for a test function) of a comparision form, do anyone know where it might come from? as I’m now unable to find it again), or maybe using a :test and :test-not keywords. Maybe even a version not quoting its keylists? ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-23 17:14 ` Replace trivial pcase occurrences in the Emacs sources Stefan Monnier 2018-10-23 17:24 ` Michael Heerdegen @ 2018-10-24 4:51 ` Richard Stallman 2018-10-24 8:34 ` Joost Kremers 2018-10-24 10:16 ` Replace trivial pcase occurrences in the Emacs sources João Távora 1 sibling, 2 replies; 375+ messages in thread From: Richard Stallman @ 2018-10-24 4:51 UTC (permalink / raw) To: Stefan Monnier; +Cc: michael_heerdegen, eliz, emacs-devel [[[ 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. ]]] > In what sense is the above cl-case more clear than the pcase equivalent? > I'm not saying the pcase version is better in those cases, but I think > the respective advantages and disadvantages pretty much balance out. I also wonder. Is it simply that people find pcase unfamiliar? -- Dr Richard Stallman President, Free Software Foundation (https://gnu.org, https://fsf.org) Internet Hall-of-Famer (https://internethalloffame.org) ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-24 4:51 ` Richard Stallman @ 2018-10-24 8:34 ` Joost Kremers 2018-10-24 12:37 ` Stefan Monnier 2018-10-24 13:03 ` pcase pattern syntax (was: Replace trivial pcase occurrences in the Emacs sources) Stefan Monnier 2018-10-24 10:16 ` Replace trivial pcase occurrences in the Emacs sources João Távora 1 sibling, 2 replies; 375+ messages in thread From: Joost Kremers @ 2018-10-24 8:34 UTC (permalink / raw) To: Richard Stallman On Wed, Oct 24, 2018 at 12:51:35AM -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. ]]] > > > In what sense is the above cl-case more clear than the pcase equivalent? > > I'm not saying the pcase version is better in those cases, but I think > > the respective advantages and disadvantages pretty much balance out. > > I also wonder. Is it simply that people find pcase unfamiliar? Well, I can't speak for others, but personally, though I find pattern matching as a concept straightforward and intuitive, pcase syntax seems unnecessarily complex and unintuitive. For example, John Wiegley's tutorial on pcase at <http://newartisans.com/2016/01/pattern-matching-with-pcase/> has the following example: ``` (pcase value (`(,_ 1 2) (message "Matched a list of anything followed by (1 2)"))) ``` It is not clear to me why I couldn't simply write: ``` (pcase value ((_ 1 2) (message "Matched a list of anything followed by (1 2)"))) ``` I *can* understand the need to write: ``` (pcase value (`(1 2 ,foo 3) (message "Matched 1, 2, something now bound to foo, and 3"))) ``` Instead of: ``` (pcase value ((1 2 foo 3) (message "Matched 1, 2, something now bound to foo, and 3"))) ``` This is obviously done in order to be able to match against the symbol `foo' while at the same time be able to match anything and bind it to the symbol `foo'. And even though this syntax with backquote and comma looks familiar to anyone who's ever written a macro, their meaning is subtly different from their meaning in macros. In pcase, «,foo» does *not* mean «evaluate `foo'», it means something like «use `foo' as a variable». So, while I understand the reasoning, it still makes me wonder why I can't write something like this: ``` (pcase value ((1 2 % 3) (message "Matched 1, 2, something now bound to %, and 3"))) ``` That is, use a special symbol (I borrowed % from Clojure's anonymous functions) to indicate that I want to match against any value and at the same time bind that value. Obviously, the following: ``` (pcase value ((1 2 % %) (message "Matched 1, 2, something now bound to %, and that same something again"))) ``` would then match lists of the form (1 2 3 3), not (1 2 3 4). If you need to bind multiple values, I could imagine using something like: ``` (pcase value ((1 2 %1 %2) (message "Matched 1, 2, something now bound to %1, and something (else) bound to %2"))) ``` Also, the use of `pred' and `guard' seem unnecessary. Instead of: ``` (pcase value (`(1 2 ,(or 3 4) ,(and (pred stringp) (pred (string> "aaa")) (pred (lambda (x) (> (length x) 10))))) (message "Matched 1, 2, 3 or 4, and a long string " "that is lexically greater than 'aaa'"))) ``` why not write: ``` (pcase value ((1 2 (or 3 4) (and (stringp %) (string> "aaa" %) (> (length %) 10))) (message "Matched 1, 2, 3 or 4, and a long string " "that is lexically greater than 'aaa'"))) ``` Similarly, the example: ``` (pcase value (`(1 2 ,(and foo (guard (and (not (numberp foo)) (/= foo 10)))) _) (message "Matched 1, 2, anything, and then anything again, " "but only if the first anything wasn't the number 10")))) ``` uses `(and foo (guard ...))' to bind a value to `foo' and apply a predicate to it. That's a coding pattern that you need to be familiar with in order to understand what it does. (John explains it in his tutorial, but if I had met this in the wild, I'd probably be puzzled by it at first). The % syntax would seem to make this simpler as well: ``` (pcase value ((1 2 (and (not (numberp %)) (/= % 10)) _) (message "Matched 1, 2, anything, and then anything again, " "but only if the first anything wasn't the number 10")))) ``` This example also shows that `and' has a meaning in pcase that is subtly different from its usual meaning in Lisp: `and' in a pcase 'UPattern' (as the manual calls it) is not a logical `and' in the sense that it tests its arguments for truthiness. Rather, it means «both arguments of `and' must apply to the value at this position *regardless of truthiness*». (The `and' inside the guard does have the usual meaning, of course.) Mind you, I'm not arguing that pcase should be changed or replaced with something that has this more intuitive (to me, anyway) syntax. I'm just trying to explain why I personally find pcase difficult to wrap my head around, and why I think this difficulty has to do with its syntax, which is different in subtle ways, to such an extent that you can't, as an Elisp programmer tackling pcase for the first time, just build on what you already know. You need to actually bend your mind to incorporate the new stuff. Moreover, at first sight, there doesn't seem to be much of an advantage to this syntax, since an alternative syntax that doesn't have the same disadvantage seems feasible. I say "seems", because it's entirely possible that this particular syntax has capabilities that wouldn't be possible with a simpler syntax. But for a pcase newbie, that's not immediately obvious. The only reason that I can think of why the %-syntax or something similar isn't used is that it's dangerous in an environment that doesn't have lexical scope... Just my two cents, of course. -- Joost Kremers Life has its moments ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-24 8:34 ` Joost Kremers @ 2018-10-24 12:37 ` Stefan Monnier 2018-10-24 13:08 ` Daniel Pittman 2018-10-24 13:03 ` pcase pattern syntax (was: Replace trivial pcase occurrences in the Emacs sources) Stefan Monnier 1 sibling, 1 reply; 375+ messages in thread From: Stefan Monnier @ 2018-10-24 12:37 UTC (permalink / raw) To: emacs-devel >> > In what sense is the above cl-case more clear than the pcase equivalent? >> > I'm not saying the pcase version is better in those cases, but I think >> > the respective advantages and disadvantages pretty much balance out. >> I also wonder. Is it simply that people find pcase unfamiliar? > Well, I can't speak for others, but personally, though I find pattern > matching as a concept straightforward and intuitive, pcase syntax > seems unnecessarily complex and unintuitive. Joost, could you post this in another thread? You're discussing destructuring pcase patterns, whereas this discussion is about cl-case vs pcase, where there's no destructuring and no backquote in sight. Stefan ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-24 12:37 ` Stefan Monnier @ 2018-10-24 13:08 ` Daniel Pittman 2018-10-24 14:35 ` Stefan Monnier 0 siblings, 1 reply; 375+ messages in thread From: Daniel Pittman @ 2018-10-24 13:08 UTC (permalink / raw) To: monnier; +Cc: emacs-devel [-- Attachment #1: Type: text/plain, Size: 1075 bytes --] On Wed, Oct 24, 2018 at 8:38 AM Stefan Monnier <monnier@iro.umontreal.ca> wrote: > >> > In what sense is the above cl-case more clear than the pcase > equivalent? > >> > I'm not saying the pcase version is better in those cases, but I > think > >> > the respective advantages and disadvantages pretty much balance out. > >> I also wonder. Is it simply that people find pcase unfamiliar? > > > Well, I can't speak for others, but personally, though I find pattern > > matching as a concept straightforward and intuitive, pcase syntax > > seems unnecessarily complex and unintuitive. > > Joost, could you post this in another thread? You're discussing > destructuring pcase patterns, whereas this discussion is about cl-case > vs pcase, where there's no destructuring and no backquote in sight. For what it is worth, I agree with Joost, and I thought this *was* the required syntax for the use case being discussed. Which, despite having written a fair bit of pcase and pcase-let based code recently, probably tells you a bit about the learning curve for the tool. [-- Attachment #2: Type: text/html, Size: 1437 bytes --] ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-24 13:08 ` Daniel Pittman @ 2018-10-24 14:35 ` Stefan Monnier 0 siblings, 0 replies; 375+ messages in thread From: Stefan Monnier @ 2018-10-24 14:35 UTC (permalink / raw) To: emacs-devel > For what it is worth, I agree with Joost, and I thought this *was* the > required syntax for the use case being discussed. What do you mean by "this"? The use cases being discussed are those which could be rewritten to use `cl-case`. So which "pcase required syntax" are you thinking of which is covered by the cl-case functionality? Stefan ^ permalink raw reply [flat|nested] 375+ messages in thread
* pcase pattern syntax (was: Replace trivial pcase occurrences in the Emacs sources) 2018-10-24 8:34 ` Joost Kremers 2018-10-24 12:37 ` Stefan Monnier @ 2018-10-24 13:03 ` Stefan Monnier 2018-10-26 7:16 ` Joost Kremers 1 sibling, 1 reply; 375+ messages in thread From: Stefan Monnier @ 2018-10-24 13:03 UTC (permalink / raw) To: emacs-devel > (pcase value > (`(,_ 1 2) > (message "Matched a list of anything followed by (1 2)"))) > > It is not clear to me why I couldn't simply write: > > (pcase value > ((_ 1 2) > (message "Matched a list of anything followed by (1 2)"))) The reason is simple: because pcase uses a more verbose pattern syntax. There are many different choices for pattern syntax, with various tradeoffs between conciseness, regularity, and extensibility. pcase's syntax leans in favor of regularity and extensibility to the detriment of conciseness. In your above example, if you allow (_ 1 2) to mean the same as pcase's `(,_ 1 2), then you need some special syntax for the case where you meant to match the same as pcase's '(_ 1 2). > would then match lists of the form (1 2 3 3), not (1 2 3 4). If you > need to bind multiple values, I could imagine using something like: > > (pcase value > ((1 2 %1 %2) > (message "Matched 1, 2, something now bound to %1, and something (else) bound to %2"))) that's getting pretty close to (1 2 ,x ,y): the only differences being the use of % instead of comma and the absence of a surrounding backquote. > why not write: > > ``` > (pcase value > ((1 2 (or 3 4) > (and (stringp %) > (string> "aaa" %) > (> (length %) 10))) > (message "Matched 1, 2, 3 or 4, and a long string " > "that is lexically greater than 'aaa'"))) Why wouldn't that be matching the same as pcase's (pcase value (`(1 2 (or 3 4) (and (stringp ,x) (string> "aaa" ,y) (> (length ,z) 10))) (message "Matched 1, 2, 3 or 4, and a long string " "that is lexically greater than 'aaa'"))) or alternatively, what special syntax would you introduce in order to say "this (or 3 4) shouldn't match "either 3 or 4" but should match a the 3-element list (or 3 4)"? > uses `(and foo (guard ...))' to bind a value to `foo' and apply > a predicate to it. That's a coding pattern that you need to be > familiar with in order to understand what it does. (John explains it > in his tutorial, but if I had met this in the wild, I'd probably be > puzzled by it at first). The % syntax would seem to make this simpler > as well: Yes, the and+guard thingy sucks. I've been thinking of changing `guard` so it automatically does an `and`, i.e. make it so that (guard foo EXP) is the same as (and foo (guard EXP)) but I don't find this terribly good either. Note that you can also write it as (pred (lambda (foo) EXP)) which is clearly not more friendly but I just mention it in case it might help someone come up with yet another solution. Many pattern matching systems don't have guards as part of the patterns and instead have them "on the side", in which case you'd write ... ,foo ... in the pattern and (guard EXP) elsewhere. I find this to be a nice way to solve the problem, but: - I don't know where to place this EXP. Maybe a branch could take the form (PATTERN :guard EXP BODY)? - This forces the guard expressions to be evaluated at the very end, so it's a bit less expressive. In practice this is not too bad, tho. - There's a similar problem for the (let PAT EXP) pattern, where it often/generally has to be coupled with an `and` as in (and PAT1 (let PAT EXP)), but this problem can't be solved by moving the `let` outside of the pattern like we can for the `guard`. > This example also shows that `and' has a meaning in pcase that is > subtly different from its usual meaning in Lisp: `and' in a pcase > 'UPattern' (as the manual calls it) is not a logical `and' in the > sense that it tests its arguments for truthiness. Rather, it means > «both arguments of `and' must apply to the value at this position > *regardless of truthiness*». (The `and' inside the guard does have the > usual meaning, of course.) That's right: the `and` pattern is really an intersection of patterns. Stefan ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: pcase pattern syntax (was: Replace trivial pcase occurrences in the Emacs sources) 2018-10-24 13:03 ` pcase pattern syntax (was: Replace trivial pcase occurrences in the Emacs sources) Stefan Monnier @ 2018-10-26 7:16 ` Joost Kremers 0 siblings, 0 replies; 375+ messages in thread From: Joost Kremers @ 2018-10-26 7:16 UTC (permalink / raw) To: Stefan Monnier On Wed, Oct 24, 2018 at 09:03:51AM -0400, Stefan Monnier wrote: > > (pcase value > > (`(,_ 1 2) > > (message "Matched a list of anything followed by (1 2)"))) > > > > It is not clear to me why I couldn't simply write: > > > > (pcase value > > ((_ 1 2) > > (message "Matched a list of anything followed by (1 2)"))) > > The reason is simple: because pcase uses a more verbose pattern syntax. Perhaps I should have said "not immediately clear". I've snipped the rest of your reply, not because it's not interesting (it is) but because I'm really not qualified to argue better pattern matching syntax with you. I was just trying to answer Richard's question, who was wondering why people don't seem to use/like pcase as much as one might expect. And since I had tried a few times in the past to grok pcase but never really got it, I thought it might be helpful to offer my perspective. I'm sure that with some practice I could "get" pcase, it's not *that* difficult. I just find it noticeably more difficult to grok than other Elisp constructs that are new to me. Usually, it's enough to read the manual to get a basic idea of how and when to use something. Not so with pcase. -- Joost Kremers Life has its moments ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-24 4:51 ` Richard Stallman 2018-10-24 8:34 ` Joost Kremers @ 2018-10-24 10:16 ` João Távora 2018-10-24 13:05 ` Stefan Monnier 2018-10-25 3:11 ` Richard Stallman 1 sibling, 2 replies; 375+ messages in thread From: João Távora @ 2018-10-24 10:16 UTC (permalink / raw) To: Richard Stallman; +Cc: michael_heerdegen, eliz, Stefan Monnier, emacs-devel Richard Stallman <rms@gnu.org> writes: > [[[ 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. ]]] > > > In what sense is the above cl-case more clear than the pcase equivalent? > > I'm not saying the pcase version is better in those cases, but I think > > the respective advantages and disadvantages pretty much balance out. > > I also wonder. Is it simply that people find pcase unfamiliar? My two cents: I like to write it, I don't like to read it. I like to write it because it's fun. I write some dummy '(1 2 (3 4 5) 6 7) into my code and then semi-randomly hammer out parenthesis, backquotes, commas and underscores until it does what I want. In the end I'm happy for winning this little game, and happily convinced it saved me a ton of LOC (which it probably did). When reading it, I shudder a little. The backquote syntax helps in warning that something potentially difficult is in front of me, so please don't remove it. I can't explain, but I don't feel this way about destructuring-bind (or its destructuring-case variants [0]): they're boring to write and easy to read. João [0]: http://www.crategus.com/books/alexandria/pages/alexandria.0.dev_fun_destructuring-case.html ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-24 10:16 ` Replace trivial pcase occurrences in the Emacs sources João Távora @ 2018-10-24 13:05 ` Stefan Monnier 2018-10-25 3:11 ` Richard Stallman 1 sibling, 0 replies; 375+ messages in thread From: Stefan Monnier @ 2018-10-24 13:05 UTC (permalink / raw) To: emacs-devel >> [[[ 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. ]]] >> >> > In what sense is the above cl-case more clear than the pcase equivalent? >> > I'm not saying the pcase version is better in those cases, but I think >> > the respective advantages and disadvantages pretty much balance out. >> >> I also wonder. Is it simply that people find pcase unfamiliar? > > My two cents: I like to write it, I don't like to read it. Same as for Joost: you're talking about the backquote syntax of pcase, whereas this thread is about cl-case vs pcase, where there's no backquote in sight. Stefan ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-24 10:16 ` Replace trivial pcase occurrences in the Emacs sources João Távora 2018-10-24 13:05 ` Stefan Monnier @ 2018-10-25 3:11 ` Richard Stallman 2018-10-25 12:42 ` Stefan Monnier 1 sibling, 1 reply; 375+ messages in thread From: Richard Stallman @ 2018-10-25 3:11 UTC (permalink / raw) To: João Távora Cc: michael_heerdegen, eliz, monnier, emacs-devel [[[ 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. ]]] Several people say they find pcase unclear. Indeed, its documentation describes various special cases. This raises the question: can we develop a clearer alternative spec for a new constuct? Would people like to try out various alternatives? -- Dr Richard Stallman President, Free Software Foundation (https://gnu.org, https://fsf.org) Internet Hall-of-Famer (https://internethalloffame.org) ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-25 3:11 ` Richard Stallman @ 2018-10-25 12:42 ` Stefan Monnier 2018-10-25 23:53 ` Andy Moreton 0 siblings, 1 reply; 375+ messages in thread From: Stefan Monnier @ 2018-10-25 12:42 UTC (permalink / raw) To: emacs-devel > This raises the question: can we develop a clearer alternative spec > for a new constuct? Would people like to try out various alternatives? Indeed, this can be done without having to re-implement the underlying machinery since you can easily use a macro-layer on top of pcase (either via normal defmacro or via pcase-defmacro, or both). Stefan ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-25 12:42 ` Stefan Monnier @ 2018-10-25 23:53 ` Andy Moreton 2018-10-26 14:59 ` Stefan Monnier 2018-10-28 21:44 ` Stefan Monnier 0 siblings, 2 replies; 375+ messages in thread From: Andy Moreton @ 2018-10-25 23:53 UTC (permalink / raw) To: emacs-devel On Thu 25 Oct 2018, Stefan Monnier wrote: >> This raises the question: can we develop a clearer alternative spec >> for a new constuct? Would people like to try out various alternatives? > > Indeed, this can be done without having to re-implement the underlying > machinery since you can easily use a macro-layer on top of pcase > (either via normal defmacro or via pcase-defmacro, or both). ...which does not help existing users, who are still dealing with inadequate documentation of the pcase family of macros, and with the baffling syntax. pcase-lambda, pcase-let, pcase-let*, and pcase-dolist still have no meaningful documentation, and are not even mentioned in the manual. Pattern matching is a useful facility, but pcase is woefully hard to use correctly, as the existing (mis-)usage shows. Something that is significantly easier to read and comprehend is needed. AndyM ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-25 23:53 ` Andy Moreton @ 2018-10-26 14:59 ` Stefan Monnier 2018-10-26 15:44 ` Garreau, Alexandre 2018-10-27 12:09 ` Andy Moreton 2018-10-28 21:44 ` Stefan Monnier 1 sibling, 2 replies; 375+ messages in thread From: Stefan Monnier @ 2018-10-26 14:59 UTC (permalink / raw) To: emacs-devel > Pattern matching is a useful facility, but pcase is woefully hard to use > correctly, as the existing (mis-)usage shows. Something that is > significantly easier to read and comprehend is needed. I was just pointing out that it is easy to *experiment* with new syntaxes (in order to find a new syntax so as to solve the current problems). Stefan "not convinced there's a solution to this problem, tho" ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-26 14:59 ` Stefan Monnier @ 2018-10-26 15:44 ` Garreau, Alexandre 2018-10-27 12:09 ` Andy Moreton 1 sibling, 0 replies; 375+ messages in thread From: Garreau, Alexandre @ 2018-10-26 15:44 UTC (permalink / raw) To: Stefan Monnier; +Cc: emacs-devel On 2018-10-26 at 10:59, Stefan Monnier wrote: >> Pattern matching is a useful facility, but pcase is woefully hard to use >> correctly, as the existing (mis-)usage shows. Something that is >> significantly easier to read and comprehend is needed. > > I was just pointing out that it is easy to *experiment* with new > syntaxes (in order to find a new syntax so as to solve the current > problems). > > > Stefan "not convinced there's a solution to this problem, tho" I think liking current pcase or not, more or less than cl-case or cond, everybody would like to get pcase improved, anyway. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-26 14:59 ` Stefan Monnier 2018-10-26 15:44 ` Garreau, Alexandre @ 2018-10-27 12:09 ` Andy Moreton 1 sibling, 0 replies; 375+ messages in thread From: Andy Moreton @ 2018-10-27 12:09 UTC (permalink / raw) To: emacs-devel On Fri 26 Oct 2018, Stefan Monnier wrote: >> Pattern matching is a useful facility, but pcase is woefully hard to use >> correctly, as the existing (mis-)usage shows. Something that is >> significantly easier to read and comprehend is needed. > > I was just pointing out that it is easy to *experiment* with new > syntaxes (in order to find a new syntax so as to solve the current > problems). Sure, but you have also removed the other part of my comment. Where is the missing documentation ? Why was it not added at the same time as the code ? Meaningful doc strings and entries in the manual are long overdue. AndyM ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-25 23:53 ` Andy Moreton 2018-10-26 14:59 ` Stefan Monnier @ 2018-10-28 21:44 ` Stefan Monnier 2018-10-29 13:01 ` Alan Mackenzie ` (2 more replies) 1 sibling, 3 replies; 375+ messages in thread From: Stefan Monnier @ 2018-10-28 21:44 UTC (permalink / raw) To: emacs-devel > pcase-lambda, pcase-let, pcase-let*, and pcase-dolist still have no > meaningful documentation, Not sure what kind of documentation would be more meaningful, sorry. Do you happen to have concrete questions about them which aren't answered by their docstrings? > Pattern matching is a useful facility, but pcase is woefully hard to use > correctly, as the existing (mis-)usage shows. I obviously can't judge fairly how hard it is to use, but I don't find any of the examples posted here as evidence of problematic use and even less misuse (they look perfectly correct to me). Could you clarify what you find problematic in those uses? Stefan ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-28 21:44 ` Stefan Monnier @ 2018-10-29 13:01 ` Alan Mackenzie 2018-10-29 13:28 ` Stefan Monnier 2018-10-29 14:47 ` Andy Moreton 2018-10-30 23:34 ` Replace trivial pcase occurrences in the Emacs sources Van L 2 siblings, 1 reply; 375+ messages in thread From: Alan Mackenzie @ 2018-10-29 13:01 UTC (permalink / raw) To: Stefan Monnier; +Cc: emacs-devel Hello, Stefan. On Sun, Oct 28, 2018 at 17:44:57 -0400, Stefan Monnier wrote: > > pcase-lambda, pcase-let, pcase-let*, and pcase-dolist still have no > > meaningful documentation, > Not sure what kind of documentation would be more meaningful, sorry. Doc strings which specify fully the arguments to these macros, including their semantics, and say what the macros do. The current doc strings (at least some of them) for these macros don't do this. Entries in the elisp manual. These don't exist at all. (Or, if they do, they don't have index entries.) > Do you happen to have concrete questions about them which aren't answered > by their docstrings? I've had such questions in the past, and had to answer them by time consuming guessing, reading the source of pcase-..., and experimentation. Adequate documentation would have saved me a great deal of time, frustration, and uncertainty. [ .... ] > Stefan -- Alan Mackenzie (Nuremberg, Germany). ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-29 13:01 ` Alan Mackenzie @ 2018-10-29 13:28 ` Stefan Monnier 2018-10-29 13:47 ` Alan Mackenzie 0 siblings, 1 reply; 375+ messages in thread From: Stefan Monnier @ 2018-10-29 13:28 UTC (permalink / raw) To: emacs-devel > Doc strings which specify fully the arguments to these macros, including > their semantics, and say what the macros do. The current doc strings > (at least some of them) for these macros don't do this. I understand this in theory, but I don't know what it means in this concrete case. > I've had such questions in the past, and had to answer them by time > consuming guessing, reading the source of pcase-..., and > experimentation. Do you remember them enough to describe the problems, so we can try and improve the doc accordingly? > Adequate documentation would have saved me a great deal of time, > frustration, and uncertainty. I don't doubt it. But I'm sadly not able to guess what those problems might be. Stefan ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-29 13:28 ` Stefan Monnier @ 2018-10-29 13:47 ` Alan Mackenzie 2018-10-29 21:08 ` Stefan Monnier 0 siblings, 1 reply; 375+ messages in thread From: Alan Mackenzie @ 2018-10-29 13:47 UTC (permalink / raw) To: Stefan Monnier; +Cc: emacs-devel Hello, Stefan. On Mon, Oct 29, 2018 at 09:28:25 -0400, Stefan Monnier wrote: > > Doc strings which specify fully the arguments to these macros, including > > their semantics, and say what the macros do. The current doc strings > > (at least some of them) for these macros don't do this. > I understand this in theory, but I don't know what it means in this > concrete case. Take a look at, for example, the doc string for pcase-dolist. In its entirety, it's this: pcase-dolist is an autoloaded Lisp macro in `pcase.el'. (pcase-dolist (PATTERN LIST) BODY...) Like `dolist' but where the binding can be a `pcase' pattern. There is no clue here what PATTERN, LIST, and BODY mean. It is unclear what "the binding" is. It is unclear, exactly, what a "`pcase' pattern" is. It is not explained what the code (generated by the macro) does. Even supposing the notion "`pcase' pattern" to be understood, there is no explanation of how such a pattern is used. There is no explanation of any compatibility constraints between the arguments PATTERN, LIST, and BODY. There are no examples to clarify the syntax and semantics. Now it is possible that partial enlightenment will come from looking at the referenced doc strings for dolist and pcase, but I remember, vaguely, this not being very helpful. Maybe it's better now, with the improved documentation of pcase. > > I've had such questions in the past, and had to answer them by time > > consuming guessing, reading the source of pcase-..., and > > experimentation. > Do you remember them enough to describe the problems, so we can try and > improve the doc accordingly? See above. > > Adequate documentation would have saved me a great deal of time, > > frustration, and uncertainty. > I don't doubt it. But I'm sadly not able to guess what those problems > might be. Also see above. > Stefan -- Alan Mackenzie (Nuremberg, Germany). ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-29 13:47 ` Alan Mackenzie @ 2018-10-29 21:08 ` Stefan Monnier 2018-10-29 21:53 ` Michael Heerdegen ` (4 more replies) 0 siblings, 5 replies; 375+ messages in thread From: Stefan Monnier @ 2018-10-29 21:08 UTC (permalink / raw) To: emacs-devel >> > Doc strings which specify fully the arguments to these macros, including >> > their semantics, and say what the macros do. The current doc strings >> > (at least some of them) for these macros don't do this. >> I understand this in theory, but I don't know what it means in this >> concrete case. > Take a look at, for example, the doc string for pcase-dolist. In its > entirety, it's this: Thanks. What do you think of the patch below? I'd rather keep it defined in terms of its differences w.r.t `dolist`, but if really needed, we could change the doc so it doesn't rely on `dolist`s own doc at all. We do have to keep the reference to `pcase` because we don't want to repeat the definition of what a pcase pattern can look like. Stefan diff --git a/lisp/emacs-lisp/pcase.el b/lisp/emacs-lisp/pcase.el index 57c2d6c3cb..861c900b21 100644 --- a/lisp/emacs-lisp/pcase.el +++ b/lisp/emacs-lisp/pcase.el @@ -281,7 +281,7 @@ pcase-let* (defmacro pcase-let (bindings &rest body) "Like `let' but where you can use `pcase' patterns for bindings. BODY should be a list of expressions, and BINDINGS should be a list of bindings -of the form (PAT EXP). +of the form (PATTERN EXP). The macro is expanded and optimized under the assumption that those patterns *will* match, so a mismatch may go undetected or may cause any kind of error." @@ -302,7 +302,12 @@ pcase-let ;;;###autoload (defmacro pcase-dolist (spec &rest body) - "Like `dolist' but where the binding can be a `pcase' pattern. + "Superset of `dolist' where the VAR binding can be a `pcase' PATTERN. +More specifically `dolist's VAR binding is replaced by a PATTERN +against which each element of the list is matched. +As in the case of `pcase-let', PATTERN is matched under the assumption +that it *will* match. + \n(fn (PATTERN LIST) BODY...)" (declare (indent 1) (debug ((pcase-PAT form) body))) (if (pcase--trivial-upat-p (car spec)) ^ permalink raw reply related [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-29 21:08 ` Stefan Monnier @ 2018-10-29 21:53 ` Michael Heerdegen 2018-10-29 23:12 ` Eric Abrahamsen 2018-10-30 1:15 ` Garreau, Alexandre ` (3 subsequent siblings) 4 siblings, 1 reply; 375+ messages in thread From: Michael Heerdegen @ 2018-10-29 21:53 UTC (permalink / raw) To: Stefan Monnier; +Cc: emacs-devel Stefan Monnier <monnier@iro.umontreal.ca> writes: > I'd rather keep it defined in terms of its differences w.r.t `dolist`, > but if really needed, we could change the doc so it doesn't rely on > `dolist`s own doc at all. I also don't think that would be an improvement. > +As in the case of `pcase-let', PATTERN is matched under the > assumption +that it *will* match. What this leaves a bit unclear: It sounds like matching itself happens differently (user visibly). Or does it just mean "if PATTERN doesn't match, the behavior [of pcase-dolist] is undefined/ this is not allowed". Michael. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-29 21:53 ` Michael Heerdegen @ 2018-10-29 23:12 ` Eric Abrahamsen 2018-10-29 23:18 ` Eric Abrahamsen 2018-10-30 12:30 ` Stefan Monnier 0 siblings, 2 replies; 375+ messages in thread From: Eric Abrahamsen @ 2018-10-29 23:12 UTC (permalink / raw) To: Michael Heerdegen; +Cc: Stefan Monnier, emacs-devel Michael Heerdegen <michael_heerdegen@web.de> writes: > Stefan Monnier <monnier@iro.umontreal.ca> writes: > >> I'd rather keep it defined in terms of its differences w.r.t `dolist`, >> but if really needed, we could change the doc so it doesn't rely on >> `dolist`s own doc at all. > > I also don't think that would be an improvement. > >> +As in the case of `pcase-let', PATTERN is matched under the >> assumption +that it *will* match. > > What this leaves a bit unclear: It sounds like matching itself happens > differently (user visibly). Or does it just mean "if PATTERN doesn't > match, the behavior [of pcase-dolist] is undefined/ this is not > allowed". I wonder if the manual shouldn't have a section somewhere making explicit the difference between `pcase' -- where a single value is matched against many patterns, and may fail to match altogether, and destructuring is only one of the use-cases -- and the other pcase-derived forms, where many values are matched against a single pattern, which *must* match (or error), and destructuring is kind of the whole point. Conceptually, they're pretty different. BTW I just looked at the new manual section for pcase -- that's much better! Eric ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-29 23:12 ` Eric Abrahamsen @ 2018-10-29 23:18 ` Eric Abrahamsen 2018-10-30 0:50 ` `pcase'/`case' implementation [Was: Re: Replace trivial pcase occurrences in the Emacs sources] Garreau, Alexandre 2018-10-30 13:07 ` Replace trivial pcase occurrences in the Emacs sources Stefan Monnier 2018-10-30 12:30 ` Stefan Monnier 1 sibling, 2 replies; 375+ messages in thread From: Eric Abrahamsen @ 2018-10-29 23:18 UTC (permalink / raw) To: Michael Heerdegen; +Cc: Stefan Monnier, emacs-devel Eric Abrahamsen <eric@ericabrahamsen.net> writes: > Michael Heerdegen <michael_heerdegen@web.de> writes: > >> Stefan Monnier <monnier@iro.umontreal.ca> writes: >> >>> I'd rather keep it defined in terms of its differences w.r.t `dolist`, >>> but if really needed, we could change the doc so it doesn't rely on >>> `dolist`s own doc at all. >> >> I also don't think that would be an improvement. >> >>> +As in the case of `pcase-let', PATTERN is matched under the >>> assumption +that it *will* match. >> >> What this leaves a bit unclear: It sounds like matching itself happens >> differently (user visibly). Or does it just mean "if PATTERN doesn't >> match, the behavior [of pcase-dolist] is undefined/ this is not >> allowed". > > I wonder if the manual shouldn't have a section somewhere making > explicit the difference between `pcase' -- where a single value is > matched against many patterns, and may fail to match altogether, and > destructuring is only one of the use-cases -- and the other > pcase-derived forms, where many values are matched against a single > pattern, which *must* match (or error), and destructuring is kind of the > whole point. Conceptually, they're pretty different. In fact, when you think about it, the "case" nature of pcase is pretty orthogonal to the "match/destructure" nature of pcase. If anything fairly fundamental were to be done to refactor pcase, I wonder if it shouldn't be to separate these two concerns. In a sense, we already have `cl-case', why would we need another case-like structure? All we really need are new _matching forms_, which could be used within `cl-case', `dolist', `lambda'... ^ permalink raw reply [flat|nested] 375+ messages in thread
* `pcase'/`case' implementation [Was: Re: Replace trivial pcase occurrences in the Emacs sources] 2018-10-29 23:18 ` Eric Abrahamsen @ 2018-10-30 0:50 ` Garreau, Alexandre 2018-10-30 13:07 ` Replace trivial pcase occurrences in the Emacs sources Stefan Monnier 1 sibling, 0 replies; 375+ messages in thread From: Garreau, Alexandre @ 2018-10-30 0:50 UTC (permalink / raw) To: Eric Abrahamsen; +Cc: Michael Heerdegen, Stefan Monnier, emacs-devel On 2018-10-29 at 16:18, Eric Abrahamsen wrote: > Eric Abrahamsen <eric@ericabrahamsen.net> writes: >> I wonder if the manual shouldn't have a section somewhere making >> explicit the difference between `pcase' -- where a single value is >> matched against many patterns, and may fail to match altogether, and >> destructuring is only one of the use-cases -- and the other >> pcase-derived forms, where many values are matched against a single >> pattern, which *must* match (or error), and destructuring is kind of the >> whole point. Conceptually, they're pretty different. > > In fact, when you think about it, the "case" nature of pcase is pretty > orthogonal to the "match/destructure" nature of pcase. If anything > fairly fundamental were to be done to refactor pcase, I wonder if it > shouldn't be to separate these two concerns. In a sense, we already have > `cl-case', why would we need another case-like structure? All we really > need are new _matching forms_, which could be used within `cl-case', > `dolist', `lambda'... I also believe this. We should, on one side, have a `match' function, that would do more advanced destructuring than `cl-destructuring-bind' (and, potentially, be based on it (so it could seeminglessly be used in `pcase-lambda' on whole argument list), or the other way around, so match returns an env (like other one-clause `match'), without having to execute body, so to be more composable, and only then it would be used in `cl-destructuring-bind' (which would then be accordingly more powerful (but potentially incompatible in some corner cases (or more than corner cases, if we don’t implement unquoted “(a . b)” where “a” isn’t a predefined pattern, to match a cons)))), preferably based on it (and potentially with an `unify' based on it). Then, on another, I strongly believe we need a `case' struct that takes a test function as an argument. That test function might be `equal', so that to make `case' generally more useful, but also `match', so now we got a neat composition of two orthogonal and separate functions to make a more complex one. Then, we might tweak `case' so that to take the result of the test function as an environment to be used for each BODY: most test functions returns t, and in emacs, that’s already the void environment referring to the global dynamical one, and `match' would return what it bound. Then `pcase' would simply be “case :test #'match” (like (setf pcase (apply-partially #'case :test #'match)), but with its defun, docstring, et al), get a simpler implementation, neat internal interfaces, and ends that sort of sterile and useless implicit fight between `case' and `pcase' (as they’re only two different levels). I like minimalism, composition and reductionnism. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-29 23:18 ` Eric Abrahamsen 2018-10-30 0:50 ` `pcase'/`case' implementation [Was: Re: Replace trivial pcase occurrences in the Emacs sources] Garreau, Alexandre @ 2018-10-30 13:07 ` Stefan Monnier 2018-10-30 23:30 ` Eric Abrahamsen 2018-11-01 0:16 ` Garreau, Alexandre 1 sibling, 2 replies; 375+ messages in thread From: Stefan Monnier @ 2018-10-30 13:07 UTC (permalink / raw) To: emacs-devel > In fact, when you think about it, the "case" nature of pcase is pretty > orthogonal to the "match/destructure" nature of pcase. If anything How do you suggest to split the two in cases like: (defun cconv-convert (form env extend) (pcase form (`(,(and letsym (or `let* `let)) ,binders . ,body) ...) (`(,(and `(lambda . ,_) fun) . ,args) ...) (`(cond . ,cond-forms) ...) (`(function (lambda ,args . ,body) . ,_) ...) (`(internal-make-closure . ,_) ...) (`(quote . ,_) form) (`(function . ,_) form) (`(,(and sym (or `defconst `defvar)) ,definedsymbol . ,forms) ...) ((and `(condition-case ,var ,protected-form . ,handlers) (guard byte-compile--use-old-handlers)) ...) (`(condition-case ,var ,protected-form . ,handlers) ...) (`(,(and head (or (and `catch (guard byte-compile--use-old-handlers)) `unwind-protect)) ,form . ,body) ...) (`(setq . ,forms) ...) (`(,(and (or `funcall `apply) callsym) ,fun . ,args) ...) (`(interactive . ,forms) ...) (`(declare . ,_) form) (`(,func . ,forms) ...) (_ ...))) That kind of use is the main motivation behind the design of pcase. Once you have this, you also trivially cover the `cl-case` uses and you can easily make it handle the "destructuring" uses. Splitting the two will just require more code to get less flexibility. Stefan ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-30 13:07 ` Replace trivial pcase occurrences in the Emacs sources Stefan Monnier @ 2018-10-30 23:30 ` Eric Abrahamsen 2018-11-01 0:16 ` Garreau, Alexandre 1 sibling, 0 replies; 375+ messages in thread From: Eric Abrahamsen @ 2018-10-30 23:30 UTC (permalink / raw) To: emacs-devel Stefan Monnier <monnier@iro.umontreal.ca> writes: >> In fact, when you think about it, the "case" nature of pcase is pretty >> orthogonal to the "match/destructure" nature of pcase. If anything > > How do you suggest to split the two in cases like: > > (defun cconv-convert (form env extend) > (pcase form > (`(,(and letsym (or `let* `let)) ,binders . ,body) > ...) > > (`(,(and `(lambda . ,_) fun) . ,args) > ...) [...] >...))) > > That kind of use is the main motivation behind the design of pcase. > > Once you have this, you also trivially cover the `cl-case` uses and you > can easily make it handle the "destructuring" uses. > Splitting the two will just require more code to get less flexibility. Sure, it was just a little realization I had, probably nothing that should lead to an actual code change. What I imagined, for a moment there, were matching forms that would look like "(m ,(and `(lambda . ,_) fun))", or something, and then you could use that matching form in a cl-case clause, or a lambda argument, or a dolist variable name. Ie, confining the pattern matching/destructuring to a form, which could be used in the existing macros/functions like cl-case or dolist. I can be safely ignored! Eric ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-30 13:07 ` Replace trivial pcase occurrences in the Emacs sources Stefan Monnier 2018-10-30 23:30 ` Eric Abrahamsen @ 2018-11-01 0:16 ` Garreau, Alexandre 1 sibling, 0 replies; 375+ messages in thread From: Garreau, Alexandre @ 2018-11-01 0:16 UTC (permalink / raw) To: Stefan Monnier; +Cc: emacs-devel On 2018-10-30 at 09:07, Stefan Monnier wrote: >> In fact, when you think about it, the "case" nature of pcase is pretty >> orthogonal to the "match/destructure" nature of pcase. If anything > > How do you suggest to split the two in cases like: > > […] Wouldn’t a “cl-case :test #'match ...”, where each `match' would be the simple-destructuring case-less version of `pcase' and `cl-case' would manage `:test' optional keyword, work? As for using bindings, either modifying cl-case (maybe getting it able to use external hooks?), either with ugly side effects (replacing “#'match” per “(lambda (arg) (setq local-pattern-env (match arg)))”, then wrapping bodies with a “let-alist local-pattern-env”) (and making that a macro, but agreed it would be ugly and not optimized)? ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-29 23:12 ` Eric Abrahamsen 2018-10-29 23:18 ` Eric Abrahamsen @ 2018-10-30 12:30 ` Stefan Monnier 2018-10-30 17:16 ` Stefan Monnier 1 sibling, 1 reply; 375+ messages in thread From: Stefan Monnier @ 2018-10-30 12:30 UTC (permalink / raw) To: Eric Abrahamsen; +Cc: Michael Heerdegen, emacs-devel > I wonder if the manual shouldn't have a section somewhere making > explicit the difference between `pcase' -- where a single value is > matched against many patterns, and may fail to match altogether, and > destructuring is only one of the use-cases -- and the other Yes, I'll send a patch for that, Stefan ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-30 12:30 ` Stefan Monnier @ 2018-10-30 17:16 ` Stefan Monnier 2018-10-30 19:03 ` Eli Zaretskii 0 siblings, 1 reply; 375+ messages in thread From: Stefan Monnier @ 2018-10-30 17:16 UTC (permalink / raw) To: Eric Abrahamsen; +Cc: Michael Heerdegen, emacs-devel >> I wonder if the manual shouldn't have a section somewhere making >> explicit the difference between `pcase' -- where a single value is >> matched against many patterns, and may fail to match altogether, and >> destructuring is only one of the use-cases -- and the other > Yes, I'll send a patch for that, How 'bout... Stefan diff --git a/doc/lispref/control.texi b/doc/lispref/control.texi index 5be4b298b4..819f486f4e 100644 --- a/doc/lispref/control.texi +++ b/doc/lispref/control.texi @@ -477,6 +477,7 @@ Pattern-Matching Conditional * The @code{pcase} macro: pcase Macro. Plus examples and caveats. * Extending @code{pcase}: Extending pcase. Define new kinds of patterns. * Backquote-Style Patterns: Backquote Patterns. Structural matching. +* Destructuring patterns:: Using pcase patterns to extract subfields. @end menu @node pcase Macro @@ -1168,6 +1169,81 @@ Backquote Patterns (evaluate '(sub 1 2) nil) @result{} error @end example +@node Destructuring patterns +@subsection Destructuring Patterns +@cindex Destructuring patterns + +Pcase patterns not only express a condition on the form of the objects +they can match but they can also extract sub-fields of those objects. +Say we have a list and want to extract 2 elements from it with the +following code: + +@example + (pcase l + (`(add ,x ,y) (message "Contains %S and %S" x y))) +@end example + +This will not only extract @code{x} and @code{y} but will additionally +test that @code{l} is a list containing exactly 3 elements and whose +first element is the symbol @code{add}. If any of those tests fail, +@code{pcase} will directly return @code{nil} without calling +@code{message}. + +The macros described in this section use @emph{destructuring} +patterns, which are normal Pcase patterns used in a context where we +presume that the object does match the pattern, and we only want +to extract some subfields. For example: + +@example + (pcase-let ((`(add ,x ,y) l)) + (message "Contains %S and %S" x y)) +@end example + +Does the same as the previous example, except that it directly tries +to extract @code{x} and @code{y} from @code{l} without first verifying +if @code{l} is a list which has the right number of elements and has +@code{add} as its first element. +The precise behavior when the object does not actually match the +pattern is undefined, although the body will not be silently skipped: +either an error is signaled or the body is run with some of the +variables potentially bound to arbitrary values like @code{nil}. + +@defmac pcase-let bindings body@dots{} +Bind variables according to @var{bindings} and then eval @var{body}. + +@var{bindings} is a list of bindings of the form @code{(@var{pattern} +@var{exp})}, where @var{exp} is an expression to evaluate and +@var{pattern} is a destructuring pattern. + +All @var{exp}s are evaluated first after which they are matched +against their respective @var{pattern}, introducing new variable +bindings which can then be used inside @var{body}. +@end defmac + +@defmac pcase-let* bindings body@dots{} +Bind variables according to @var{bindings} and then eval @var{body}. + +@var{bindings} is a list of bindings of the form @code{(@var{pattern} +@var{exp})}, where @var{exp} is an expression to evaluate and +@var{pattern} is a destructuring pattern. + +Unlike @code{pcase-let}, but like @code{let*}, each @var{exp} is +matched against its corresponding @var{pattern} before passing to the +next element of @var{bindings}, so the variables introduced in each +binding are available in the @var{exp}s that follow it, additionally +to being available in @var{body}. +@end defmac + +@findex dolist +@defmac pcase-dolist (pattern list) body@dots{} +This construct executes @var{body} once for each element of +@var{list}, in a context where the destructuring pattern +@var{pattern} was matched against the element. +When @var{pattern} is a simple variable, this ends up being equivalent +to @code{dolist}. +@end defmac + + @node Iteration @section Iteration @cindex iteration ^ permalink raw reply related [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-30 17:16 ` Stefan Monnier @ 2018-10-30 19:03 ` Eli Zaretskii 2018-10-30 19:21 ` Stefan Monnier 0 siblings, 1 reply; 375+ messages in thread From: Eli Zaretskii @ 2018-10-30 19:03 UTC (permalink / raw) To: Stefan Monnier; +Cc: eric, michael_heerdegen, emacs-devel > From: Stefan Monnier <monnier@IRO.UMontreal.CA> > Date: Tue, 30 Oct 2018 13:16:33 -0400 > Cc: Michael Heerdegen <michael_heerdegen@web.de>, emacs-devel@gnu.org > > >> I wonder if the manual shouldn't have a section somewhere making > >> explicit the difference between `pcase' -- where a single value is > >> matched against many patterns, and may fail to match altogether, and > >> destructuring is only one of the use-cases -- and the other > > Yes, I'll send a patch for that, > > How 'bout... Thanks. I have a few comments: > +* Destructuring patterns:: Using pcase patterns to extract subfields. We never used "pcase patterns" in the manual before, so I wonder whether we should start now. If we want to do that, this should be defined before it is used. > +@node Destructuring patterns > +@subsection Destructuring Patterns > +@cindex Destructuring patterns By convention, index entries should start with a lower-case letter. > +The macros described in this section use @emph{destructuring} > +patterns, which are normal Pcase patterns used in a context where we > +presume that the object does match the pattern, and we only want > +to extract some subfields. I think we need to define "destructuring" here (or elsewhere in the manual, and have a cross-reference there in this section). Readers that aren't familiar with that term will not be able to understand why this word is used here. We need to start this with something like @dfn{Destructuring} means ... It would also help to tell what exactly makes a pattern a destructuring one. > +@example > + (pcase-let ((`(add ,x ,y) l)) > + (message "Contains %S and %S" x y)) > +@end example > + > +Does the same as the previous example, except that it directly tries You want the text after the example to start like this: @noindent does the same as ... Otherwise, this sentence sounds awkward, and will also be indented. > +@var{bindings} is a list of bindings of the form @code{(@var{pattern} > +@var{exp})} Please use @w{..} around this form, so that it doesn't get broken between two lines. > +All @var{exp}s are evaluated first after which they are matched > +against their respective @var{pattern}, introducing new variable > +bindings which can then be used inside @var{body}. AFAIU, this means only some of the pcase patterns make sense in this context. If that is true, I'd suggest ti somehow tell which are (or which aren't, if that's easier). > +@defmac pcase-dolist (pattern list) body@dots{} > +This construct executes @var{body} once for each element of > +@var{list}, in a context where the destructuring pattern > +@var{pattern} was matched against the element. I don't think I understand what "in a context where the pattern was matched" means here. Is any aspect of the match except destructuring bindings relevant to execution of the body? If so, what other aspects are relevant? Thanks. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-30 19:03 ` Eli Zaretskii @ 2018-10-30 19:21 ` Stefan Monnier 2018-10-30 19:54 ` Eli Zaretskii 2018-10-30 20:04 ` Dmitry Gutov 0 siblings, 2 replies; 375+ messages in thread From: Stefan Monnier @ 2018-10-30 19:21 UTC (permalink / raw) To: emacs-devel >> +* Destructuring patterns:: Using pcase patterns to extract subfields. > We never used "pcase patterns" in the manual before, so I wonder > whether we should start now. If we want to do that, this should be > defined before it is used. I'm uncomfortable using "pattern" to refer to "pcase pattern" unless the context makes it clear. I'm not completely sure where best to define pcase patterns. >> +@node Destructuring patterns >> +@subsection Destructuring Patterns >> +@cindex Destructuring patterns > > By convention, index entries should start with a lower-case letter. Fixed. >> +The macros described in this section use @emph{destructuring} >> +patterns, which are normal Pcase patterns used in a context where we >> +presume that the object does match the pattern, and we only want >> +to extract some subfields. > > I think we need to define "destructuring" here (or elsewhere in the > manual, and have a cross-reference there in this section). The paragraph you quoted is exactly what I consider the definition of "destructuring pattern" (I don't see a need to define "destructuring" separately: the word placed in front of "pattern" is here treated as a kind of "proper name", just chosen so that it will help some if they already know the term from elsewhere, such as cl-destructuring-bind). > Readers that aren't familiar with that term will not be able to > understand why this word is used here. We need to start this with > something like > > @dfn{Destructuring} means ... I'd rather rename those to "Monnier patterns" and avoid the problem, if that's what it takes. > It would also help to tell what exactly makes a pattern a > destructuring one. As the paragraph says: it's the context in which it's used. > You want the text after the example to start like this: > > @noindent > does the same as ... > > Otherwise, this sentence sounds awkward, and will also be indented. Thanks. >> +@var{bindings} is a list of bindings of the form @code{(@var{pattern} >> +@var{exp})} > > Please use @w{..} around this form, so that it doesn't get broken > between two lines. Done. >> +All @var{exp}s are evaluated first after which they are matched >> +against their respective @var{pattern}, introducing new variable >> +bindings which can then be used inside @var{body}. > AFAIU, this means only some of the pcase patterns make sense in this > context. If that is true, I'd suggest ti somehow tell which are (or > which aren't, if that's easier). Not sure what you're thinking of. >> +@defmac pcase-dolist (pattern list) body@dots{} >> +This construct executes @var{body} once for each element of >> +@var{list}, in a context where the destructuring pattern >> +@var{pattern} was matched against the element. > > I don't think I understand what "in a context where the pattern was > matched" means here. Is any aspect of the match except destructuring > bindings relevant to execution of the body? No. But those extra bindings are exactly the context I'm referring to. In my work, "context" and "environment" are the usual words used to refer to the map that links identifiers to their corresponding information (typically, type or value depending on the ...ahem... context). Stefan diff --git a/doc/lispref/control.texi b/doc/lispref/control.texi index 5be4b298b4..da6a240ddc 100644 --- a/doc/lispref/control.texi +++ b/doc/lispref/control.texi @@ -477,6 +477,7 @@ Pattern-Matching Conditional * The @code{pcase} macro: pcase Macro. Plus examples and caveats. * Extending @code{pcase}: Extending pcase. Define new kinds of patterns. * Backquote-Style Patterns: Backquote Patterns. Structural matching. +* Destructuring patterns:: Using pcase patterns to extract subfields. @end menu @node pcase Macro @@ -497,6 +498,10 @@ pcase Macro Otherwise, @code{pcase} evaluates to @code{nil}. @end defmac +Each @var{pattern} has to be a @dfn{pcase pattern}, which can either +use one of the core patterns defined below, or use one of the patterns +defined via @code{pcase-defmacro}. + The rest of this subsection describes different forms of core patterns, presents some examples, @@ -1168,6 +1173,82 @@ Backquote Patterns (evaluate '(sub 1 2) nil) @result{} error @end example +@node Destructuring patterns +@subsection Destructuring Patterns +@cindex destructuring patterns + +Pcase patterns not only express a condition on the form of the objects +they can match but they can also extract sub-fields of those objects. +Say we have a list and want to extract 2 elements from it with the +following code: + +@example + (pcase l + (`(add ,x ,y) (message "Contains %S and %S" x y))) +@end example + +This will not only extract @code{x} and @code{y} but will additionally +test that @code{l} is a list containing exactly 3 elements and whose +first element is the symbol @code{add}. If any of those tests fail, +@code{pcase} will directly return @code{nil} without calling +@code{message}. + +The macros described in this section use @dfn{destructuring +patterns}, which are normal Pcase patterns used in a context where we +presume that the object does match the pattern, and we only want +to extract some subfields. For example: + +@example + (pcase-let ((`(add ,x ,y) l)) + (message "Contains %S and %S" x y)) +@end example + +@noindent +does the same as the previous example, except that it directly tries +to extract @code{x} and @code{y} from @code{l} without first verifying +if @code{l} is a list which has the right number of elements and has +@code{add} as its first element. +The precise behavior when the object does not actually match the +pattern is undefined, although the body will not be silently skipped: +either an error is signaled or the body is run with some of the +variables potentially bound to arbitrary values like @code{nil}. + +@defmac pcase-let bindings body@dots{} +Bind variables according to @var{bindings} and then eval @var{body}. + +@var{bindings} is a list of bindings of the form @w{@code{(@var{pattern} +@var{exp})}}, where @var{exp} is an expression to evaluate and +@var{pattern} is a destructuring pattern. + +All @var{exp}s are evaluated first after which they are matched +against their respective @var{pattern}, introducing new variable +bindings which can then be used inside @var{body}. +@end defmac + +@defmac pcase-let* bindings body@dots{} +Bind variables according to @var{bindings} and then eval @var{body}. + +@var{bindings} is a list of bindings of the form @code{(@var{pattern} +@var{exp})}, where @var{exp} is an expression to evaluate and +@var{pattern} is a destructuring pattern. + +Unlike @code{pcase-let}, but like @code{let*}, each @var{exp} is +matched against its corresponding @var{pattern} before passing to the +next element of @var{bindings}, so the variables introduced in each +binding are available in the @var{exp}s that follow it, additionally +to being available in @var{body}. +@end defmac + +@findex dolist +@defmac pcase-dolist (pattern list) body@dots{} +This construct executes @var{body} once for each element of +@var{list}, in a context where the destructuring pattern +@var{pattern} was matched against the element. +When @var{pattern} is a simple variable, this ends up being equivalent +to @code{dolist}. +@end defmac + + @node Iteration @section Iteration @cindex iteration ^ permalink raw reply related [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-30 19:21 ` Stefan Monnier @ 2018-10-30 19:54 ` Eli Zaretskii 2018-10-30 20:44 ` Stefan Monnier 2018-11-01 1:40 ` Garreau, Alexandre 2018-10-30 20:04 ` Dmitry Gutov 1 sibling, 2 replies; 375+ messages in thread From: Eli Zaretskii @ 2018-10-30 19:54 UTC (permalink / raw) To: Stefan Monnier; +Cc: emacs-devel > From: Stefan Monnier <monnier@iro.umontreal.ca> > Date: Tue, 30 Oct 2018 15:21:52 -0400 > > >> +* Destructuring patterns:: Using pcase patterns to extract subfields. > > We never used "pcase patterns" in the manual before, so I wonder > > whether we should start now. If we want to do that, this should be > > defined before it is used. > > I'm uncomfortable using "pattern" to refer to "pcase pattern" unless the > context makes it clear. I'm not completely sure where best to define > pcase patterns. I think the best place of defining them is where we first describe them, i.e. in the section about pcase itself. > >> +The macros described in this section use @emph{destructuring} > >> +patterns, which are normal Pcase patterns used in a context where we > >> +presume that the object does match the pattern, and we only want > >> +to extract some subfields. > > > > I think we need to define "destructuring" here (or elsewhere in the > > manual, and have a cross-reference there in this section). > > The paragraph you quoted is exactly what I consider the definition of > "destructuring pattern" (I don't see a need to define "destructuring" > separately: the word placed in front of "pattern" is here treated as > a kind of "proper name", just chosen so that it will help some if they > already know the term from elsewhere, such as cl-destructuring-bind). The "destructuring" part needs to make sense, or at least we should strive that it does. It isn't a random word. > > Readers that aren't familiar with that term will not be able to > > understand why this word is used here. We need to start this with > > something like > > > > @dfn{Destructuring} means ... > > I'd rather rename those to "Monnier patterns" and avoid the problem, if > that's what it takes. No, I think "destructuring" is about right. How about this text: @dfn{Destructuring} of an object is an operation that extracts multiple values stored in the object, e.g., the 2nd and the 3rd element of a list or a vector. @dfn{Destructuring binding} is similar to a local binding (@pxref{Local Variables}), but it gives values to multiple elements of a variable by extracting those values from an object of compatible structure. > > It would also help to tell what exactly makes a pattern a > > destructuring one. > > As the paragraph says: it's the context in which it's used. I'm not sure I understand. AFAIU, not every pattern described in "pcase Macro" can be a destructuring one. Right? > >> +All @var{exp}s are evaluated first after which they are matched > >> +against their respective @var{pattern}, introducing new variable > >> +bindings which can then be used inside @var{body}. > > AFAIU, this means only some of the pcase patterns make sense in this > > context. If that is true, I'd suggest ti somehow tell which are (or > > which aren't, if that's easier). > > Not sure what you're thinking of. See above: not every pattern can be a destructuring one, AFAIU. > >> +@defmac pcase-dolist (pattern list) body@dots{} > >> +This construct executes @var{body} once for each element of > >> +@var{list}, in a context where the destructuring pattern > >> +@var{pattern} was matched against the element. > > > > I don't think I understand what "in a context where the pattern was > > matched" means here. Is any aspect of the match except destructuring > > bindings relevant to execution of the body? > > No. But those extra bindings are exactly the context I'm referring to. > In my work, "context" and "environment" are the usual words used to > refer to the map that links identifiers to their corresponding > information (typically, type or value depending on the > ...ahem... context). I find this too abstract in general, so I think it's better to be specific where we can. Thanks. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-30 19:54 ` Eli Zaretskii @ 2018-10-30 20:44 ` Stefan Monnier 2018-10-31 15:57 ` Eli Zaretskii 2018-11-01 1:40 ` Garreau, Alexandre 1 sibling, 1 reply; 375+ messages in thread From: Stefan Monnier @ 2018-10-30 20:44 UTC (permalink / raw) To: Eli Zaretskii; +Cc: emacs-devel > I think the best place of defining them is where we first describe > them, i.e. in the section about pcase itself. That's what I tried to do in the patch I had attached. > No, I think "destructuring" is about right. How about this text: > > @dfn{Destructuring} of an object is an operation that extracts > multiple values stored in the object, e.g., the 2nd and the 3rd > element of a list or a vector. @dfn{Destructuring binding} is > similar to a local binding (@pxref{Local Variables}), but it gives > values to multiple elements of a variable by extracting those values > from an object of compatible structure. Fine by me. >> > It would also help to tell what exactly makes a pattern a >> > destructuring one. >> As the paragraph says: it's the context in which it's used. > I'm not sure I understand. AFAIU, not every pattern described in > "pcase Macro" can be a destructuring one. Right? A destructuring pattern can bind any number of variables, so I don't see why we should limit this number to be strictly positive. A pattern like 'Emacs will not be very useful on its own in pcase-let, admittedly, but it's perfectly valid to use it (it will just do the same as _, which is often convenient to use when you don't care about the value). And of course, it can even be useful to use it within a larger pattern, e.g. (pcase-let (((or (and 'Emacs (let x 'a)) `(,x . ,_)) 'Emacs)) x) will return `a` whereas (pcase-let (((or (and 'Emacs (let x 'a)) `(,x . ,_)) 'Typer)) x) will signal an error (because it's trying to destructure `Typer` according to `(,x . ,_)). > See above: not every pattern can be a destructuring one, AFAIU. They all can be used as destructuring patterns. Some are more often useful than others. > I find this too abstract in general, so I think it's better to be > specific where we can. So, but this is as specific as I can be. Maybe you'd prefer something less specific. See new patch below, Stefan diff --git a/doc/lispref/control.texi b/doc/lispref/control.texi index 5be4b298b4..06c6622bf0 100644 --- a/doc/lispref/control.texi +++ b/doc/lispref/control.texi @@ -477,6 +477,7 @@ Pattern-Matching Conditional * The @code{pcase} macro: pcase Macro. Plus examples and caveats. * Extending @code{pcase}: Extending pcase. Define new kinds of patterns. * Backquote-Style Patterns: Backquote Patterns. Structural matching. +* Destructuring patterns:: Using pcase patterns to extract subfields. @end menu @node pcase Macro @@ -497,6 +498,10 @@ pcase Macro Otherwise, @code{pcase} evaluates to @code{nil}. @end defmac +Each @var{pattern} has to be a @dfn{pcase pattern}, which can either +use one of the core patterns defined below, or use one of the patterns +defined via @code{pcase-defmacro}. + The rest of this subsection describes different forms of core patterns, presents some examples, @@ -1168,6 +1173,90 @@ Backquote Patterns (evaluate '(sub 1 2) nil) @result{} error @end example +@node Destructuring patterns +@subsection Destructuring Patterns +@cindex destructuring patterns + +Pcase patterns not only express a condition on the form of the objects +they can match but they can also extract sub-fields of those objects. +Say we have a list and want to extract 2 elements from it with the +following code: + +@example + (pcase l + (`(add ,x ,y) (message "Contains %S and %S" x y))) +@end example + +This will not only extract @code{x} and @code{y} but will additionally +test that @code{l} is a list containing exactly 3 elements and whose +first element is the symbol @code{add}. If any of those tests fail, +@code{pcase} will directly return @code{nil} without calling +@code{message}. + +@dfn{Destructuring} of an object is an operation that extracts +multiple values stored in the object, e.g., the 2nd and the 3rd +element of a list or a vector. @dfn{Destructuring binding} is +similar to a local binding (@pxref{Local Variables}), but it gives +values to multiple elements of a variable by extracting those values +from an object of compatible structure. + +The macros described in this section use @dfn{destructuring +patterns}, which are normal Pcase patterns used in a context where we +presume that the object does match the pattern, and we only want +to extract some subfields. For example: + +@example + (pcase-let ((`(add ,x ,y) l)) + (message "Contains %S and %S" x y)) +@end example + +@noindent +does the same as the previous example, except that it directly tries +to extract @code{x} and @code{y} from @code{l} without first verifying +if @code{l} is a list which has the right number of elements and has +@code{add} as its first element. +The precise behavior when the object does not actually match the +pattern is undefined, although the body will not be silently skipped: +either an error is signaled or the body is run with some of the +variables potentially bound to arbitrary values like @code{nil}. + +@defmac pcase-let bindings body@dots{} +Bind variables according to @var{bindings} and then eval @var{body}. + +@var{bindings} is a list of bindings of the form @w{@code{(@var{pattern} +@var{exp})}}, where @var{exp} is an expression to evaluate and +@var{pattern} is a destructuring pattern. + +All @var{exp}s are evaluated first after which they are matched +against their respective @var{pattern}, introducing new variable +bindings which can then be used inside @var{body}. +@end defmac + +@defmac pcase-let* bindings body@dots{} +Bind variables according to @var{bindings} and then eval @var{body}. + +@var{bindings} is a list of bindings of the form @code{(@var{pattern} +@var{exp})}, where @var{exp} is an expression to evaluate and +@var{pattern} is a destructuring pattern. + +Unlike @code{pcase-let}, but like @code{let*}, each @var{exp} is +matched against its corresponding @var{pattern} before passing to the +next element of @var{bindings}, so the variables introduced in each +binding are available in the @var{exp}s that follow it, additionally +to being available in @var{body}. +@end defmac + +@findex dolist +@defmac pcase-dolist (pattern list) body@dots{} +This construct executes @var{body} once for each element of +@var{list}, in a context where the variables appearing in the the +destructuring pattern @var{pattern} are bound to the corresponding +values found in the element. +When @var{pattern} is a simple variable, this ends up being equivalent +to @code{dolist}. +@end defmac + + @node Iteration @section Iteration @cindex iteration ^ permalink raw reply related [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-30 20:44 ` Stefan Monnier @ 2018-10-31 15:57 ` Eli Zaretskii 2018-10-31 19:35 ` Stefan Monnier 0 siblings, 1 reply; 375+ messages in thread From: Eli Zaretskii @ 2018-10-31 15:57 UTC (permalink / raw) To: Stefan Monnier; +Cc: emacs-devel > From: Stefan Monnier <monnier@IRO.UMontreal.CA> > Cc: emacs-devel@gnu.org > Date: Tue, 30 Oct 2018 16:44:01 -0400 > > See new patch below, Thanks, I think it should go in. We can always improve it later if we want. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-31 15:57 ` Eli Zaretskii @ 2018-10-31 19:35 ` Stefan Monnier 0 siblings, 0 replies; 375+ messages in thread From: Stefan Monnier @ 2018-10-31 19:35 UTC (permalink / raw) To: Eli Zaretskii; +Cc: emacs-devel > Thanks, I think it should go in. We can always improve it later if we > want. Done, thanks, Stefan ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-30 19:54 ` Eli Zaretskii 2018-10-30 20:44 ` Stefan Monnier @ 2018-11-01 1:40 ` Garreau, Alexandre 2018-11-01 4:10 ` Eli Zaretskii 1 sibling, 1 reply; 375+ messages in thread From: Garreau, Alexandre @ 2018-11-01 1:40 UTC (permalink / raw) To: Eli Zaretskii; +Cc: Stefan Monnier, emacs-devel On 2018-10-30 at 21:54, Eli Zaretskii wrote: > No, I think "destructuring" is about right. How about this text: > > @dfn{Destructuring} of an object is an operation that extracts > multiple values stored in the object, e.g., the 2nd and the 3rd > element of a list or a vector. @dfn{Destructuring binding} is > similar to a local binding (@pxref{Local Variables}), but it gives > values to multiple elements of a variable by extracting those values > from an object of compatible structure. “(car list)” is extracting a value stored in an object, yet it’s not destructuring (though a list is a structure). Nor even is “(cons (car list) (caddr list))” or “(setq a (nth 1 list) b (nth 2 list))”. I’d say destructuring, like in python (so to stop referring ocaml) “a,b = 2,3”, implies a “specification reflecting the structure”, so “a,b” *has* to be a pair/two-elements array/list/whatever. So how about: @dfn{Destructuring} of an object is an operation that extracts multiple values stored in the object, by speciying a structure reflecting it, e.g., the 2nd and the 3rd element of a 3-elements list or a vector. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-11-01 1:40 ` Garreau, Alexandre @ 2018-11-01 4:10 ` Eli Zaretskii 2018-11-01 5:21 ` Garreau, Alexandre 0 siblings, 1 reply; 375+ messages in thread From: Eli Zaretskii @ 2018-11-01 4:10 UTC (permalink / raw) To: Garreau, Alexandre; +Cc: monnier, emacs-devel > From: "Garreau\, Alexandre" <galex-713@galex-713.eu> > Cc: Stefan Monnier <monnier@iro.umontreal.ca>, emacs-devel@gnu.org > Date: Thu, 01 Nov 2018 02:40:23 +0100 > > On 2018-10-30 at 21:54, Eli Zaretskii wrote: > > No, I think "destructuring" is about right. How about this text: > > > > @dfn{Destructuring} of an object is an operation that extracts > > multiple values stored in the object, e.g., the 2nd and the 3rd > > element of a list or a vector. @dfn{Destructuring binding} is > > similar to a local binding (@pxref{Local Variables}), but it gives > > values to multiple elements of a variable by extracting those values > > from an object of compatible structure. > > “(car list)” is extracting a value stored in an object, yet it’s not > destructuring (though a list is a structure). Nor even is “(cons (car > list) (caddr list))” or “(setq a (nth 1 list) b (nth 2 list))”. You forget the "multiple" part in the description. "Destructuring" is not a term that Emacs invented. You can look it up on the Internet; I think you will find that the adopted definitions are similar to what I wrote. So we don't need to try too hard in this case, as someone else already did that for us. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-11-01 4:10 ` Eli Zaretskii @ 2018-11-01 5:21 ` Garreau, Alexandre 2018-11-01 18:07 ` Eli Zaretskii 0 siblings, 1 reply; 375+ messages in thread From: Garreau, Alexandre @ 2018-11-01 5:21 UTC (permalink / raw) To: Eli Zaretskii; +Cc: monnier, emacs-devel On 2018/11/01 at 06:10, Eli Zaretskii wrote: >> From: "Garreau\, Alexandre" <galex-713@galex-713.eu> >> Cc: Stefan Monnier <monnier@iro.umontreal.ca>, emacs-devel@gnu.org >> Date: Thu, 01 Nov 2018 02:40:23 +0100 >> >> On 2018-10-30 at 21:54, Eli Zaretskii wrote: >> > No, I think "destructuring" is about right. How about this text: >> > >> > @dfn{Destructuring} of an object is an operation that extracts >> > multiple values stored in the object, e.g., the 2nd and the 3rd >> > element of a list or a vector. @dfn{Destructuring binding} is >> > similar to a local binding (@pxref{Local Variables}), but it gives >> > values to multiple elements of a variable by extracting those values >> > from an object of compatible structure. >> >> “(car list)” is extracting a value stored in an object, yet it’s not >> destructuring (though a list is a structure). Nor even is “(cons (car >> list) (caddr list))” or “(setq a (nth 1 list) b (nth 2 list))”. > > You forget the "multiple" part in the description. Then you forgot “(cons (car list) (caddr list))” which I proposed later. > "Destructuring" is not a term that Emacs invented. Yes, learnt it reading stuff about python and ocaml, afair. > You can look it up on the Internet; I think you will find that the > adopted definitions are similar to what I wrote. Yes, and these are wrong. > So we don't need to try too hard in this case, as someone else already > did that for us. Not “too hard”, nor “hard” at all, nor even correctly. Or then, any reference (hence extraction) to something inside a structure, when done several time, is destructuring, and as this ought to be possible if structures exist, any language with structures / compound data, does destructuring all the time. But when talking about destructuring such as in cl-destructuring-bind, pcase, python/ml/js multiple-assignments, this is different. Wasn’t my definition attempt okay? it even defined three quite used and intuitive terms. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-11-01 5:21 ` Garreau, Alexandre @ 2018-11-01 18:07 ` Eli Zaretskii 2018-11-01 19:35 ` Garreau, Alexandre 0 siblings, 1 reply; 375+ messages in thread From: Eli Zaretskii @ 2018-11-01 18:07 UTC (permalink / raw) To: Garreau, Alexandre; +Cc: monnier, emacs-devel > From: "Garreau\, Alexandre" <galex-713@galex-713.eu> > Cc: monnier@iro.umontreal.ca, emacs-devel@gnu.org > Date: Thu, 01 Nov 2018 06:21:49 +0100 > > >> > @dfn{Destructuring} of an object is an operation that extracts > >> > multiple values stored in the object, e.g., the 2nd and the 3rd > >> > element of a list or a vector. @dfn{Destructuring binding} is > >> > similar to a local binding (@pxref{Local Variables}), but it gives > >> > values to multiple elements of a variable by extracting those values > >> > from an object of compatible structure. > >> > >> “(car list)” is extracting a value stored in an object, yet it’s not > >> destructuring (though a list is a structure). Nor even is “(cons (car > >> list) (caddr list))” or “(setq a (nth 1 list) b (nth 2 list))”. > > > > You forget the "multiple" part in the description. > > Then you forgot “(cons (car list) (caddr list))” which I proposed later. The values need to be extracted in one go, so the above doesn't qualify. > > "Destructuring" is not a term that Emacs invented. > > Yes, learnt it reading stuff about python and ocaml, afair. > > > You can look it up on the Internet; I think you will find that the > > adopted definitions are similar to what I wrote. > > Yes, and these are wrong. :-) > Wasn’t my definition attempt okay? it even defined three quite used and > intuitive terms. It didn't look like a more clear description to me, no. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-11-01 18:07 ` Eli Zaretskii @ 2018-11-01 19:35 ` Garreau, Alexandre 2018-11-01 19:49 ` TEIRLLM ` (2 more replies) 0 siblings, 3 replies; 375+ messages in thread From: Garreau, Alexandre @ 2018-11-01 19:35 UTC (permalink / raw) To: Eli Zaretskii; +Cc: monnier, emacs-devel Le 01/11/2018 à 20h07, Eli Zaretskii a écrit : >> From: "Garreau\, Alexandre" <galex-713@galex-713.eu> >> Cc: monnier@iro.umontreal.ca, emacs-devel@gnu.org >> Date: Thu, 01 Nov 2018 06:21:49 +0100 >> >> >> > @dfn{Destructuring} of an object is an operation that extracts >> >> > multiple values stored in the object, e.g., the 2nd and the 3rd >> >> > element of a list or a vector. @dfn{Destructuring binding} is >> >> > similar to a local binding (@pxref{Local Variables}), but it gives >> >> > values to multiple elements of a variable by extracting those values >> >> > from an object of compatible structure. >> >> >> >> “(car list)” is extracting a value stored in an object, yet it’s not >> >> destructuring (though a list is a structure). Nor even is “(cons (car >> >> list) (caddr list))” or “(setq a (nth 1 list) b (nth 2 list))”. >> > >> > You forget the "multiple" part in the description. >> >> Then you forgot “(cons (car list) (caddr list))” which I proposed later. > > The values need to be extracted in one go, so the above doesn't > qualify. Let’s say this was in a language were arguments evaluation order is not specified, and it is wrapped as macro/function set-two-vars-from-car-and-caddr, how wouldn’t that match your definition? After all this later form can be considered as atomic, or pcase as not atomic (it will necessarily get one value before the other), to me that’s no what’s relevant to the destructuring concept: pcase requires a pattern to specify matched data structure (same for cl-destructuring-bind). That’s what makes “destructuring”. Another example: the pcase and pcase-* forms are destructuring, but the lambda pcase-* forms (full of car, cdr and other structure extraction functions call) are not destructuring, because they don’t refer to matched data structure, don’t specify it, and even ignore anything not being related to what it needs to fetch. >> Wasn’t my definition attempt okay? it even defined three quite used and >> intuitive terms. > > It didn't look like a more clear description to me, no. Do you have some more precise suggestion on why is not clear and how to clearly phrase the concept of “specifying a matched data structure”, or should I just give up and accept the rest of world is fine with a more loose, large, less specific, and according to me, wrong, definition of “destructuring”? ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-11-01 19:35 ` Garreau, Alexandre @ 2018-11-01 19:49 ` TEIRLLM 2018-11-03 2:53 ` Richard Stallman 2018-11-01 19:51 ` TEIRLLM 2018-11-01 20:02 ` Eli Zaretskii 2 siblings, 1 reply; 375+ messages in thread From: TEIRLLM @ 2018-11-01 19:49 UTC (permalink / raw) To: Garreau, Alexandre; +Cc: eliz, monnier, emacs-devel After reading your question more carefully, I do not really remember with certainty whether I launched firefox from venus or mars. I _believe_ to remember that it was mars. Sincerely, Luc. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-11-01 19:49 ` TEIRLLM @ 2018-11-03 2:53 ` Richard Stallman 2018-11-04 11:35 ` Nix 0 siblings, 1 reply; 375+ messages in thread From: Richard Stallman @ 2018-11-03 2:53 UTC (permalink / raw) To: TEIRLLM; +Cc: eliz, monnier, galex-713, emacs-devel [[[ 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. ]]] > After reading your question more carefully, I do not really remember > with certainty whether I launched firefox from venus or mars. I > _believe_ to remember that it was mars. Do we have Emacs users on other planets now? Wow!! -- Dr Richard Stallman President, Free Software Foundation (https://gnu.org, https://fsf.org) Internet Hall-of-Famer (https://internethalloffame.org) ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-11-03 2:53 ` Richard Stallman @ 2018-11-04 11:35 ` Nix 2018-11-04 12:40 ` Garreau, Alexandre 0 siblings, 1 reply; 375+ messages in thread From: Nix @ 2018-11-04 11:35 UTC (permalink / raw) To: Richard Stallman; +Cc: galex-713, eliz, monnier, TEIRLLM, emacs-devel On 3 Nov 2018, Richard Stallman told this: > [[[ 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. ]]] > > > After reading your question more carefully, I do not really remember > > with certainty whether I launched firefox from venus or mars. I > > _believe_ to remember that it was mars. > > Do we have Emacs users on other planets now? Wow!! I thought this was implying that pcase is from Mars, cond is from Venus (or vice versa). :) -- NULL && (void) ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-11-04 11:35 ` Nix @ 2018-11-04 12:40 ` Garreau, Alexandre 0 siblings, 0 replies; 375+ messages in thread From: Garreau, Alexandre @ 2018-11-04 12:40 UTC (permalink / raw) To: Nix; +Cc: eliz, emacs-devel, Richard Stallman, TEIRLLM, monnier On 2018/11/04 at 11:35, Nix wrote: > On 3 Nov 2018, Richard Stallman told this: > >> [[[ 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. ]]] >> >> > After reading your question more carefully, I do not really remember >> > with certainty whether I launched firefox from venus or mars. I >> > _believe_ to remember that it was mars. >> >> Do we have Emacs users on other planets now? Wow!! > > I thought this was implying that pcase is from Mars, cond is from Venus > (or vice versa). :) I assumed mars and venus were hostnames (unless it was part of a (context-lacking, for us) joke), I don’t see the relationship between firefox and elisp (yet there’s one between a such message and emacs since it was posted on this list, implying the author uses emacs anyway). ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-11-01 19:35 ` Garreau, Alexandre 2018-11-01 19:49 ` TEIRLLM @ 2018-11-01 19:51 ` TEIRLLM 2018-11-01 20:02 ` Eli Zaretskii 2 siblings, 0 replies; 375+ messages in thread From: TEIRLLM @ 2018-11-01 19:51 UTC (permalink / raw) To: Garreau, Alexandre; +Cc: eliz, monnier, emacs-devel Sorry for my previous message. I replied by error to the wrong message. Had nothing to do with emacs-devel. Sincerely, Luc. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-11-01 19:35 ` Garreau, Alexandre 2018-11-01 19:49 ` TEIRLLM 2018-11-01 19:51 ` TEIRLLM @ 2018-11-01 20:02 ` Eli Zaretskii 2 siblings, 0 replies; 375+ messages in thread From: Eli Zaretskii @ 2018-11-01 20:02 UTC (permalink / raw) To: Garreau, Alexandre; +Cc: monnier, emacs-devel > From: "Garreau\, Alexandre" <galex-713@galex-713.eu> > Cc: monnier@iro.umontreal.ca, emacs-devel@gnu.org > Date: Thu, 01 Nov 2018 20:35:41 +0100 > > Let’s say this was in a language were arguments evaluation order is not > specified, and it is wrapped as macro/function set-two-vars-from-car-and-caddr, > how wouldn’t that match your definition? > > After all this later form can be considered as atomic, or pcase as not > atomic (it will necessarily get one value before the other) That's implementation details. We are talking about defining the concept. > > It didn't look like a more clear description to me, no. > > Do you have some more precise suggestion on why is not clear and how to > clearly phrase the concept of “specifying a matched data structure” One problem with your suggestion is that destructuring itself doesn't need specification of a matching structure to extract values into, that's only needed for destructuring binding. When explaining destructuring binding, I used "object of compatible structure" because I deliberately wanted to avoid using the concept of "matching", which can easily cause misinterpretation due to its other meanings in the context of Emacs. > should I just give up and accept the rest of world is fine with a more > loose, large, less specific, and according to me, wrong, definition of > “destructuring”? That's also an option, of course. Yet another option is to trust my experience in writing Emacs documentation a little more. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-30 19:21 ` Stefan Monnier 2018-10-30 19:54 ` Eli Zaretskii @ 2018-10-30 20:04 ` Dmitry Gutov 2018-10-30 20:46 ` Stefan Monnier 1 sibling, 1 reply; 375+ messages in thread From: Dmitry Gutov @ 2018-10-30 20:04 UTC (permalink / raw) To: Stefan Monnier, emacs-devel On 30.10.2018 21:21, Stefan Monnier wrote: >> It would also help to tell what exactly makes a pattern a >> destructuring one. > As the paragraph says: it's the context in which it's used. Couldn't we also say that a pattern with "holes" is a destructuring pattern, not matter if it is used in pcase-let, or just pcase? ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-30 20:04 ` Dmitry Gutov @ 2018-10-30 20:46 ` Stefan Monnier 2018-10-31 13:41 ` Dmitry Gutov 0 siblings, 1 reply; 375+ messages in thread From: Stefan Monnier @ 2018-10-30 20:46 UTC (permalink / raw) To: emacs-devel > Couldn't we also say that a pattern with "holes" is a destructuring pattern, > not matter if it is used in pcase-let, or just pcase? We could, but the reason why I'm trying to define a new term (which I called here "destructuring pattern") is to define what happens with pcase-let, pcase-dolist, pcase-let* where the pattern is assumed to match. Stefan ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-30 20:46 ` Stefan Monnier @ 2018-10-31 13:41 ` Dmitry Gutov 2018-10-31 13:52 ` Stefan Monnier 0 siblings, 1 reply; 375+ messages in thread From: Dmitry Gutov @ 2018-10-31 13:41 UTC (permalink / raw) To: Stefan Monnier, emacs-devel On 30.10.2018 22:46, Stefan Monnier wrote: >> Couldn't we also say that a pattern with "holes" is a destructuring pattern, >> not matter if it is used in pcase-let, or just pcase? > > We could, but the reason why I'm trying to define a new term (which > I called here "destructuring pattern") is to define what happens with > pcase-let, pcase-dolist, pcase-let* where the pattern is assumed > to match. I only meant to say that introducing a term that somebody fairly familiar with the subject might misinterpret without reading its definition in the manual, could be suboptimal. But don't mind me, I don't have any alternative proposals anyway. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-31 13:41 ` Dmitry Gutov @ 2018-10-31 13:52 ` Stefan Monnier 2018-10-31 15:50 ` Eli Zaretskii 0 siblings, 1 reply; 375+ messages in thread From: Stefan Monnier @ 2018-10-31 13:52 UTC (permalink / raw) To: Dmitry Gutov; +Cc: emacs-devel >>> Couldn't we also say that a pattern with "holes" is a destructuring pattern, >>> not matter if it is used in pcase-let, or just pcase? >> We could, but the reason why I'm trying to define a new term (which >> I called here "destructuring pattern") is to define what happens with >> pcase-let, pcase-dolist, pcase-let* where the pattern is assumed >> to match. > I only meant to say that introducing a term that somebody fairly familiar > with the subject might misinterpret without reading its definition in the > manual, could be suboptimal. Agreed. > But don't mind me, I don't have any alternative proposals anyway. Neither do I, Stefan ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-31 13:52 ` Stefan Monnier @ 2018-10-31 15:50 ` Eli Zaretskii 2018-10-31 16:05 ` Dmitry Gutov 0 siblings, 1 reply; 375+ messages in thread From: Eli Zaretskii @ 2018-10-31 15:50 UTC (permalink / raw) To: Stefan Monnier; +Cc: emacs-devel, dgutov > From: Stefan Monnier <monnier@IRO.UMontreal.CA> > Date: Wed, 31 Oct 2018 09:52:37 -0400 > Cc: emacs-devel@gnu.org > > >>> Couldn't we also say that a pattern with "holes" is a destructuring pattern, > >>> not matter if it is used in pcase-let, or just pcase? > >> We could, but the reason why I'm trying to define a new term (which > >> I called here "destructuring pattern") is to define what happens with > >> pcase-let, pcase-dolist, pcase-let* where the pattern is assumed > >> to match. > > I only meant to say that introducing a term that somebody fairly familiar > > with the subject might misinterpret without reading its definition in the > > manual, could be suboptimal. > > Agreed. > > > But don't mind me, I don't have any alternative proposals anyway. > > Neither do I, Can someone enlighten me regarding those "holes"? What does that allude to? ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-31 15:50 ` Eli Zaretskii @ 2018-10-31 16:05 ` Dmitry Gutov 2018-10-31 16:13 ` Eli Zaretskii 0 siblings, 1 reply; 375+ messages in thread From: Dmitry Gutov @ 2018-10-31 16:05 UTC (permalink / raw) To: Eli Zaretskii, Stefan Monnier; +Cc: emacs-devel On 31.10.2018 17:50, Eli Zaretskii wrote: >>>>> Couldn't we also say that a pattern with "holes" is a destructuring pattern, >>>>> not matter if it is used in pcase-let, or just pcase? >>>> We could, but the reason why I'm trying to define a new term (which >>>> I called here "destructuring pattern") is to define what happens with >>>> pcase-let, pcase-dolist, pcase-let* where the pattern is assumed >>>> to match. >>> I only meant to say that introducing a term that somebody fairly familiar >>> with the subject might misinterpret without reading its definition in the >>> manual, could be suboptimal. >> >> Agreed. >> >>> But don't mind me, I don't have any alternative proposals anyway. >> >> Neither do I, > > Can someone enlighten me regarding those "holes"? What does that > allude to? I stole the term from Clement here: http://lists.gnu.org/archive/html/emacs-devel/2018-10/msg00590.html ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-31 16:05 ` Dmitry Gutov @ 2018-10-31 16:13 ` Eli Zaretskii 2018-10-31 16:27 ` Dmitry Gutov ` (2 more replies) 0 siblings, 3 replies; 375+ messages in thread From: Eli Zaretskii @ 2018-10-31 16:13 UTC (permalink / raw) To: Dmitry Gutov; +Cc: monnier, emacs-devel > Cc: emacs-devel@gnu.org > From: Dmitry Gutov <dgutov@yandex.ru> > Date: Wed, 31 Oct 2018 18:05:44 +0200 > > > Can someone enlighten me regarding those "holes"? What does that > > allude to? > > I stole the term from Clement here: > http://lists.gnu.org/archive/html/emacs-devel/2018-10/msg00590.html Ah, the elements that are assigned by destructuring? I indeed hoped we could identify in some way the patterns which satisfy that condition. I didn't give up yet. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-31 16:13 ` Eli Zaretskii @ 2018-10-31 16:27 ` Dmitry Gutov 2018-10-31 16:33 ` Dmitry Gutov ` (2 more replies) 2018-10-31 17:48 ` Clément Pit-Claudel 2018-11-03 13:15 ` Eli Zaretskii 2 siblings, 3 replies; 375+ messages in thread From: Dmitry Gutov @ 2018-10-31 16:27 UTC (permalink / raw) To: Eli Zaretskii; +Cc: monnier, emacs-devel On 31.10.2018 18:13, Eli Zaretskii wrote: > Ah, the elements that are assigned by destructuring? I indeed hoped > we could identify in some way the patterns which satisfy that > condition. I didn't give up yet. Yeah, so we could say a pattern is a "destructuring" one if it introduces new bindings, so to speak. Not sure if it will help with the manual entries, though. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-31 16:27 ` Dmitry Gutov @ 2018-10-31 16:33 ` Dmitry Gutov 2018-10-31 16:54 ` Eli Zaretskii 2018-10-31 16:52 ` Eli Zaretskii 2018-10-31 18:55 ` Michael Heerdegen 2 siblings, 1 reply; 375+ messages in thread From: Dmitry Gutov @ 2018-10-31 16:33 UTC (permalink / raw) To: Eli Zaretskii; +Cc: monnier, emacs-devel On 31.10.2018 18:27, Dmitry Gutov wrote: > On 31.10.2018 18:13, Eli Zaretskii wrote: > >> Ah, the elements that are assigned by destructuring? I indeed hoped >> we could identify in some way the patterns which satisfy that >> condition. I didn't give up yet. > > Yeah, so we could say a pattern is a "destructuring" one if it > introduces new bindings, so to speak. > > Not sure if it will help with the manual entries, though. ...after all, a destructuring construct like pcase-dolist or pcase-let doesn't *have to* be used with destructuring patterns as defined above. It would simply be pointless to do otherwise, most of the time, but they can be used with simple ones, too. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-31 16:33 ` Dmitry Gutov @ 2018-10-31 16:54 ` Eli Zaretskii 2018-10-31 16:58 ` Dmitry Gutov 0 siblings, 1 reply; 375+ messages in thread From: Eli Zaretskii @ 2018-10-31 16:54 UTC (permalink / raw) To: Dmitry Gutov; +Cc: monnier, emacs-devel > From: Dmitry Gutov <dgutov@yandex.ru> > Cc: monnier@IRO.UMontreal.CA, emacs-devel@gnu.org > Date: Wed, 31 Oct 2018 18:33:43 +0200 > > ...after all, a destructuring construct like pcase-dolist or pcase-let > doesn't *have to* be used with destructuring patterns as defined above. > > It would simply be pointless to do otherwise, most of the time, but they > can be used with simple ones, too. I think it is important to explain which patterns make most sense in these macros. That other patterns can be used with little or no usefulness shouldn't deter us from saying what _is_ useful. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-31 16:54 ` Eli Zaretskii @ 2018-10-31 16:58 ` Dmitry Gutov 0 siblings, 0 replies; 375+ messages in thread From: Dmitry Gutov @ 2018-10-31 16:58 UTC (permalink / raw) To: Eli Zaretskii; +Cc: monnier, emacs-devel On 31.10.2018 18:54, Eli Zaretskii wrote: > I think it is important to explain which patterns make most sense in > these macros. That other patterns can be used with little or no > usefulness shouldn't deter us from saying what _is_ useful. Agreed. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-31 16:27 ` Dmitry Gutov 2018-10-31 16:33 ` Dmitry Gutov @ 2018-10-31 16:52 ` Eli Zaretskii 2018-10-31 18:55 ` Michael Heerdegen 2 siblings, 0 replies; 375+ messages in thread From: Eli Zaretskii @ 2018-10-31 16:52 UTC (permalink / raw) To: Dmitry Gutov; +Cc: monnier, emacs-devel > Cc: monnier@IRO.UMontreal.CA, emacs-devel@gnu.org > From: Dmitry Gutov <dgutov@yandex.ru> > Date: Wed, 31 Oct 2018 18:27:04 +0200 > > On 31.10.2018 18:13, Eli Zaretskii wrote: > > > Ah, the elements that are assigned by destructuring? I indeed hoped > > we could identify in some way the patterns which satisfy that > > condition. I didn't give up yet. > > Yeah, so we could say a pattern is a "destructuring" one if it > introduces new bindings, so to speak. Something like that, yes. I'm still looking for the right wording. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-31 16:27 ` Dmitry Gutov 2018-10-31 16:33 ` Dmitry Gutov 2018-10-31 16:52 ` Eli Zaretskii @ 2018-10-31 18:55 ` Michael Heerdegen 2018-10-31 19:23 ` Eli Zaretskii 2 siblings, 1 reply; 375+ messages in thread From: Michael Heerdegen @ 2018-10-31 18:55 UTC (permalink / raw) To: Dmitry Gutov; +Cc: Eli Zaretskii, monnier, emacs-devel Dmitry Gutov <dgutov@yandex.ru> writes: > Yeah, so we could say a pattern is a "destructuring" one if it > introduces new bindings, so to speak. I wouldn't call a `let' or `app' pattern that introduces a new binding destructuring per se. OTOH, I would call a pattern using ` that tests e.g. the car of the matched object with e.g. `pred' destructuring even if that car is not bound to a variable. With other words: I would say a pattern where subpatterns are matched against parts of a compound object is desctructuring. Michael. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-31 18:55 ` Michael Heerdegen @ 2018-10-31 19:23 ` Eli Zaretskii 2018-10-31 19:50 ` Michael Heerdegen 0 siblings, 1 reply; 375+ messages in thread From: Eli Zaretskii @ 2018-10-31 19:23 UTC (permalink / raw) To: Michael Heerdegen; +Cc: emacs-devel, monnier, dgutov > From: Michael Heerdegen <michael_heerdegen@web.de> > Cc: Eli Zaretskii <eliz@gnu.org>, monnier@IRO.UMontreal.CA, emacs-devel@gnu.org > Date: Wed, 31 Oct 2018 19:55:23 +0100 > > I wouldn't call a `let' or `app' pattern that introduces a new binding > destructuring per se. OTOH, I would call a pattern using ` that tests > e.g. the car of the matched object with e.g. `pred' destructuring even > if that car is not bound to a variable. Can you give an example? I don't think I follow. > With other words: I would say a pattern where subpatterns are matched > against parts of a compound object is desctructuring. But note that your generalization is inconsistent with your example: there's no "pattern matching" in the example, there's only a "matched object", which is a matching of an entirely different kind. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-31 19:23 ` Eli Zaretskii @ 2018-10-31 19:50 ` Michael Heerdegen 2018-10-31 20:05 ` Eli Zaretskii 2018-10-31 20:06 ` Stefan Monnier 0 siblings, 2 replies; 375+ messages in thread From: Michael Heerdegen @ 2018-10-31 19:50 UTC (permalink / raw) To: Eli Zaretskii; +Cc: emacs-devel, monnier, dgutov Eli Zaretskii <eliz@gnu.org> writes: > > I wouldn't call a `let' or `app' pattern that introduces a new binding > > destructuring per se. OTOH, I would call a pattern using ` that tests > > e.g. the car of the matched object with e.g. `pred' destructuring even > > if that car is not bound to a variable. > > Can you give an example? I don't think I follow. (pcase '(1 2 3) ((let a 3) a)) ==> 3 Is the used pattern destructuring? It binds a variable. Or (pcase '(1 2 3) ((app (lambda (thing) 27) x) x)) ==> 27 As in the above example, the pattern ignores the given object. OTOH, when you use `app' with a function like `car' (the ` pcase macro is defined like this), it can be used for destructuring. The feature to bind variables is totally orthogonal to destructuring. The two are often used together, however, but that shouldn't let us confuse these two different things. > > With other words: I would say a pattern where subpatterns are matched > > against parts of a compound object is desctructuring. > > But note that your generalization is inconsistent with your example: > there's no "pattern matching" in the example, there's only a "matched > object", which is a matching of an entirely different kind. I think it is. I mean a pattern like `(,a ,b) is destructuring, independently from the object being matched, because when used for matching it (tries to) extract parts of a compound object and tests these with subpatterns (a, b in this case). The pattern fails to match objects that are not compound or have the wrong structure. But trying to use the pattern for matching tries to extract and analyse the parts of any object. That's why I would call the pattern destructuring. To give an exact accurate definition is nearly impossible, however. For example, is (or 'foo `(,a ,b)) desctructuring? Is (pred some-fun) destructuring if SOME-FUN may look at the parts of its argument? How would you define that? I don't think "destructuring" is such a good term to use in the docs, apart from giving a hint what ` is about. Michael. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-31 19:50 ` Michael Heerdegen @ 2018-10-31 20:05 ` Eli Zaretskii 2018-10-31 20:41 ` Michael Heerdegen 2018-10-31 20:06 ` Stefan Monnier 1 sibling, 1 reply; 375+ messages in thread From: Eli Zaretskii @ 2018-10-31 20:05 UTC (permalink / raw) To: Michael Heerdegen; +Cc: emacs-devel, monnier, dgutov > From: Michael Heerdegen <michael_heerdegen@web.de> > Cc: dgutov@yandex.ru, monnier@IRO.UMontreal.CA, emacs-devel@gnu.org > Date: Wed, 31 Oct 2018 20:50:58 +0100 > > Eli Zaretskii <eliz@gnu.org> writes: > > > > I wouldn't call a `let' or `app' pattern that introduces a new binding > > > destructuring per se. OTOH, I would call a pattern using ` that tests > > > e.g. the car of the matched object with e.g. `pred' destructuring even > > > if that car is not bound to a variable. > > > > Can you give an example? I don't think I follow. > > (pcase '(1 2 3) > ((let a 3) a)) > ==> 3 Thanks, but I meant an example of what's described after the "OTOH". > To give an exact accurate definition is nearly impossible, however. That's not what I'm after. I'm after a definition that's usable and useful in practice, even if it has to be slightly inaccurate. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-31 20:05 ` Eli Zaretskii @ 2018-10-31 20:41 ` Michael Heerdegen 2018-11-01 4:14 ` Eli Zaretskii 0 siblings, 1 reply; 375+ messages in thread From: Michael Heerdegen @ 2018-10-31 20:41 UTC (permalink / raw) To: Eli Zaretskii; +Cc: emacs-devel, monnier, dgutov Eli Zaretskii <eliz@gnu.org> writes: > > (pcase '(1 2 3) > > ((let a 3) a)) > > ==> 3 > > Thanks, but I meant an example of what's described after the "OTOH". Oh, sorry. How about this: (defun second-elt-is-positive-p (l) (pcase l (`(,_ ,(pred (< 0)) . ,_) t))) (second-elt-is-positive-p (list 1 2 3)) ==> t (second-elt-is-positive-p (list 1 -2 3)) ==> nil Is the pattern `(,_ ,(pred (< 0)) . ,_) destructuring or does it additionally have to bind at least one variable to be called like that? Such patterns are used in real life - some bind variables, but others are only used as tests to see if the structure fulfils certain requirements. I guess there is no sharp dividing line. Michael. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-31 20:41 ` Michael Heerdegen @ 2018-11-01 4:14 ` Eli Zaretskii 0 siblings, 0 replies; 375+ messages in thread From: Eli Zaretskii @ 2018-11-01 4:14 UTC (permalink / raw) To: Michael Heerdegen; +Cc: emacs-devel, monnier, dgutov > From: Michael Heerdegen <michael_heerdegen@web.de> > Cc: dgutov@yandex.ru, monnier@IRO.UMontreal.CA, emacs-devel@gnu.org > Date: Wed, 31 Oct 2018 21:41:01 +0100 > > (defun second-elt-is-positive-p (l) > (pcase l > (`(,_ ,(pred (< 0)) . ,_) t))) > > (second-elt-is-positive-p (list 1 2 3)) > ==> t > > (second-elt-is-positive-p (list 1 -2 3)) > ==> nil > > Is the pattern `(,_ ,(pred (< 0)) . ,_) destructuring or does it > additionally have to bind at least one variable to be called like that? I think we have a destructuring here, since elements of a list are extracted and assigned to the elements of the pattern. What we do with the extracted elements (ignore 2 of them and apply a predicate to the 3rd) is not really important for the purposes of this discussion. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-31 19:50 ` Michael Heerdegen 2018-10-31 20:05 ` Eli Zaretskii @ 2018-10-31 20:06 ` Stefan Monnier 2018-10-31 20:12 ` Eli Zaretskii 1 sibling, 1 reply; 375+ messages in thread From: Stefan Monnier @ 2018-10-31 20:06 UTC (permalink / raw) To: emacs-devel > (pcase '(1 2 3) > ((let a 3) a)) > ==> 3 > > Is the used pattern destructuring? It binds a variable. I think it's not worth trying to define precisely which patterns are "destructuring" and which aren't. We can just show two clear examples, like a 'emacs pattern and a `(,a . ,b) pattern to contrast the two. Stefan ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-31 20:06 ` Stefan Monnier @ 2018-10-31 20:12 ` Eli Zaretskii 0 siblings, 0 replies; 375+ messages in thread From: Eli Zaretskii @ 2018-10-31 20:12 UTC (permalink / raw) To: Stefan Monnier; +Cc: emacs-devel > From: Stefan Monnier <monnier@iro.umontreal.ca> > Date: Wed, 31 Oct 2018 16:06:38 -0400 > > I think it's not worth trying to define precisely which patterns are > "destructuring" and which aren't. We can just show two clear examples, > like a 'emacs pattern and a `(,a . ,b) pattern to contrast the two. Agreed. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-31 16:13 ` Eli Zaretskii 2018-10-31 16:27 ` Dmitry Gutov @ 2018-10-31 17:48 ` Clément Pit-Claudel 2018-10-31 18:11 ` Eli Zaretskii 2018-11-01 1:34 ` Garreau, Alexandre 2018-11-03 13:15 ` Eli Zaretskii 2 siblings, 2 replies; 375+ messages in thread From: Clément Pit-Claudel @ 2018-10-31 17:48 UTC (permalink / raw) To: emacs-devel On 31/10/2018 12.13, Eli Zaretskii wrote: >> Cc: emacs-devel@gnu.org >> From: Dmitry Gutov <dgutov@yandex.ru> >> Date: Wed, 31 Oct 2018 18:05:44 +0200 >> >>> Can someone enlighten me regarding those "holes"? What does that >>> allude to? >> >> I stole the term from Clement here: >> http://lists.gnu.org/archive/html/emacs-devel/2018-10/msg00590.html > > Ah, the elements that are assigned by destructuring? I indeed hoped > we could identify in some way the patterns which satisfy that > condition. I didn't give up yet. Regarding the word "holes": I think these ","-prefixed symbols are typically called "pattern-matching variables", or "placeholders". "holes" is the more colloquial term, the idea being that if you "fill" the "holes" in the pattern with the appropriate values, you get the original data back (formally, you perform a "substitution" of the "placeholders"). Regarding the term "destructuring pattern": I think it's perfect. The only other decent alternative I can think of would be "variable-binding pattern". Clément. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-31 17:48 ` Clément Pit-Claudel @ 2018-10-31 18:11 ` Eli Zaretskii 2018-10-31 18:28 ` Clément Pit-Claudel 2018-11-01 1:34 ` Garreau, Alexandre 1 sibling, 1 reply; 375+ messages in thread From: Eli Zaretskii @ 2018-10-31 18:11 UTC (permalink / raw) To: Clément Pit-Claudel; +Cc: emacs-devel > From: Clément Pit-Claudel <cpitclaudel@gmail.com> > Date: Wed, 31 Oct 2018 13:48:42 -0400 > > >> I stole the term from Clement here: > >> http://lists.gnu.org/archive/html/emacs-devel/2018-10/msg00590.html > > > > Ah, the elements that are assigned by destructuring? I indeed hoped > > we could identify in some way the patterns which satisfy that > > condition. I didn't give up yet. > > Regarding the word "holes": I think these ","-prefixed symbols are typically called "pattern-matching variables", or "placeholders". "holes" is the more colloquial term, the idea being that if you "fill" the "holes" in the pattern with the appropriate values, you get the original data back (formally, you perform a "substitution" of the "placeholders"). I actually think you meant "slots", not "holes". > Regarding the term "destructuring pattern": I think it's perfect. But the pattern is not the one that destructures. So I think "pattern-based destructuring" or "destructuring using patterns" would be better. Or something like that. I'm still looking for an appropriate term. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-31 18:11 ` Eli Zaretskii @ 2018-10-31 18:28 ` Clément Pit-Claudel 2018-10-31 18:33 ` Eli Zaretskii 0 siblings, 1 reply; 375+ messages in thread From: Clément Pit-Claudel @ 2018-10-31 18:28 UTC (permalink / raw) To: Eli Zaretskii; +Cc: emacs-devel On 31/10/2018 14.11, Eli Zaretskii wrote: >> From: Clément Pit-Claudel <cpitclaudel@gmail.com> >> Date: Wed, 31 Oct 2018 13:48:42 -0400 >> >>>> I stole the term from Clement here: >>>> http://lists.gnu.org/archive/html/emacs-devel/2018-10/msg00590.html >>> >>> Ah, the elements that are assigned by destructuring? I indeed hoped >>> we could identify in some way the patterns which satisfy that >>> condition. I didn't give up yet. >> >> Regarding the word "holes": I think these ","-prefixed symbols are typically called "pattern-matching variables", or "placeholders". "holes" is the more colloquial term, the idea being that if you "fill" the "holes" in the pattern with the appropriate values, you get the original data back (formally, you perform a "substitution" of the "placeholders"). > > I actually think you meant "slots", not "holes". No, I meant holes :) I've seen that term used both with patterns (see e.g. http://people.cs.uchicago.edu/~blume/classes/aut2008/proglang/handouts/lec-sml.pdf) and contexts (http://homepages.inf.ed.ac.uk/slindley/papers/many-holes.pdf). >> Regarding the term "destructuring pattern": I think it's perfect. > > But the pattern is not the one that destructures. So I think > "pattern-based destructuring" or "destructuring using patterns" would > be better. Or something like that. I'm still looking for an > appropriate term. I think I don't understand what kind of term you're looking for, then :/ A "destructuring pattern" is a thing; "destructuring using patterns" is an action. Sorry for the noise if I'm misunderstanding something. Clément ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-31 18:28 ` Clément Pit-Claudel @ 2018-10-31 18:33 ` Eli Zaretskii 2018-10-31 19:00 ` Yuri Khan ` (2 more replies) 0 siblings, 3 replies; 375+ messages in thread From: Eli Zaretskii @ 2018-10-31 18:33 UTC (permalink / raw) To: Clément Pit-Claudel; +Cc: emacs-devel > Cc: emacs-devel@gnu.org > From: Clément Pit-Claudel <cpitclaudel@gmail.com> > Date: Wed, 31 Oct 2018 14:28:45 -0400 > > > But the pattern is not the one that destructures. So I think > > "pattern-based destructuring" or "destructuring using patterns" would > > be better. Or something like that. I'm still looking for an > > appropriate term. > > I think I don't understand what kind of term you're looking for, then :/ > A "destructuring pattern" is a thing; "destructuring using patterns" is an action. A thing can be called "destructuring" if it destructures something. It's like a "flying carpet": the carpet that flies. But in our case the patterns don't destructure anything, they are a means for destructuring. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-31 18:33 ` Eli Zaretskii @ 2018-10-31 19:00 ` Yuri Khan 2018-10-31 19:20 ` Eli Zaretskii 2018-10-31 19:21 ` Clément Pit-Claudel 2018-10-31 20:03 ` Stefan Monnier 2 siblings, 1 reply; 375+ messages in thread From: Yuri Khan @ 2018-10-31 19:00 UTC (permalink / raw) To: Eli Zaretskii; +Cc: Clément Pit-Claudel, Emacs developers On Thu, Nov 1, 2018 at 1:34 AM Eli Zaretskii <eliz@gnu.org> wrote: > A thing can be called "destructuring" if it destructures something. > It's like a "flying carpet": the carpet that flies. But in our case > the patterns don't destructure anything, they are a means for > destructuring. The construct “<verb>ing <noun>” could alternatively be parsed as “<gerund> <noun>”, with the gerund in the role of a determiner, e.g.: a “walking stick” is a stick that is used for walking, or a “thinking cap” is a cap for thinking. They don’t walk and think on their own, but are tools used in a specific activity. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-31 19:00 ` Yuri Khan @ 2018-10-31 19:20 ` Eli Zaretskii 2018-11-01 0:11 ` Dmitry Gutov 0 siblings, 1 reply; 375+ messages in thread From: Eli Zaretskii @ 2018-10-31 19:20 UTC (permalink / raw) To: Yuri Khan; +Cc: cpitclaudel, emacs-devel > From: Yuri Khan <yurivkhan@gmail.com> > Date: Thu, 1 Nov 2018 02:00:39 +0700 > Cc: Clément Pit-Claudel <cpitclaudel@gmail.com>, > Emacs developers <emacs-devel@gnu.org> > > a “walking stick” is a stick that is used for walking, or a “thinking > cap” is a cap for thinking. They don’t walk and think on their own, > but are tools used in a specific activity. No, they are tools that help in that activity: the stick helps in walking, the hat helps thinking. By contrast, those patterns don't "help" destructuring in any way I could spot. In any case, even if we can find some convoluted justification for "destructuring patterns", I think it's worth our while to try to look for better terminology that doesn't need so many words to explain it, but instead speaks for itself. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-31 19:20 ` Eli Zaretskii @ 2018-11-01 0:11 ` Dmitry Gutov 0 siblings, 0 replies; 375+ messages in thread From: Dmitry Gutov @ 2018-11-01 0:11 UTC (permalink / raw) To: Eli Zaretskii, Yuri Khan; +Cc: cpitclaudel, emacs-devel On 31.10.2018 21:20, Eli Zaretskii wrote: >> a “walking stick” is a stick that is used for walking, or a “thinking >> cap” is a cap for thinking. They don’t walk and think on their own, >> but are tools used in a specific activity. > > No, they are tools that help in that activity: the stick helps in > walking, the hat helps thinking. > > By contrast, those patterns don't "help" destructuring in any way I > could spot. Surely they do: they provide the whole destructuring logic, in a declarative way. pcase then simply interprets it according to its rules. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-31 18:33 ` Eli Zaretskii 2018-10-31 19:00 ` Yuri Khan @ 2018-10-31 19:21 ` Clément Pit-Claudel 2018-10-31 19:29 ` Eli Zaretskii 2018-10-31 20:03 ` Stefan Monnier 2 siblings, 1 reply; 375+ messages in thread From: Clément Pit-Claudel @ 2018-10-31 19:21 UTC (permalink / raw) To: Eli Zaretskii; +Cc: emacs-devel On 31/10/2018 14.33, Eli Zaretskii wrote: >> Cc: emacs-devel@gnu.org >> From: Clément Pit-Claudel <cpitclaudel@gmail.com> >> Date: Wed, 31 Oct 2018 14:28:45 -0400 >> >>> But the pattern is not the one that destructures. So I think >>> "pattern-based destructuring" or "destructuring using patterns" would >>> be better. Or something like that. I'm still looking for an >>> appropriate term. >> >> I think I don't understand what kind of term you're looking for, then :/ >> A "destructuring pattern" is a thing; "destructuring using patterns" is an action. > > A thing can be called "destructuring" if it destructures something. > It's like a "flying carpet": the carpet that flies. But in our case > the patterns don't destructure anything, they are a means for > destructuring. But something can also be called "destructuring" if it's used *for* destructuring: a "swimming pool" is not a pool that swims, it's a pool that's used for swimming. I think of "destructuring" in "destructuring pattern" as a gerund, not a present participle:<we have "shopping lists" and "shaving cream", so why not "destructuring patterns"? :) Clément. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-31 19:21 ` Clément Pit-Claudel @ 2018-10-31 19:29 ` Eli Zaretskii 2018-10-31 19:31 ` Clément Pit-Claudel ` (2 more replies) 0 siblings, 3 replies; 375+ messages in thread From: Eli Zaretskii @ 2018-10-31 19:29 UTC (permalink / raw) To: Clément Pit-Claudel; +Cc: emacs-devel > Cc: emacs-devel@gnu.org > From: Clément Pit-Claudel <cpitclaudel@gmail.com> > Date: Wed, 31 Oct 2018 15:21:05 -0400 > > But something can also be called "destructuring" if it's used *for* destructuring: a "swimming pool" is not a pool that swims, it's a pool that's used for swimming. I think of "destructuring" in "destructuring pattern" as a gerund, not a present participle:<we have "shopping lists" and "shaving cream", so why not "destructuring patterns"? :) They are a kind of jargon. Try to explain that to a Martian. Or even to a non-native English speakers. I speak a couple of languages other than English, and none of them has "swimming pools" and "shopping lists", verbatim. Anyway, I think this argument is futile. I'm trying to find a better terminology that doesn't need explaining; I don't think anyone should have a problem with a clearer terminology. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-31 19:29 ` Eli Zaretskii @ 2018-10-31 19:31 ` Clément Pit-Claudel 2018-10-31 20:36 ` Eli Zaretskii 2018-11-01 0:13 ` Dmitry Gutov 2018-11-01 1:31 ` Garreau, Alexandre 2 siblings, 1 reply; 375+ messages in thread From: Clément Pit-Claudel @ 2018-10-31 19:31 UTC (permalink / raw) To: Eli Zaretskii; +Cc: emacs-devel On 31/10/2018 15.29, Eli Zaretskii wrote: >> Cc: emacs-devel@gnu.org From: Clément Pit-Claudel >> <cpitclaudel@gmail.com> Date: Wed, 31 Oct 2018 15:21:05 -0400 >> >> But something can also be called "destructuring" if it's used *for* >> destructuring: a "swimming pool" is not a pool that swims, it's a >> pool that's used for swimming. I think of "destructuring" in >> "destructuring pattern" as a gerund, not a present participle:<we >> have "shopping lists" and "shaving cream", so why not >> "destructuring patterns"? :) > > They are a kind of jargon. Try to explain that to a Martian. Or > even to a non-native English speakers. You're talking to one :) > Anyway, I think this argument is futile. OK, apologies. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-31 19:31 ` Clément Pit-Claudel @ 2018-10-31 20:36 ` Eli Zaretskii 0 siblings, 0 replies; 375+ messages in thread From: Eli Zaretskii @ 2018-10-31 20:36 UTC (permalink / raw) To: Clément Pit-Claudel; +Cc: emacs-devel > Cc: emacs-devel@gnu.org > From: Clément Pit-Claudel <cpitclaudel@gmail.com> > Date: Wed, 31 Oct 2018 15:31:58 -0400 > > > Anyway, I think this argument is futile. > > OK, apologies. No need to apologize. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-31 19:29 ` Eli Zaretskii 2018-10-31 19:31 ` Clément Pit-Claudel @ 2018-11-01 0:13 ` Dmitry Gutov 2018-11-01 1:31 ` Garreau, Alexandre 2 siblings, 0 replies; 375+ messages in thread From: Dmitry Gutov @ 2018-11-01 0:13 UTC (permalink / raw) To: Eli Zaretskii, Clément Pit-Claudel; +Cc: emacs-devel On 31.10.2018 21:29, Eli Zaretskii wrote: > They are a kind of jargon. Try to explain that to a Martian. Or even > to a non-native English speakers. I am one as well. > I speak a couple of languages other > than English, and none of them has "swimming pools" and "shopping > lists", verbatim. German does, I think. Not that I know it very well, though. > Anyway, I think this argument is futile. I'm trying to find a better > terminology that doesn't need explaining; I don't think anyone should > have a problem with a clearer terminology. I think this term is fine, but please don't let me stop you. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-31 19:29 ` Eli Zaretskii 2018-10-31 19:31 ` Clément Pit-Claudel 2018-11-01 0:13 ` Dmitry Gutov @ 2018-11-01 1:31 ` Garreau, Alexandre 2 siblings, 0 replies; 375+ messages in thread From: Garreau, Alexandre @ 2018-11-01 1:31 UTC (permalink / raw) To: Eli Zaretskii; +Cc: Clément Pit-Claudel, emacs-devel On 2018-10-31 at 21:29, Eli Zaretskii wrote: >> Cc: emacs-devel@gnu.org >> From: Clément Pit-Claudel <cpitclaudel@gmail.com> >> Date: Wed, 31 Oct 2018 15:21:05 -0400 >> >> But something can also be called "destructuring" if it's used *for* >> destructuring: a "swimming pool" is not a pool that swims, it's a >> pool that's used for swimming. I think of "destructuring" in >> "destructuring pattern" as a gerund, not a present participle:<we >> have "shopping lists" and "shaving cream", so why not "destructuring >> patterns"? :) > > They are a kind of jargon. Try to explain that to a Martian. Or even > to a non-native English speakers. On 2018-10-31 at 15:31, Clément Pit-Claudel wrote: > You're talking to one :) I’d say the non english-alphabet letter in the name was an hint ;) Jargon are no harm I’d say, from the moment it is logically as well as straightforwardly formed from other jargon words which are known, and whose relation is imaginable from further explanation (especially definition). Me too btw (perhaps from same place): > I speak a couple of languages other than English, and none of them has > "swimming pools" and "shopping lists", verbatim. Esperanto has (“naĝejo” is litteraly “swimming place”: usually “<verb>ejo” is “place where you <verb>”, very simple to explain to a Martian (and simple generalization of the afterwards-described stacking-language feature (afaik it takes it from Russian and other slavic languages))). I always interpreted english adjectives not to mean “being part of” (or even also “being used for”) but “being related to”: that’s also one key difference between english or esperanto to ido or french (or italian), and I easily understood that at first, while being native of both the two later. For instance, first time I saw it (the stacking-language feature of esperanto) described (it was formally enough “to be understood by a Martian” in intent, I believe), it was about “vaporŝipo” (steamship, notice it’s a direct mapping of meaning with english btw): “it is not a ‘ŝipo’ [ship] made of ‘vaporo’ [steam], it is a ‘ship[…]’ *using* [steam]”, afair, from original Fundamento. In french it’s more precise, like you say “Bateau à vapeur” (ship with (“à” [0] is actually more specific and refer to usage) steam), in italian (“nave a vapore” (same), “vaporetto” (little steam, really quite unrelated), “piroscafo” (made from greek, fire+dive, completely unrelated): these are good languages if you like useless exceptions and dislike useful generalizations. It was also a key difference of “Ido” fork of esperanto: instead of simply stacking related radicals, you use lots of collections of rich preposition that each indicate how in fact they are related: one for transformation, one for composition, one for addition, one for state, one for action [1]… in the end Ido was almost only used by the linguists who invented it, unlike esperanto which, unlike what was claimed by these last, is still used and wasn’t block by some fantasmed “primordial confusion in front of its exagerated generality”. > Anyway, I think this argument is futile. I'm trying to find a better > terminology that doesn't need explaining; I don't think anyone should > have a problem with a clearer terminology. What about a heavier terminology? lighter (and simpler) terms should always be welcome too I believe. Notes and references: [0] https://en.wiktionary.org/wiki/%C3%A0#Preposition_3 [1] <https://fr.wikipedia.org/wiki/Ido#Un_syst%C3%A8me_de_composition_plus_strict> Translation [2]: Composition in Ido obeys stricter rules than in esperanto, especially names, adectives and verbs formations from a radical of a different class. The reversibility principle assume that for each composition rule (affix addition), decomposition rule (affix remove) is valid. Henceforth, while in esperanto an adjective (for instance /papera/, formed on the radical /papero/) can mean an attribute (/papera enciklopedio/: /paper-made encyclopedia/), and a relation (/papera fabriko/: /paper-making factory/), ido will distinguish per construction the attribute /papera/ (“paper” or “of paper” (not “paper-made” exactely)) from the relation /paperala/ (“paper-making”). Similarily, /krono/ mean in esperanto and ido “crown”; where esperanto allow formation of “to crown” by simple /kroni/ (“the fact to crown” is /kronado/), ido requires an affix so the composition is reversible: /kronizar/ (“the fact to crown” is /kronizo/). According Claude Piron, some modifications brought by Ido are in practice impossible to use and ruin spontaneous expression: “Ido displays, on linguistical level, other drawbacks which esperanto suceeded to avoid, but I don’t have at hand documents which would allow me to more go in detail. For instance, if I remember correctly, where esperanto only has the suffix “-igi*”, ido has several: “*-ifar*”, “*-izar*”, “*-igar*”, which match subtleties which were meant to make language clearer, but that, in practice, inhibit natural expression.” [30]. [2] Sorry to embed this here, but I’m still trying to recover my wikipedia account and understand wikicode (and translate it too >< since it’s localized…) before to add this to wikipedia… anyway maybe it would be removed anyway, if done incorrectly enough. [30] http://claudepiron.free.fr/lettresouvertes/ido.htm ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-31 18:33 ` Eli Zaretskii 2018-10-31 19:00 ` Yuri Khan 2018-10-31 19:21 ` Clément Pit-Claudel @ 2018-10-31 20:03 ` Stefan Monnier 2018-11-01 0:07 ` Dmitry Gutov 2 siblings, 1 reply; 375+ messages in thread From: Stefan Monnier @ 2018-10-31 20:03 UTC (permalink / raw) To: emacs-devel > A thing can be called "destructuring" if it destructures something. > It's like a "flying carpet": the carpet that flies. But in our case > the patterns don't destructure anything, they are a means for > destructuring. And let's not forget that what I used this term currently is to talk about the specific way pcase patterns are used within pcase-let (i.e. the way pcase-let and friends skip the tests to verify that the pattern does match). So maybe we should just say "a pattern used to destructure" to clarify that it's not a property of the pattern but of the way it's being used. Stefan ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-31 20:03 ` Stefan Monnier @ 2018-11-01 0:07 ` Dmitry Gutov 0 siblings, 0 replies; 375+ messages in thread From: Dmitry Gutov @ 2018-11-01 0:07 UTC (permalink / raw) To: Stefan Monnier, emacs-devel On 31.10.2018 22:03, Stefan Monnier wrote: >> A thing can be called "destructuring" if it destructures something. >> It's like a "flying carpet": the carpet that flies. But in our case >> the patterns don't destructure anything, they are a means for >> destructuring. > > And let's not forget that what I used this term currently is to talk > about the specific way pcase patterns are used within pcase-let > (i.e. the way pcase-let and friends skip the tests to verify that the > pattern does match). That part of the explanation is pretty counter-intuitive to me. I mean, I get what it's saying (pcase-let skips certain checks), but that's not a property of a pattern (which is a certain form), so the phrase "destructuring pattern" (which, in my mind, should just describe the pattern) shouldn't imply a particular aspect of its use. The way I think of the situation is pcase performs both the structure check and destructuring, and pcase-let only performs destructuring. But destructuring is present in both cases and it's a property of the pattern (and maybe of the input data if the pattern includes an "(or"). > So maybe we should just say "a pattern used to destructure" to clarify > that it's not a property of the pattern but of the way it's being used. Maybe we shouldn't try to explain that through saying that patterns exhibit a certain property in this situation, and explain that purely in terms of behavior of certain macros (pcase-let and pcase-dolist, IIRC)? ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-31 17:48 ` Clément Pit-Claudel 2018-10-31 18:11 ` Eli Zaretskii @ 2018-11-01 1:34 ` Garreau, Alexandre 1 sibling, 0 replies; 375+ messages in thread From: Garreau, Alexandre @ 2018-11-01 1:34 UTC (permalink / raw) To: Clément Pit-Claudel; +Cc: emacs-devel On 2018-10-31 at 13:48, Clément Pit-Claudel wrote: > On 31/10/2018 12.13, Eli Zaretskii wrote: >>> Cc: emacs-devel@gnu.org >>> From: Dmitry Gutov <dgutov@yandex.ru> >>> Date: Wed, 31 Oct 2018 18:05:44 +0200 >>> >>>> Can someone enlighten me regarding those "holes"? What does that >>>> allude to? >>> >>> I stole the term from Clement here: >>> http://lists.gnu.org/archive/html/emacs-devel/2018-10/msg00590.html >> >> Ah, the elements that are assigned by destructuring? I indeed hoped >> we could identify in some way the patterns which satisfy that >> condition. I didn't give up yet. > > Regarding the word "holes": I think these ","-prefixed symbols are > typically called "pattern-matching variables", or "placeholders". > "holes" is the more colloquial term, the idea being that if you "fill" > the "holes" in the pattern with the appropriate values, you get the > original data back (formally, you perform a "substitution" of the > "placeholders"). > > Regarding the term "destructuring pattern": I think it's perfect. The > only other decent alternative I can think of would be > "variable-binding pattern". So may we not define “destructuring pattern” as a “structure pattern that use placeholders”, a “structure pattern” as a “pattern only matching a structure, whose subpatterns match its subelements”, and a “placeholder” as a “match-everything symbol that binds what it match to its name”? ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-31 16:13 ` Eli Zaretskii 2018-10-31 16:27 ` Dmitry Gutov 2018-10-31 17:48 ` Clément Pit-Claudel @ 2018-11-03 13:15 ` Eli Zaretskii 2 siblings, 0 replies; 375+ messages in thread From: Eli Zaretskii @ 2018-11-03 13:15 UTC (permalink / raw) To: dgutov, monnier; +Cc: emacs-devel > Date: Wed, 31 Oct 2018 18:13:25 +0200 > From: Eli Zaretskii <eliz@gnu.org> > Cc: monnier@IRO.UMontreal.CA, emacs-devel@gnu.org > > > Cc: emacs-devel@gnu.org > > From: Dmitry Gutov <dgutov@yandex.ru> > > Date: Wed, 31 Oct 2018 18:05:44 +0200 > > > > > Can someone enlighten me regarding those "holes"? What does that > > > allude to? > > > > I stole the term from Clement here: > > http://lists.gnu.org/archive/html/emacs-devel/2018-10/msg00590.html > > Ah, the elements that are assigned by destructuring? I indeed hoped > we could identify in some way the patterns which satisfy that > condition. I didn't give up yet. It turns out we already have a section for these patterns: "Backquote Patterns". So I just refereed to that section. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-29 21:08 ` Stefan Monnier 2018-10-29 21:53 ` Michael Heerdegen @ 2018-10-30 1:15 ` Garreau, Alexandre 2018-10-30 6:17 ` Eli Zaretskii ` (2 subsequent siblings) 4 siblings, 0 replies; 375+ messages in thread From: Garreau, Alexandre @ 2018-10-30 1:15 UTC (permalink / raw) To: Stefan Monnier; +Cc: emacs-devel On 2018-10-29 at 17:08, Stefan Monnier wrote: >>> > Doc strings which specify fully the arguments to these macros, including >>> > their semantics, and say what the macros do. The current doc strings >>> > (at least some of them) for these macros don't do this. >>> I understand this in theory, but I don't know what it means in this >>> concrete case. >> Take a look at, for example, the doc string for pcase-dolist. In its >> entirety, it's this: > > Thanks. What do you think of the patch below? > > I'd rather keep it defined in terms of its differences w.r.t `dolist`, > but if really needed, we could change the doc so it doesn't rely on > `dolist`s own doc at all. You can do that while being more explicit on how arguments relate. A little redundancy might be welcome, but I believe the standard minimum (that, for instance, would satisfy checkdoc) would only to cite each argument name in upcase and say it is like in `dolist', only if this is *exactely the case*. It is not for “PATTERN” so usage ought to be more detailed: instead of describing what is done, you’d better explain what it is for. So in “More specifically `dolist's VAR binding is replaced by a PATTERN against which each element of the list is matched.” you’re simply describing your macro implementation, which readers doesn’t want (otherwise they would be reading function’s source), you’d better say “PATTERN allow to bind several variables at once through a `pcase' pattern, instead of only one var as in simple `dolist'”. This is way clearer (I really ought to learn how to make up patches ><). > We do have to keep the reference to `pcase` because we don't want to > repeat the definition of what a pcase pattern can look like. Of course. But you want to precise how exactely does it relate to `pcase'. > (defmacro pcase-let (bindings &rest body) > "Like `let' but where you can use `pcase' patterns for bindings. > BODY should be a list of expressions, and BINDINGS should be a list of bindings > -of the form (PAT EXP). > +of the form (PATTERN EXP). So `pcase-let' doesn’t support single variable names bound to `nil' (not that sad, I (sadly) never use that anyway, that’s only for lexical locality tweaking)? I checked, in fact it indeed doesn’t: knowing the other `pcase-' functions docstrings tendency to omit optional behavior, if I didn’t checked, I’d have bet it were supporting it. Then, contrarily to `let' you might make your docstring more readable by changing the arglist spec: "\(fn ((PATTERN EXP)...) BODY...)" or you may be more formal, so it’d become more readable: “BINDINGS is a list of the form (BINDING...), with each BINDING is (PATTERN EXP), where PATTERN is a `pcase' pattern, and EXP the expression it must match.” > ;;;###autoload > (defmacro pcase-dolist (spec &rest body) > - "Like `dolist' but where the binding can be a `pcase' pattern. > + "Superset of `dolist' where the VAR binding can be a `pcase' PATTERN. > +More specifically `dolist's VAR binding is replaced by a PATTERN > +against which each element of the list is matched. > +As in the case of `pcase-let', PATTERN is matched under the assumption > +that it *will* match. First I don’t believe it is a good idea to talk about `pcase-let' in the docstring of another function, or then you should cite the whole family (including `pcase-lambda', etc.), except if they’re tightly tied, but then you should also cite `pcase-dolist' in `pcase-let' docstring, so to make a followable dual-link. > The macro is expanded and optimized under the assumption that those > patterns *will* match, so a mismatch may go undetected or may cause > any kind of error." That’s not explicit enough on the result if not doing so: what kind of error? From what I see there: #+BEGIN_SRC emacs-lisp (pcase-let ((`(,a ,b ,c) (list 1 2))) (list a b c)) ; => (1 2 nil) (pcase-let ((`(,a ,b (2 3)) (list 1 2 3))) (list a b)) ;; => (wrong-type-argument listp 3) (pcase-let ((`(,a ,b (2 3)) (list 1 2 (list 4 5)))) (list a b)) ;; => (1 2) #+END_SRC It seems to be like `pcase-lambda': it binds nil, and doesn’t err anything, as long as the structures are in the same places and the same types. This behavior ought to be documented, or changed. In my message about `pcase-lambda', I wrote: > A given subpattern inside PATTERN might not match values (equality) or > even types, except for each of its subsequences, which *have* to > exist, have the right type, and be in the right place. > \n(fn (PATTERN LIST) BODY...)" > (declare (indent 1) (debug ((pcase-PAT form) body))) > (if (pcase--trivial-upat-p (car spec)) So `pcase-dolist' doesn’t support `dolist'’s `result'? I bet it does (if it doesn’t it’s sad), and like in `pcase-lambda' you again omitted optional arguments from your docstring: this is confusing, as you might as well have implemented it so that to remove or override these. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-29 21:08 ` Stefan Monnier 2018-10-29 21:53 ` Michael Heerdegen 2018-10-30 1:15 ` Garreau, Alexandre @ 2018-10-30 6:17 ` Eli Zaretskii 2018-10-30 12:15 ` Stefan Monnier 2018-10-30 17:22 ` Michael Heerdegen 2018-10-30 18:09 ` Alan Mackenzie 4 siblings, 1 reply; 375+ messages in thread From: Eli Zaretskii @ 2018-10-30 6:17 UTC (permalink / raw) To: Stefan Monnier; +Cc: emacs-devel > From: Stefan Monnier <monnier@iro.umontreal.ca> > Date: Mon, 29 Oct 2018 17:08:38 -0400 > > Thanks. What do you think of the patch below? Thanks for doing this. > I'd rather keep it defined in terms of its differences w.r.t `dolist`, > but if really needed, we could change the doc so it doesn't rely on > `dolist`s own doc at all. I think the doc string should be (more) independent, at least in the pcase-dolist case, because the semantics of executing BODY with PATTERN matched against a LIST element is significantly different from that of executing the dolist BODY with a VAR binding. And the description of that semantics is missing from the doc string you propose. > We do have to keep the reference to `pcase` because we don't want to > repeat the definition of what a pcase pattern can look like. I see no problem to say something like See `pcase' for the description of possible forms of PATTERN. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-30 6:17 ` Eli Zaretskii @ 2018-10-30 12:15 ` Stefan Monnier 2018-10-30 12:38 ` Eli Zaretskii 2018-10-30 14:16 ` Andy Moreton 0 siblings, 2 replies; 375+ messages in thread From: Stefan Monnier @ 2018-10-30 12:15 UTC (permalink / raw) To: Eli Zaretskii; +Cc: emacs-devel > I think the doc string should be (more) independent, at least in the > pcase-dolist case, because the semantics of executing BODY with > PATTERN matched against a LIST element is significantly different from > that of executing the dolist BODY with a VAR binding. Hmm... I really don't see what difference you're thinking of. Maybe a simpler way to document it is to show its definition: (dolist (x LIST) (pcase-let ((PATTERN x)) BODY)) -- Stefan ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-30 12:15 ` Stefan Monnier @ 2018-10-30 12:38 ` Eli Zaretskii 2018-10-30 15:00 ` Stefan Monnier 2018-10-30 14:16 ` Andy Moreton 1 sibling, 1 reply; 375+ messages in thread From: Eli Zaretskii @ 2018-10-30 12:38 UTC (permalink / raw) To: Stefan Monnier; +Cc: emacs-devel > From: Stefan Monnier <monnier@IRO.UMontreal.CA> > Cc: emacs-devel@gnu.org > Date: Tue, 30 Oct 2018 08:15:31 -0400 > > > I think the doc string should be (more) independent, at least in the > > pcase-dolist case, because the semantics of executing BODY with > > PATTERN matched against a LIST element is significantly different from > > that of executing the dolist BODY with a VAR binding. > > Hmm... I really don't see what difference you're thinking of. I thought it was clear: matching doesn't assign any values to anything directly related to BODY, so the mechanism by which it affects execution of BODY needs to be described. > Maybe a simpler way to document it is to show its definition: > > (dolist (x LIST) (pcase-let ((PATTERN x)) BODY)) You aren't saying that showing the code removes the need for any documentation of what it does, do you? ;-) ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-30 12:38 ` Eli Zaretskii @ 2018-10-30 15:00 ` Stefan Monnier 2018-10-30 17:00 ` Eli Zaretskii 0 siblings, 1 reply; 375+ messages in thread From: Stefan Monnier @ 2018-10-30 15:00 UTC (permalink / raw) To: Eli Zaretskii; +Cc: emacs-devel >> (dolist (x LIST) (pcase-let ((PATTERN x)) BODY)) > You aren't saying that showing the code removes the need for any > documentation of what it does, do you? ;-) I think I am, yes. In cases like these where the definition is really just a trivial combination of two less trivial elements, it might be a better option for the docstring, since it is both more concise and more precise than whatever wording we can come up with to try and repeat what dolist and pcase-let do. Stefan ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-30 15:00 ` Stefan Monnier @ 2018-10-30 17:00 ` Eli Zaretskii 2018-10-30 17:27 ` Stefan Monnier 0 siblings, 1 reply; 375+ messages in thread From: Eli Zaretskii @ 2018-10-30 17:00 UTC (permalink / raw) To: Stefan Monnier; +Cc: emacs-devel > From: Stefan Monnier <monnier@IRO.UMontreal.CA> > Cc: emacs-devel@gnu.org > Date: Tue, 30 Oct 2018 11:00:47 -0400 > > >> (dolist (x LIST) (pcase-let ((PATTERN x)) BODY)) > > You aren't saying that showing the code removes the need for any > > documentation of what it does, do you? ;-) > > I think I am, yes. Seriously? This cannot fly: for starters, the user could be using an Emacs where *.el files are not accessible. More generally, it sounds like a defeat to say that we are unable to describe the behavior, and ask users to read the code instead. > In cases like these where the definition is really just a trivial > combination of two less trivial elements, it might be a better > option for the docstring, since it is both more concise and more > precise than whatever wording we can come up with to try and repeat > what dolist and pcase-let do. Tell you what: how about if you try explaining this, and I will then make a better doc string out of that? Deal? ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-30 17:00 ` Eli Zaretskii @ 2018-10-30 17:27 ` Stefan Monnier 2018-10-30 17:36 ` Eli Zaretskii 0 siblings, 1 reply; 375+ messages in thread From: Stefan Monnier @ 2018-10-30 17:27 UTC (permalink / raw) To: emacs-devel > Seriously? This cannot fly: for starters, the user could be using an > Emacs where *.el files are not accessible. I didn't mean for the docstring to say "read the code"; I meant the patch below. > Tell you what: how about if you try explaining this, I already did. Stefan diff --git a/lisp/emacs-lisp/pcase.el b/lisp/emacs-lisp/pcase.el index 57c2d6c3cb..7781d0d424 100644 --- a/lisp/emacs-lisp/pcase.el +++ b/lisp/emacs-lisp/pcase.el @@ -302,7 +302,10 @@ pcase-let ;;;###autoload (defmacro pcase-dolist (spec &rest body) - "Like `dolist' but where the binding can be a `pcase' pattern. + "Superset of `dolist' where the VAR binding can be a `pcase' PATTERN. +More specifically, this is just a shorthand for + + (dolist (x LIST) (pcase-let ((PATTERN x)) BODY...)) \n(fn (PATTERN LIST) BODY...)" (declare (indent 1) (debug ((pcase-PAT form) body))) (if (pcase--trivial-upat-p (car spec)) ^ permalink raw reply related [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-30 17:27 ` Stefan Monnier @ 2018-10-30 17:36 ` Eli Zaretskii 2018-10-30 18:09 ` Stefan Monnier 2018-10-30 18:24 ` Alan Mackenzie 0 siblings, 2 replies; 375+ messages in thread From: Eli Zaretskii @ 2018-10-30 17:36 UTC (permalink / raw) To: Stefan Monnier; +Cc: emacs-devel > From: Stefan Monnier <monnier@iro.umontreal.ca> > Date: Tue, 30 Oct 2018 13:27:43 -0400 > > > Seriously? This cannot fly: for starters, the user could be using an > > Emacs where *.el files are not accessible. > > I didn't mean for the docstring to say "read the code"; I meant the > patch below. > > > Tell you what: how about if you try explaining this, > > I already did. And I already read that, and hoped for some more details. Should I give up? ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-30 17:36 ` Eli Zaretskii @ 2018-10-30 18:09 ` Stefan Monnier 2018-10-30 18:42 ` Eli Zaretskii 2018-10-30 18:24 ` Alan Mackenzie 1 sibling, 1 reply; 375+ messages in thread From: Stefan Monnier @ 2018-10-30 18:09 UTC (permalink / raw) To: Eli Zaretskii; +Cc: emacs-devel > And I already read that, and hoped for some more details. Should I > give up? As I said, I'm not interested in a docstring that repeats what dolist does; I want it to explain the difference between dolist and pcase-dolist (because that's how pcase-dolist is defined both in terms of design and in terms of implementation). Stefan ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-30 18:09 ` Stefan Monnier @ 2018-10-30 18:42 ` Eli Zaretskii 2018-10-30 18:58 ` Stefan Monnier 0 siblings, 1 reply; 375+ messages in thread From: Eli Zaretskii @ 2018-10-30 18:42 UTC (permalink / raw) To: Stefan Monnier; +Cc: emacs-devel > From: Stefan Monnier <monnier@IRO.UMontreal.CA> > Cc: emacs-devel@gnu.org > Date: Tue, 30 Oct 2018 14:09:18 -0400 > > > And I already read that, and hoped for some more details. Should I > > give up? > > As I said, I'm not interested in a docstring that repeats what > dolist does; I want it to explain the difference between dolist and > pcase-dolist (because that's how pcase-dolist is defined both in terms > of design and in terms of implementation). I didn't say we should repeat what dolist does, so our interests don't necessarily conflict yet. I tried to explain earlier what I thought was missing, here it is again: > matching doesn't assign any values to anything directly related to > BODY, so the mechanism by which it affects execution of BODY needs > to be described. Could you please fill that void? This isn't a repetition of what dolist does. TIA ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-30 18:42 ` Eli Zaretskii @ 2018-10-30 18:58 ` Stefan Monnier 2018-10-31 12:08 ` Alan Mackenzie 2018-11-03 13:13 ` Eli Zaretskii 0 siblings, 2 replies; 375+ messages in thread From: Stefan Monnier @ 2018-10-30 18:58 UTC (permalink / raw) To: Eli Zaretskii; +Cc: emacs-devel >> matching doesn't assign any values to anything directly related to >> BODY, so the mechanism by which it affects execution of BODY needs >> to be described. > > Could you please fill that void? This isn't a repetition of what > dolist does. I don't know how to say it any better than with the patch I just installed into emacs-26. Stefan ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-30 18:58 ` Stefan Monnier @ 2018-10-31 12:08 ` Alan Mackenzie 2018-10-31 12:33 ` Stefan Monnier 2018-11-03 13:13 ` Eli Zaretskii 1 sibling, 1 reply; 375+ messages in thread From: Alan Mackenzie @ 2018-10-31 12:08 UTC (permalink / raw) To: Stefan Monnier; +Cc: Eli Zaretskii, emacs-devel Hello, Stefan. On Tue, Oct 30, 2018 at 14:58:58 -0400, Stefan Monnier wrote: > >> matching doesn't assign any values to anything directly related to > >> BODY, so the mechanism by which it affects execution of BODY needs > >> to be described. > > Could you please fill that void? This isn't a repetition of what > > dolist does. > I don't know how to say it any better than with the patch I just > installed into emacs-26. Thank you for this patch, which is excellent. However, the doc string for pcase-dolist is still not quite perfect, in that: 1. It doesn't say what the macro does. 2. It doesn't document the arguments to the macro. 3. It appears to refer to an argument which don't exist (VAR). 4. It forces somebody new to Lisp to traverse 5 nodes of the graph of doc strings (namely pcase-dolist, pcase, dolist, pcase-let, let) and synthesise these disparate doc strings to get an idea of what the macro does. This is too many nodes, and the task is too difficult. 5. It states the macro is equivalent to an expansion of other macros, which appear no easier to understand than pcase-dolist itself. Otherwise, not bad! Are you willing to put these final touches onto pcase-dolist's doc string, or would you prefer somebody else to do it? > Stefan -- Alan Mackenzie (Nuremberg, Germany). ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-31 12:08 ` Alan Mackenzie @ 2018-10-31 12:33 ` Stefan Monnier 2018-10-31 15:47 ` Eli Zaretskii 0 siblings, 1 reply; 375+ messages in thread From: Stefan Monnier @ 2018-10-31 12:33 UTC (permalink / raw) To: emacs-devel > Are you willing to put these final touches onto pcase-dolist's doc > string, or would you prefer somebody else to do it? This is excrutiating for me. Anyone else but me, please, Stefan ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-31 12:33 ` Stefan Monnier @ 2018-10-31 15:47 ` Eli Zaretskii 2018-10-31 16:07 ` Alan Mackenzie 2018-11-03 13:16 ` Eli Zaretskii 0 siblings, 2 replies; 375+ messages in thread From: Eli Zaretskii @ 2018-10-31 15:47 UTC (permalink / raw) To: Stefan Monnier; +Cc: emacs-devel > From: Stefan Monnier <monnier@iro.umontreal.ca> > Date: Wed, 31 Oct 2018 08:33:42 -0400 > > > Are you willing to put these final touches onto pcase-dolist's doc > > string, or would you prefer somebody else to do it? > > This is excrutiating for me. Anyone else but me, please, I will try, if no one beats me to it. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-31 15:47 ` Eli Zaretskii @ 2018-10-31 16:07 ` Alan Mackenzie 2018-10-31 16:20 ` Eli Zaretskii 2018-11-03 13:16 ` Eli Zaretskii 1 sibling, 1 reply; 375+ messages in thread From: Alan Mackenzie @ 2018-10-31 16:07 UTC (permalink / raw) To: Eli Zaretskii; +Cc: Stefan Monnier, emacs-devel Hello, Eli. On Wed, Oct 31, 2018 at 17:47:26 +0200, Eli Zaretskii wrote: > > From: Stefan Monnier <monnier@iro.umontreal.ca> > > Date: Wed, 31 Oct 2018 08:33:42 -0400 > > > Are you willing to put these final touches onto pcase-dolist's doc > > > string, or would you prefer somebody else to do it? > > This is excrutiating for me. Anyone else but me, please, > I will try, if no one beats me to it. A beating attempt, first draught: (pcase-dolist (PATTERN LIST) BODY...) Loop over a list. Evaluate BODY with bindings made by matching PATTERN to each element of LIST in turn. PATTERN is a pcase pattern, the matching being done as described in `pcase'. The return value is not significant. Should the matching fail for any LIST element, the results are undefined. See also `dolist' -- Alan Mackenzie (Nuremberg, Germany). ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-31 16:07 ` Alan Mackenzie @ 2018-10-31 16:20 ` Eli Zaretskii 2018-11-01 8:36 ` Achim Gratz 0 siblings, 1 reply; 375+ messages in thread From: Eli Zaretskii @ 2018-10-31 16:20 UTC (permalink / raw) To: Alan Mackenzie; +Cc: monnier, emacs-devel > Date: Wed, 31 Oct 2018 16:07:29 +0000 > Cc: Stefan Monnier <monnier@iro.umontreal.ca>, emacs-devel@gnu.org > From: Alan Mackenzie <acm@muc.de> > > > I will try, if no one beats me to it. > > A beating attempt, first draught: > > (pcase-dolist (PATTERN LIST) BODY...) > > Loop over a list. > > Evaluate BODY with bindings made by matching PATTERN to each > element of LIST in turn. PATTERN is a pcase pattern, the > matching being done as described in `pcase'. The return value is > not significant. > > Should the matching fail for any LIST element, the results are > undefined. > > See also `dolist' Thanks. I think we can do better in this part: Evaluate BODY with bindings made by matching PATTERN to each element of LIST in turn. PATTERN is a pcase pattern I think using "matching" here is detrimental to understanding what's going on, which is a destructuring binding that uses pcase patterns. (The "matching" here is between the structures of PATTERN and elements of LIST, but the usual meaning of "matching" in Emacs is different, especially when "patterns" are mentioned nearby. So we should not use "matching" here, at least not without significant qualifiers, like "structure matching" or somesuch.) And this: Should the matching fail for any LIST element, the results are undefined. should be reworded to explain that elements of LIST should have a structure compatible with PATTERN, so that the destructuring works. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-31 16:20 ` Eli Zaretskii @ 2018-11-01 8:36 ` Achim Gratz 2018-11-01 10:36 ` Alan Mackenzie 0 siblings, 1 reply; 375+ messages in thread From: Achim Gratz @ 2018-11-01 8:36 UTC (permalink / raw) To: emacs-devel Am 31.10.2018 um 17:20 schrieb Eli Zaretskii: > I think we can do better in this part: > > Evaluate BODY with bindings made by matching PATTERN to each > element of LIST in turn. PATTERN is a pcase pattern > > I think using "matching" here is detrimental to understanding what's > going on, which is a destructuring binding that uses pcase patterns. > (The "matching" here is between the structures of PATTERN and elements > of LIST, but the usual meaning of "matching" in Emacs is different, > especially when "patterns" are mentioned nearby. So we should not use > "matching" here, at least not without significant qualifiers, like > "structure matching" or somesuch.) > > And this: > > Should the matching fail for any LIST element, the results are > undefined. > > should be reworded to explain that elements of LIST should have a > structure compatible with PATTERN, so that the destructuring works. How about this: PATTERN describes the expected structure of LIST and is used to establish bindings to corresponding elements of LIST during evaluation of BODY. Undefined behaviour results if the structure of LIST is different from that described by PATTERN. -- Achim. (on the road :-) ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-11-01 8:36 ` Achim Gratz @ 2018-11-01 10:36 ` Alan Mackenzie 2018-11-01 12:29 ` Achim Gratz 2018-11-01 14:19 ` Michael Heerdegen 0 siblings, 2 replies; 375+ messages in thread From: Alan Mackenzie @ 2018-11-01 10:36 UTC (permalink / raw) To: Achim Gratz; +Cc: emacs-devel Hello, Achim. On Thu, Nov 01, 2018 at 09:36:54 +0100, Achim Gratz wrote: > Am 31.10.2018 um 17:20 schrieb Eli Zaretskii: > > I think we can do better in this part: > > Evaluate BODY with bindings made by matching PATTERN to each > > element of LIST in turn. PATTERN is a pcase pattern > > I think using "matching" here is detrimental to understanding what's > > going on, which is a destructuring binding that uses pcase patterns. > > (The "matching" here is between the structures of PATTERN and elements > > of LIST, but the usual meaning of "matching" in Emacs is different, > > especially when "patterns" are mentioned nearby. So we should not use > > "matching" here, at least not without significant qualifiers, like > > "structure matching" or somesuch.) > > And this: > > Should the matching fail for any LIST element, the results are > > undefined. > > should be reworded to explain that elements of LIST should have a > > structure compatible with PATTERN, so that the destructuring works. > How about this: > PATTERN describes the expected structure of LIST and is used to > establish bindings to corresponding elements of LIST during evaluation > of BODY. Undefined behaviour results if the structure of LIST is > different from that described by PATTERN. That doesn't say clearly that BODY is executed once for each LIST element. I would also go for "... the expected structure of each LIST element ..." and "... bindings of the corresponding parts of the element during ....". And one or two other changes. That would give something like this: (pcase-dolist (PATTERN LIST) BODY...) Loop over a list, evaluating BODY for each element of LIST in turn. PATTERN describes the expected structure of each LIST element and is used to establish bindings to the corresponding parts of the element during the evaluation of BODY. Undefined behavior results if the structure of any LIST element is different from PATTERN. For a description of PATTERNs, see `pcase'. See also `dolist'. What do you think? > -- > Achim. -- Alan Mackenzie (Nuremberg, Germany). ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-11-01 10:36 ` Alan Mackenzie @ 2018-11-01 12:29 ` Achim Gratz 2018-11-01 14:19 ` Michael Heerdegen 1 sibling, 0 replies; 375+ messages in thread From: Achim Gratz @ 2018-11-01 12:29 UTC (permalink / raw) To: emacs-devel Am 01.11.2018 um 11:36 schrieb Alan Mackenzie: > I would also go for "... the expected structure of each LIST element ..." > and "... bindings of the corresponding parts of the element during ....". > And one or two other changes. That would give something like this: > > (pcase-dolist (PATTERN LIST) BODY...) > > Loop over a list, evaluating BODY for each element of LIST in turn. > > PATTERN describes the expected structure of each LIST element and is > used to establish bindings to the corresponding parts of the element > during the evaluation of BODY. Undefined behavior results if the > structure of any LIST element is different from PATTERN. > > For a description of PATTERNs, see `pcase'. See also `dolist'. > > What do you think? I'd lose the plural "s" on "PATTERN" in the last sentence, but other than that I think it strikes the right balance between brevity and explaining the obvious. -- Achim. (on the road :-) ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-11-01 10:36 ` Alan Mackenzie 2018-11-01 12:29 ` Achim Gratz @ 2018-11-01 14:19 ` Michael Heerdegen 1 sibling, 0 replies; 375+ messages in thread From: Michael Heerdegen @ 2018-11-01 14:19 UTC (permalink / raw) To: Alan Mackenzie; +Cc: Achim Gratz, emacs-devel Alan Mackenzie <acm@muc.de> writes: > PATTERN describes the expected structure of each LIST element and is > used to establish bindings to the corresponding parts of the element > during the evaluation of BODY. Undefined behavior results if the > structure of any LIST element is different from PATTERN. Maybe leave out "expected"? Since the PATTERN must match, it should just match the structure, point. The programmer should be sure about that. Michael. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-31 15:47 ` Eli Zaretskii 2018-10-31 16:07 ` Alan Mackenzie @ 2018-11-03 13:16 ` Eli Zaretskii 2018-11-03 15:45 ` Michael Heerdegen 1 sibling, 1 reply; 375+ messages in thread From: Eli Zaretskii @ 2018-11-03 13:16 UTC (permalink / raw) To: monnier; +Cc: emacs-devel > Date: Wed, 31 Oct 2018 17:47:26 +0200 > From: Eli Zaretskii <eliz@gnu.org> > Cc: emacs-devel@gnu.org > > > From: Stefan Monnier <monnier@iro.umontreal.ca> > > Date: Wed, 31 Oct 2018 08:33:42 -0400 > > > > > Are you willing to put these final touches onto pcase-dolist's doc > > > string, or would you prefer somebody else to do it? > > > > This is excrutiating for me. Anyone else but me, please, > > I will try, if no one beats me to it. Done, I hope. I would like to take this opportunity to thank everybody who participated in this discussion. I tried to use all the good ideas mentioned here. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-11-03 13:16 ` Eli Zaretskii @ 2018-11-03 15:45 ` Michael Heerdegen 2018-11-03 16:25 ` Eli Zaretskii 0 siblings, 1 reply; 375+ messages in thread From: Michael Heerdegen @ 2018-11-03 15:45 UTC (permalink / raw) To: Eli Zaretskii; +Cc: monnier, emacs-devel Eli Zaretskii <eliz@gnu.org> writes: > Done, I hope. Great, thanks Eli. Some comments/thoughts: control.texi line 521 "is equals": typo. | The pcase patterns that are useful for destructuring bindings are | generally those described in @ref{Backquote Patterns}, since they | express a specification of the structure of objects that will match. I don't like that sentence for two reasons: (1) ` is the pcase pattern for destructuring. The "Backquote Patterns" or "Backquote style Patterns" are not really "pcase patterns" since they are part of the implicit semantics ``' defines. They are _not_ pcase patterns. Your sentence confuses the both. (2) We already have a lot other patterns for destructuring (eieio, seq, map, cl-struct), and we probably will get even more in the future. | @defmac pcase-let bindings body@dots{} | Perform desctructuring binding of variables according to | @var{bindings}, and then evaluate @var{body}. and lots of similar: `pcase-let', `pcase-dolist' and the like are very often used only for destructuring, but they are not limited to destructuring. Like in (defun test (arg) (pcase-let (((or (and (pred stringp) s) (and (pred numberp) (app number-to-string s))) arg)) s)) (test "Hallo") => "Hallo" (test 1) => "1" Also the docstrings give the impression that these are limited to destructuring, which is not true. Michael. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-11-03 15:45 ` Michael Heerdegen @ 2018-11-03 16:25 ` Eli Zaretskii 2018-11-03 17:12 ` Michael Heerdegen 0 siblings, 1 reply; 375+ messages in thread From: Eli Zaretskii @ 2018-11-03 16:25 UTC (permalink / raw) To: Michael Heerdegen; +Cc: monnier, emacs-devel > From: Michael Heerdegen <michael_heerdegen@web.de> > Cc: monnier@iro.umontreal.ca, emacs-devel@gnu.org > Date: Sat, 03 Nov 2018 16:45:08 +0100 > > control.texi line 521 "is equals": typo. Thanks, fixed. > | The pcase patterns that are useful for destructuring bindings are > | generally those described in @ref{Backquote Patterns}, since they > | express a specification of the structure of objects that will match. > > I don't like that sentence for two reasons: > > (1) ` is the pcase pattern for destructuring. The "Backquote Patterns" > or "Backquote style Patterns" are not really "pcase patterns" since they > are part of the implicit semantics ``' defines. They are _not_ pcase > patterns. Your sentence confuses the both. Sorry, you lost me here. How can these not be pcase patterns, when they are used with 'pcase', and "pcase patterns" are _defined_ as those used with 'pcase'? > (2) We already have a lot other patterns for destructuring (eieio, seq, > map, cl-struct), and we probably will get even more in the future. OK, but why is that a reason not to use what I wrote? Note that it talks about "destructuring binding", not just about destructuring. Also please note that I made some changes in the description of seq-let to say that is an alternative facility for destructuring binding. The text you quoted doesn't say that those pcase patterns are the _only_ method of destructuring. If that is the root cause of your disliking, we could make this even more clear. > | @defmac pcase-let bindings body@dots{} > | Perform desctructuring binding of variables according to > | @var{bindings}, and then evaluate @var{body}. > > and lots of similar: > > `pcase-let', `pcase-dolist' and the like are very often used only for > destructuring, but they are not limited to destructuring. Like in > > (defun test (arg) > (pcase-let (((or (and (pred stringp) s) > (and (pred numberp) (app number-to-string s))) > arg)) > s)) > > (test "Hallo") => "Hallo" > (test 1) => "1" OK, but why would I need pcase-let in this example? Isn't the above the same as (defun test (arg) (let ((s (cond ((stringp arg) arg) ((numberp arg) (number-to-string arg))))) s)) (which is both simpler and shorter)? > Also the docstrings give the impression that these are limited to > destructuring, which is not true. Can you tell where did you get that impression? The doc strings talk about destructuring bindings, when BINDINGS have the form specified, and I believe that is true. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-11-03 16:25 ` Eli Zaretskii @ 2018-11-03 17:12 ` Michael Heerdegen 2018-11-03 17:55 ` Eli Zaretskii 0 siblings, 1 reply; 375+ messages in thread From: Michael Heerdegen @ 2018-11-03 17:12 UTC (permalink / raw) To: Eli Zaretskii; +Cc: monnier, emacs-devel Eli Zaretskii <eliz@gnu.org> writes: > > | The pcase patterns that are useful for destructuring bindings are > > | generally those described in @ref{Backquote Patterns}, since they > > | express a specification of the structure of objects that will match. > > > > I don't like that sentence for two reasons: > > > > (1) ` is the pcase pattern for destructuring. The "Backquote Patterns" > > or "Backquote style Patterns" are not really "pcase patterns" since > > they > > are part of the implicit semantics ``' defines. They are _not_ pcase > > patterns. Your sentence confuses the both. > > Sorry, you lost me here. How can these not be pcase patterns, when > they are used with 'pcase', and "pcase patterns" are _defined_ as > those used with 'pcase'? We called these UPATS in the past btw. Not every part of a pattern is also a pattern. ,a is not an expression since it's only valid as sexp inside a backquote expression. For a similar reason, ,a is not a pcase pattern because it's only valid in a ` pattern. (< 1) is also not a pcase pattern, although it's valid inside a pred: (pred (< 1)). A pcase pattern should only be called what is valid as PATTERN in a pcase clause (PATTERN BODY). > > (2) We already have a lot other patterns for destructuring (eieio, seq, > > map, cl-struct), and we probably will get even more in the future. > > OK, but why is that a reason not to use what I wrote? Note that it > talks about "destructuring binding", not just about destructuring. Well, for binding there is only one pattern, SYMBOL. But you also write | since they express a specification of the structure of objects that | will match. so this seems to speak about destructuring and not about binding. > Also please note that I made some changes in the description of > seq-let to say that is an alternative facility for destructuring > binding. > > The text you quoted doesn't say that those pcase patterns are the > _only_ method of destructuring. If that is the root cause of your > disliking, we could make this even more clear. I didn't speak about other methods in Emacs, I spoke about other pcase patterns also performing destructuring. But | The pcase patterns that are useful for destructuring bindings are | generally those described in @ref{Backquote Patterns} makes it sounds if ` is the only method to get destructuring bindings with pcase. > > | @defmac pcase-let bindings body@dots{} > > | Perform desctructuring binding of variables according to > > | @var{bindings}, and then evaluate @var{body}. > > > > and lots of similar: > > > > `pcase-let', `pcase-dolist' and the like are very often used only for > > destructuring, but they are not limited to destructuring. Like in > > > > (defun test (arg) > > (pcase-let (((or (and (pred stringp) s) > > (and (pred numberp) (app number-to-string s))) > > arg)) > > s)) > > > > (test "Hallo") => "Hallo" > > (test 1) => "1" > > OK, but why would I need pcase-let in this example? Isn't the above > the same as > > (defun test (arg) > (let ((s (cond ((stringp arg) arg) > ((numberp arg) (number-to-string arg))))) > s)) > > (which is both simpler and shorter)? It was just an example. And docstrings shouldn't tell restrictions that don't exist just because you would prefer `cond' in such cases anyway. > > Also the docstrings give the impression that these are limited to > > destructuring, which is not true. > > Can you tell where did you get that impression? The doc strings talk > about destructuring bindings, when BINDINGS have the form specified, > and I believe that is true. You say | Perform desctructuring binding of variables according to | @var{bindings}, and then evaluate @var{body}. Any pcase PATTERN can be used in BINDINGS, whether it performs destructuring or not, the only assumption is that it should match. You can say that pcase-let is mostly useful for destructuring the bound values, but as a summary of what `pcase-let' and the like is about it's misleading. It's misleading because I then wonder where the restriction to destructuring comes from, and what's different to just matching the patterns against the values as in `pcase'. Michael. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-11-03 17:12 ` Michael Heerdegen @ 2018-11-03 17:55 ` Eli Zaretskii 2018-11-03 22:22 ` Michael Heerdegen 0 siblings, 1 reply; 375+ messages in thread From: Eli Zaretskii @ 2018-11-03 17:55 UTC (permalink / raw) To: Michael Heerdegen; +Cc: monnier, emacs-devel > From: Michael Heerdegen <michael_heerdegen@web.de> > Cc: monnier@iro.umontreal.ca, emacs-devel@gnu.org > Date: Sat, 03 Nov 2018 18:12:43 +0100 > > > Sorry, you lost me here. How can these not be pcase patterns, when > > they are used with 'pcase', and "pcase patterns" are _defined_ as > > those used with 'pcase'? > > We called these UPATS in the past btw. > > Not every part of a pattern is also a pattern. > > ,a is not an expression since it's only valid as sexp inside a backquote > expression. For a similar reason, ,a is not a pcase pattern because > it's only valid in a ` pattern. > > (< 1) is also not a pcase pattern, although it's valid inside a pred: > (pred (< 1)). > > A pcase pattern should only be called what is valid as PATTERN in a > pcase clause (PATTERN BODY). Sorry, I'm still in the dark here. The node I pointed to describes "backquote-style patterns", and explains that these "ease structural matching". The same patterns are useful for destructuring binding, precisely because destructuring binding needs a structural match. That is all that I'm trying to convey. Making that point will help the reader to understand what subset of pcase patterns will be most useful for destructuring. > > > (2) We already have a lot other patterns for destructuring (eieio, seq, > > > map, cl-struct), and we probably will get even more in the future. > > > > OK, but why is that a reason not to use what I wrote? Note that it > > talks about "destructuring binding", not just about destructuring. > > Well, for binding there is only one pattern, SYMBOL. But you also write > > | since they express a specification of the structure of objects that > | will match. > > so this seems to speak about destructuring and not about binding. Destructuring binding requires destructuring, that's all. Again, I don't understand the nature of your objections to the text. > | The pcase patterns that are useful for destructuring bindings are > | generally those described in @ref{Backquote Patterns} > > makes it sounds if ` is the only method to get destructuring bindings > with pcase. No, it says those are _useful_ for destructuring bindings, that's all. I'm sure you realize that saying A doesn't say that there's nothing but A. > > (defun test (arg) > > (let ((s (cond ((stringp arg) arg) > > ((numberp arg) (number-to-string arg))))) > > s)) > > > > (which is both simpler and shorter)? > > It was just an example. I submit that any other example, except the ones that follow my description, will have the same property: they can be rewritten cleaner, and in many cases also shorter, than using pcase-let etc. > And docstrings shouldn't tell restrictions that don't exist just > because you would prefer `cond' in such cases anyway. So you seem to object to the doc string describing only part of the possible uses? If so, this argument was already voiced in the discussion, and I already said that I think it's a mistake to make our documentation more vague and therefore more confusing, for the benefit of being 100% accurate. IOW, it is quite clear that, knowing the way a macro is implemented, one can tweak the macro into doing stuff it never was designed to do. But we introduced pcase-let for a reason, and AFAIU that reason is to allow destructuring binding. It can also do other things, but nothing important will be lost by making the documentation general enough, and thus vague/abstract enough, to cover those other use cases. > > > Also the docstrings give the impression that these are limited to > > > destructuring, which is not true. > > > > Can you tell where did you get that impression? The doc strings talk > > about destructuring bindings, when BINDINGS have the form specified, > > and I believe that is true. > > You say > > | Perform desctructuring binding of variables according to > | @var{bindings}, and then evaluate @var{body}. > > Any pcase PATTERN can be used in BINDINGS, whether it performs > destructuring or not, the only assumption is that it should match. But these macros were invented to support destructuring, don't you agree? Stefan's original text talked about extracting values (or subfields), so it was clear to me that Stefan, too, alluded to destructuring. I think we should describe the intended usage of these macros first and foremost. If the other uses can be described without losing clarity, fine; but that's not the case here, as the long discussions seem to show -- people were unhappy with the original abstract and general descriptions because they didn't tell them enough about the main use case. In any case, feel free to suggest modifications of the doc strings that are more general without losing clarity, and let's take this from there. > You can say that pcase-let is mostly useful for destructuring the > bound values, but as a summary of what `pcase-let' and the like is > about it's misleading. It's misleading because I then wonder where > the restriction to destructuring comes from, and what's different to > just matching the patterns against the values as in `pcase'. I disagree that it's misleading. If you care so much about the restrictions, or lack thereof, you are welcome to study the code. But the doc string should explain how to use the macro to the rest of us. We write our documentation to be useful in the main use cases, not to be 110% accurate. Favoring the latter at the price of obfuscating the former is IME a serious mistake that produces inferior programming docs. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-11-03 17:55 ` Eli Zaretskii @ 2018-11-03 22:22 ` Michael Heerdegen 2018-11-04 14:16 ` Eli Zaretskii 0 siblings, 1 reply; 375+ messages in thread From: Michael Heerdegen @ 2018-11-03 22:22 UTC (permalink / raw) To: Eli Zaretskii; +Cc: monnier, emacs-devel Eli Zaretskii <eliz@gnu.org> writes: > > We called these UPATS in the past btw. That should have been QPATs, sorry. > Sorry, I'm still in the dark here. The node I pointed to describes > "backquote-style patterns", and explains that these "ease structural > matching". The same patterns are useful for destructuring binding, > precisely because destructuring binding needs a structural match. > That is all that I'm trying to convey. Making that point will help > the reader to understand what subset of pcase patterns will be most > useful for destructuring. So, I should read it as "the set of patterns that are of the form `SOMETHING"? I had read it as the set of what we call "QPATs". So we have probably talked about different things. I find the wording used in (info "(elisp) Backquote Patterns") confusing, especially the first sentence "This subsection describes “backquote-style patterns”, a set of builtin patterns that eases structural matching." which seems to introduce a whole set of builtin patterns though it talks only about one macro, `. You only refer to that in your change, using the same wording, so what you changed is consistent with what we have, although I don't like it that much. > > > > (2) We already have a lot other patterns for destructuring > > > > (eieio, seq, map, cl-struct), and we probably will get even more > > > > in the future. > > > > > > OK, but why is that a reason not to use what I wrote? Note that it > > > talks about "destructuring binding", not just about destructuring. > > > > Well, for binding there is only one pattern, SYMBOL. But you also > > write > > > > | since they express a specification of the structure of objects that > > | will match. > > > > so this seems to speak about destructuring and not about binding. > > Destructuring binding requires destructuring, that's all. "Destructuring binding" - pcase has nothing like that. We have a pattern type for binding, SYMBOL, and diverse for performing destructuring, ``' being the main and most general one. You can combine these, but both are different things. We talk about this paragraph: | +The pcase patterns that are useful for destructuring bindings are | +generally those described in @ref{Backquote Patterns}, since they | +express a specification of the structure of objects that will match. I would already be happy if you would leave out the word "bindings". Establishing bindings is not the only use of `. > Again, I don't understand the nature of your objections to the text. > > > | The pcase patterns that are useful for destructuring bindings are > > | generally those described in @ref{Backquote Patterns} > > > > makes it sounds if ` is the only method to get destructuring bindings > > with pcase. > > No, it says those are _useful_ for destructuring bindings, that's all. > I'm sure you realize that saying A doesn't say that there's nothing > but A. Sorry, I'm not an native English speaker. But "are generally those" sounds quite, well, generalizing to me ;-) > I submit that any other example, except the ones that follow my > description, will have the same property: they can be rewritten > cleaner, and in many cases also shorter, than using pcase-let etc. But that's personal preference. I found at least one example of such a `pcase-let' that doesn't use destructuring in the Emacs sources. It isn't wrong just because you would personally write it in a different way, and it should be understandable after reading the docs. All occurrences should be understandable after reading the docs, not only those that are main use cases or cases that the inventor had in mind when the thing was created. > > And docstrings shouldn't tell restrictions that don't exist just > > because you would prefer `cond' in such cases anyway. > > So you seem to object to the doc string describing only part of the > possible uses? If so, this argument was already voiced in the > discussion, and I already said that I think it's a mistake to make our > documentation more vague and therefore more confusing, for the benefit > of being 100% accurate. I don't suggest to make it vague. In my option, what you did in your change makes it more vague, actually. What we write in the docs should be correct, at least. > IOW, it is quite clear that, knowing the way a macro is implemented, > one can tweak the macro into doing stuff it never was designed to do. These are still valid use cases. > But we introduced pcase-let for a reason, and AFAIU that reason is to > allow destructuring binding. It can also do other things, but nothing > important will be lost by making the documentation general enough, and > thus vague/abstract enough, to cover those other use cases. I don't understand what this means in concrete. > > > > Also the docstrings give the impression that these are limited to > > > > destructuring, which is not true. > > > > > > Can you tell where did you get that impression? The doc strings talk > > > about destructuring bindings, when BINDINGS have the form specified, > > > and I believe that is true. > > > > You say > > > > | Perform desctructuring binding of variables according to > > | @var{bindings}, and then evaluate @var{body}. > > > > Any pcase PATTERN can be used in BINDINGS, whether it performs > > destructuring or not, the only assumption is that it should match. > > But these macros were invented to support destructuring, don't you > agree? To 100%. > Stefan's original text talked about extracting values (or subfields), > so it was clear to me that Stefan, too, alluded to destructuring. It talked about "extracting data". It didn't restrict to what data and from where. Destructuring comes to my mind when I read that, but "extracting data" doesn't explicitly limit it to that case. I wouldn't have chosen that wording, however. It was not the original docstring, btw, but one Stefan had rewritten after he had been urged to by people (like you) who were not happy with the original docstring. The original docstring was clearer in that regard, indeed. > I think we should describe the intended usage of these macros first > and foremost. If the other uses can be described without losing > clarity, fine; but that's not the case here, as the long discussions > seem to show -- people were unhappy with the original abstract and > general descriptions because they didn't tell them enough about the > main use case. I'm not against telling the main use cases. But a thing isn't described completely or even in a good way only by telling the main use cases. > > You can say that pcase-let is mostly useful for destructuring the > > bound values, but as a summary of what `pcase-let' and the like is > > about it's misleading. It's misleading because I then wonder where > > the restriction to destructuring comes from, and what's different to > > just matching the patterns against the values as in `pcase'. > > I disagree that it's misleading. If you care so much about the > restrictions, or lack thereof, you are welcome to study the code. But > the doc string should explain how to use the macro to the rest of us. Say the "rest of us" is 50% of the people. The other 50% don't matter? The docs get more confusing for them. What would you say if I would change the docstring of `cond' to say it's limited to the cases where I would use it, just because I, and lots of other people ("the rest of us") would prefer something more suited in our eyes in these cases, like pcase? Also, not only people write pcase/pcase-let expressions, but also code can do that. The documentation should make clear what is allowed and what not also for that case. After saying that you can write how the main use cases look like. FWIW, I always thought that the docstrings tell how something works and what it does, and the manual is for learning and telling use cases. It's also a difference between "... is typically used for" (which I would find ok) and "... does this and that" and it's not accurate. Michael. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-11-03 22:22 ` Michael Heerdegen @ 2018-11-04 14:16 ` Eli Zaretskii 2018-11-06 0:00 ` Michael Heerdegen 0 siblings, 1 reply; 375+ messages in thread From: Eli Zaretskii @ 2018-11-04 14:16 UTC (permalink / raw) To: Michael Heerdegen; +Cc: monnier, emacs-devel > From: Michael Heerdegen <michael_heerdegen@web.de> > Cc: monnier@iro.umontreal.ca, emacs-devel@gnu.org > Date: Sat, 03 Nov 2018 23:22:02 +0100 > > > The node I pointed to describes > > "backquote-style patterns", and explains that these "ease structural > > matching". The same patterns are useful for destructuring binding, > > precisely because destructuring binding needs a structural match. > > That is all that I'm trying to convey. Making that point will help > > the reader to understand what subset of pcase patterns will be most > > useful for destructuring. > > So, I should read it as "the set of patterns that are of the form > `SOMETHING"? I had read it as the set of what we call "QPATs". So we > have probably talked about different things. I refer to the patterns described in that section. They are all `SOMETHING, but not just any SOMETHING. Does that answer your question? (Please don't talk about QPATs, that term no longer exists in the manual, so using it is just making this discussion more confusing than it already is.) > I find the wording used in (info "(elisp) Backquote Patterns") > confusing, especially the first sentence "This subsection describes > “backquote-style patterns”, a set of builtin patterns that eases > structural matching." which seems to introduce a whole set of builtin > patterns though it talks only about one macro, `. > > You only refer to that in your change, using the same wording, so what > you changed is consistent with what we have, although I don't like it > that much. The current description of pcase uses took a lot of time and effort to get to the current shape, so I'm going to trust those who labored on it that they found the best balance between clarity and accuracy. In any case, that's a separate issue, let's please not mix them. I didn't change anything in that section, only referred to it. > > Destructuring binding requires destructuring, that's all. > > "Destructuring binding" - pcase has nothing like that. The section in question is not about pcase, it's about pcase-let, pcase-let*, and pcase-dolist. > We have a > pattern type for binding, SYMBOL, and diverse for performing > destructuring, ``' being the main and most general one. You can combine > these, but both are different things. The macros described in the section we are talking about provide a kind of binding. I needed to describe how to use the combination of the above, so I called that "destructuring binding", both to follow terminology accepted in other languages and to provide a concise description of this combination that doesn't require too many words. Since you seem to agree that there is destructuring and there is binding, I don't understand the nature of your objections to the term "destructuring binding", as defined in this section. Are you saying that this description: [...] similar to a local binding (@pxref{Local Variables}), but gives values to multiple elements of a variable by extracting those values from an object of compatible structure. is incorrect, or that pcase patterns don't allow them, or that pcase-let etc. is not about using such bindings in the BODY? > We talk about this paragraph: > > | +The pcase patterns that are useful for destructuring bindings are > | +generally those described in @ref{Backquote Patterns}, since they > | +express a specification of the structure of objects that will match. > > I would already be happy if you would leave out the word "bindings". > Establishing bindings is not the only use of `. The text doesn't say that the only use of ` is for establishing bindings. It says that destructuring bindings can be done by using backquote-style patterns. That's not the same, as you surely realize. If A can be done by using B, it doesn't imply that B's only use is to do A. The text you quote says the former and never says anything to imply the latter. So I'm really surprised that you interpret it that way. > > > | The pcase patterns that are useful for destructuring bindings are > > > | generally those described in @ref{Backquote Patterns} > > > > > > makes it sounds if ` is the only method to get destructuring bindings > > > with pcase. > > > > No, it says those are _useful_ for destructuring bindings, that's all. > > I'm sure you realize that saying A doesn't say that there's nothing > > but A. > > Sorry, I'm not an native English speaker. But "are generally those" > sounds quite, well, generalizing to me ;-) Would you be happier if the text said "typically" instead of "generally"? Because that's what it means. > > Stefan's original text talked about extracting values (or subfields), > > so it was clear to me that Stefan, too, alluded to destructuring. > > It talked about "extracting data". It talked about extracting subfields of objects. Isn't that destructuring? > It's also a difference between "... is typically used for" (which I > would find ok) and "... does this and that" and it's not accurate. Could you please tell what concrete changes in the doc strings of pcase-let etc. would make you happier? I feel that we are trapped in abstract discussions with no clear way out, and I think I'm at least slightly confused what is it that you don't like about the current docs. Concrete proposals for changes might go a long way towards dispersing the fog. Thanks. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-11-04 14:16 ` Eli Zaretskii @ 2018-11-06 0:00 ` Michael Heerdegen 2018-11-06 3:30 ` Eli Zaretskii 0 siblings, 1 reply; 375+ messages in thread From: Michael Heerdegen @ 2018-11-06 0:00 UTC (permalink / raw) To: Eli Zaretskii; +Cc: monnier, emacs-devel Eli Zaretskii <eliz@gnu.org> writes: > > > Destructuring binding requires destructuring, that's all. > > > > "Destructuring binding" - pcase has nothing like that. > > The section in question is not about pcase, it's about pcase-let, > pcase-let*, and pcase-dolist. I only summarized these as `pcase' since they use the same pattern matching mechanism from pcase. > Would you be happier if the text said "typically" instead of > "generally"? Because that's what it means. It's ok for me if it means that. > Could you please tell what concrete changes in the doc strings of > pcase-let etc. would make you happier? I feel that we are trapped in > abstract discussions with no clear way out, and I think I'm at least > slightly confused what is it that you don't like about the current > docs. I'm also confused. I found the old docstrings simple and clear (though they lacked some details). I find already reading the new docstrings in order to make suggestions for improvements straining. After I read your response, I see and can comprehend now that everything makes sense from your point of view. You have a totally different view and understanding than I. For example, for you `(,a ,b) and `[,a ,b] are two different patterns for destructuring binding that can be used in pcase. For me, I see SYMBOL as the trivial pattern thing to establish bindings, and the ` macro which has a simple specification that fits into very few lines, and above we have two examples of combining and using the two. I can only say that I find the new docstrings more confusing and complicated than before, and I find it a mistake to describe the behavior using concepts like "destructuring binding" that neither have a direct counterpart in the implementation nor in the specification. I agree it could help people when the manual uses such concepts to explain things and make nice chapters, but I don't like it when docstrings use such terms, terms that are not clearly defined and don't really fit to how the thing actually works, instead of giving a clear description. I understand now that the new docstrings actually give a clear description to you; for me, they are now harder to read and understand. So I don't think I can be of much help, becauseprobably my suggestions would not be acceptable for you. I wonder if there is still a way to provide the old docstrings, at least as comments in the sources? Thanks, Michael. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-11-06 0:00 ` Michael Heerdegen @ 2018-11-06 3:30 ` Eli Zaretskii 0 siblings, 0 replies; 375+ messages in thread From: Eli Zaretskii @ 2018-11-06 3:30 UTC (permalink / raw) To: Michael Heerdegen; +Cc: monnier, emacs-devel > From: Michael Heerdegen <michael_heerdegen@web.de> > Cc: monnier@iro.umontreal.ca, emacs-devel@gnu.org > Date: Tue, 06 Nov 2018 01:00:56 +0100 > > I wonder if there is still a way to provide the old docstrings, at > least as comments in the sources? If you show a patch to do that, we can discuss that. Thanks. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-30 18:58 ` Stefan Monnier 2018-10-31 12:08 ` Alan Mackenzie @ 2018-11-03 13:13 ` Eli Zaretskii 1 sibling, 0 replies; 375+ messages in thread From: Eli Zaretskii @ 2018-11-03 13:13 UTC (permalink / raw) To: Stefan Monnier; +Cc: emacs-devel > From: Stefan Monnier <monnier@IRO.UMontreal.CA> > Cc: emacs-devel@gnu.org > Date: Tue, 30 Oct 2018 14:58:58 -0400 > > >> matching doesn't assign any values to anything directly related to > >> BODY, so the mechanism by which it affects execution of BODY needs > >> to be described. > > > > Could you please fill that void? This isn't a repetition of what > > dolist does. > > I don't know how to say it any better than with the patch I just > installed into emacs-26. I made what I think are minor improvements on that text. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-30 17:36 ` Eli Zaretskii 2018-10-30 18:09 ` Stefan Monnier @ 2018-10-30 18:24 ` Alan Mackenzie 1 sibling, 0 replies; 375+ messages in thread From: Alan Mackenzie @ 2018-10-30 18:24 UTC (permalink / raw) To: Eli Zaretskii; +Cc: Stefan Monnier, emacs-devel Hello, Eli. On Tue, Oct 30, 2018 at 19:36:04 +0200, Eli Zaretskii wrote: > > From: Stefan Monnier <monnier@iro.umontreal.ca> > > Date: Tue, 30 Oct 2018 13:27:43 -0400 > > > Seriously? This cannot fly: for starters, the user could be using an > > > Emacs where *.el files are not accessible. > > I didn't mean for the docstring to say "read the code"; I meant the > > patch below. > > > Tell you what: how about if you try explaining this, > > I already did. > And I already read that, and hoped for some more details. Should I > give up? No, please don't. Two things: I explained what I think is the semantics of pcase-dolist in a post I posted ~20 minutes ago in reply to Stefan's opening of this sub thread. I can't be sure I've got all the details right, but I believe I'm not far off. If we can't get quality doc strings for pcase-dolist and friends, I say we should remove them from Emacs. There are only around 30 occurrences of pcase-dolist. -- Alan Mackenzie (Nuremberg, Germany). ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-30 12:15 ` Stefan Monnier 2018-10-30 12:38 ` Eli Zaretskii @ 2018-10-30 14:16 ` Andy Moreton 2018-10-30 15:05 ` Clément Pit-Claudel 1 sibling, 1 reply; 375+ messages in thread From: Andy Moreton @ 2018-10-30 14:16 UTC (permalink / raw) To: emacs-devel On Tue 30 Oct 2018, Stefan Monnier wrote: >> I think the doc string should be (more) independent, at least in the >> pcase-dolist case, because the semantics of executing BODY with >> PATTERN matched against a LIST element is significantly different from >> that of executing the dolist BODY with a VAR binding. > > Hmm... I really don't see what difference you're thinking of. > > Maybe a simpler way to document it is to show its definition: > > (dolist (x LIST) (pcase-let ((PATTERN x)) BODY)) So this also fails randomly if the pattern does not match, like `pcase-let', and this should be documented. How are users meant to write reliable code using such constructs ? Why are there not versions of these constructs that have deterministic behaviour on pattern match failure ? AndyM ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-30 14:16 ` Andy Moreton @ 2018-10-30 15:05 ` Clément Pit-Claudel 2018-10-30 18:14 ` Alan Mackenzie 0 siblings, 1 reply; 375+ messages in thread From: Clément Pit-Claudel @ 2018-10-30 15:05 UTC (permalink / raw) To: emacs-devel On 30/10/2018 10.16, Andy Moreton wrote: > How are users meant to write reliable code using such constructs ? Ensure that the pattern actually matches :) IOW, only use these constructs when it's an invariant of your program that the pattern will match the data. For cases in which the pattern might not match, use pcase instead of pcase-dolist. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-30 15:05 ` Clément Pit-Claudel @ 2018-10-30 18:14 ` Alan Mackenzie 2018-10-30 19:56 ` Clément Pit-Claudel 0 siblings, 1 reply; 375+ messages in thread From: Alan Mackenzie @ 2018-10-30 18:14 UTC (permalink / raw) To: Clément Pit-Claudel; +Cc: emacs-devel Hello, Clément. On Tue, Oct 30, 2018 at 11:05:55 -0400, Clément Pit-Claudel wrote: > On 30/10/2018 10.16, Andy Moreton wrote: > > How are users meant to write reliable code using such constructs ? > Ensure that the pattern actually matches :) You mean, unless you can be 100% sure that the pattern will match, you mustn't use pcase-... constructs. That sounds equivalent to saying you shouldn't use these constructs at all. > IOW, only use these constructs when it's an invariant of your program > that the pattern will match the data. For cases in which the pattern > might not match, use pcase instead of pcase-dolist. pcase is not a looping construct. pcase-dolist is. They're not replacements for eachother. -- Alan Mackenzie (Nuremberg, Germany). ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-30 18:14 ` Alan Mackenzie @ 2018-10-30 19:56 ` Clément Pit-Claudel 2018-10-31 0:08 ` Andy Moreton 0 siblings, 1 reply; 375+ messages in thread From: Clément Pit-Claudel @ 2018-10-30 19:56 UTC (permalink / raw) To: Alan Mackenzie; +Cc: emacs-devel On 30/10/2018 14.14, Alan Mackenzie wrote: > Hello, Clément. Hey Alan :) > On Tue, Oct 30, 2018 at 11:05:55 -0400, Clément Pit-Claudel wrote: >> On 30/10/2018 10.16, Andy Moreton wrote: >>> How are users meant to write reliable code using such constructs ? > >> Ensure that the pattern actually matches :) > > You mean, unless you can be 100% sure that the pattern will match, you > mustn't use pcase-... constructs. That sounds equivalent to saying you > shouldn't use these constructs at all. That's an odd conclusion. >> IOW, only use these constructs when it's an invariant of your program >> that the pattern will match the data. For cases in which the pattern >> might not match, use pcase instead of pcase-dolist. > > pcase is not a looping construct. pcase-dolist is. They're not > replacements for eachother. I should have written "use `pcase' with `dolist` instead of `pcase-dolist'". Concretely, replace this: (pcase-dolist (pat list) …) with this: (dolist (xyz list) (pcase xyz (pat …) (_ (handle-error-here)))) ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-30 19:56 ` Clément Pit-Claudel @ 2018-10-31 0:08 ` Andy Moreton 2018-10-31 3:19 ` Stefan Monnier 2018-10-31 16:23 ` Clément Pit-Claudel 0 siblings, 2 replies; 375+ messages in thread From: Andy Moreton @ 2018-10-31 0:08 UTC (permalink / raw) To: emacs-devel On Tue 30 Oct 2018, Clément Pit-Claudel wrote: > On 30/10/2018 14.14, Alan Mackenzie wrote: >> Hello, Clément. > > Hey Alan :) > >> On Tue, Oct 30, 2018 at 11:05:55 -0400, Clément Pit-Claudel wrote: >>> On 30/10/2018 10.16, Andy Moreton wrote: >>>> How are users meant to write reliable code using such constructs ? >> >>> Ensure that the pattern actually matches :) >> >> You mean, unless you can be 100% sure that the pattern will match, you >> mustn't use pcase-... constructs. That sounds equivalent to saying you >> shouldn't use these constructs at all. > > That's an odd conclusion. It is a perfectly reasonable conclusion. `pcase-exhaustive' is available as a replacement for `pcase', but a similar exhaustive matcher that signals an error on pattern match failure is missing for all of the other pcase constructs. AndyM ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-31 0:08 ` Andy Moreton @ 2018-10-31 3:19 ` Stefan Monnier 2018-10-31 16:23 ` Clément Pit-Claudel 1 sibling, 0 replies; 375+ messages in thread From: Stefan Monnier @ 2018-10-31 3:19 UTC (permalink / raw) To: emacs-devel > It is a perfectly reasonable conclusion. `pcase-exhaustive' is available > as a replacement for `pcase', but a similar exhaustive matcher that > signals an error on pattern match failure is missing for all of the > other pcase constructs. Their absence is a mere reflection of the fact that noone's found a concrete use for them yet. They'd be easy to add (just like pcase-exhaustive was easy to add once someone found a use for it). Stefan ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-31 0:08 ` Andy Moreton 2018-10-31 3:19 ` Stefan Monnier @ 2018-10-31 16:23 ` Clément Pit-Claudel 2018-11-01 14:44 ` Andy Moreton 1 sibling, 1 reply; 375+ messages in thread From: Clément Pit-Claudel @ 2018-10-31 16:23 UTC (permalink / raw) To: emacs-devel On 30/10/2018 20.08, Andy Moreton wrote: > On Tue 30 Oct 2018, Clément Pit-Claudel wrote: > >> On 30/10/2018 14.14, Alan Mackenzie wrote: >>> Hello, Clément. >> >> Hey Alan :) >> >>> On Tue, Oct 30, 2018 at 11:05:55 -0400, Clément Pit-Claudel wrote: >>>> On 30/10/2018 10.16, Andy Moreton wrote: >>>>> How are users meant to write reliable code using such constructs ? >>> >>>> Ensure that the pattern actually matches :) >>> >>> You mean, unless you can be 100% sure that the pattern will match, you >>> mustn't use pcase-... constructs. That sounds equivalent to saying you >>> shouldn't use these constructs at all. >> >> That's an odd conclusion. > > It is a perfectly reasonable conclusion. Why? A large number of ELisp functions don't say what they do if their argument isn't of the expected type, or doesn't have the expected structure. If you're not 100% sure that the argument has the right type, you shouldn't use them (instead, you should do an appropriate check first). This is not equivalent to saying that they shouldn't be used at all. I don't understand what's so special about pcase-*. Functions like lookup-key or define-key don't tell you what happens if you pass something else that a keymap; does that mean you should never use them? Same for a function like `c-common-init' in cc-mode (the doc doesn't tell you what happens if you pass a symbol that isn't a mode; AFAICT, if you do, you get an error but the current buffer is left in a broken state. This is a pattern across most ELisp functions, really: if you pass them the wrong thing, some do sanity checks and exit cleanly, some exit silently, some raise a seemingly unrelated error, etc. Most of them don't document that behavior (some, like car and cdr, do). If pcase-dolist, pcase-let, or pcase-lambda happen across a value that doesn't match the pattern, they'll typically raise an error; that behavior isn't guaranteed, so you're not supposed to rely on it. The docs point it out. We can debate whether they should be amended to have more predictable behavior in the face of match failures, but it's sounds like a real stretch to conclude that they shouldn't be used at all use them at all. Clément. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-31 16:23 ` Clément Pit-Claudel @ 2018-11-01 14:44 ` Andy Moreton 2018-11-01 15:28 ` Clément Pit-Claudel 0 siblings, 1 reply; 375+ messages in thread From: Andy Moreton @ 2018-11-01 14:44 UTC (permalink / raw) To: emacs-devel On Wed 31 Oct 2018, Clément Pit-Claudel wrote: > On 30/10/2018 20.08, Andy Moreton wrote: >> On Tue 30 Oct 2018, Clément Pit-Claudel wrote: >> >>> On 30/10/2018 14.14, Alan Mackenzie wrote: >>>> Hello, Clément. >>> >>> Hey Alan :) >>> >>>> On Tue, Oct 30, 2018 at 11:05:55 -0400, Clément Pit-Claudel wrote: >>>>> On 30/10/2018 10.16, Andy Moreton wrote: >>>>>> How are users meant to write reliable code using such constructs ? >>>> >>>>> Ensure that the pattern actually matches :) >>>> >>>> You mean, unless you can be 100% sure that the pattern will match, you >>>> mustn't use pcase-... constructs. That sounds equivalent to saying you >>>> shouldn't use these constructs at all. >>> >>> That's an odd conclusion. >> >> It is a perfectly reasonable conclusion. > > Why? A large number of ELisp functions don't say what they do if their > argument isn't of the expected type, or doesn't have the expected structure. > If you're not 100% sure that the argument has the right type, you shouldn't > use them (instead, you should do an appropriate check first). This is not > equivalent to saying that they shouldn't be used at all. > > I don't understand what's so special about pcase-*. Functions like lookup-key > or define-key don't tell you what happens if you pass something else that a > keymap; does that mean you should never use them? Same for a function like > `c-common-init' in cc-mode (the doc doesn't tell you what happens if you pass > a symbol that isn't a mode; AFAICT, if you do, you get an error but the > current buffer is left in a broken state. The difference is that the non-pcase constructs can document exactly which types are acceptable as arguments. For the pcase macros, the acceptable argument types are not fixed by the pcase macro, but depend on the patterns used. That is harder to explain clearly, and harder for the user to reason about correctness of the code that they write. AndyM ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-11-01 14:44 ` Andy Moreton @ 2018-11-01 15:28 ` Clément Pit-Claudel 0 siblings, 0 replies; 375+ messages in thread From: Clément Pit-Claudel @ 2018-11-01 15:28 UTC (permalink / raw) To: emacs-devel On 01/11/2018 10.44, Andy Moreton wrote: > The difference is that the non-pcase constructs can document exactly > which types are acceptable as arguments. For the pcase macros, the > acceptable argument types are not fixed by the pcase macro, but depend > on the patterns used. That is harder to explain clearly, and harder for > the user to reason about correctness of the code that they write. Thanks, I see what you mean (though it soujnds more like a general indictment of pcase, not just of the "fail silently" behavior of pcase-*). Conversely, though, you could argue that documenting exactly which data are acceptable is precisely what the patterns passed to pcase-let do: if I write `(pcase-let* ((`(,a . ,b) xyz)) …)`, I'm specifying that `xyz' should be a cons. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-29 21:08 ` Stefan Monnier ` (2 preceding siblings ...) 2018-10-30 6:17 ` Eli Zaretskii @ 2018-10-30 17:22 ` Michael Heerdegen 2018-10-30 17:31 ` Stefan Monnier 2018-10-30 18:09 ` Alan Mackenzie 4 siblings, 1 reply; 375+ messages in thread From: Michael Heerdegen @ 2018-10-30 17:22 UTC (permalink / raw) To: Stefan Monnier; +Cc: emacs-devel [-- Attachment #1: Type: text/plain, Size: 227 bytes --] Stefan, we also wanted to say something more about side effects. Since the restoration of the pcase docstring this is completely missing. Maybe you also can take care about this? I would suggest maybe something like this: [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #2: 0001-WIP-pcase-pattern-side-effects.patch --] [-- Type: text/x-diff, Size: 771 bytes --] From 499e715e2f31fc7f9e50dfb553532aedaba1dd3f Mon Sep 17 00:00:00 2001 From: Michael Heerdegen <michael_heerdegen@web.de> Date: Sun, 28 Oct 2018 23:30:49 +0100 Subject: [PATCH] WIP: pcase pattern side effects --- lisp/emacs-lisp/pcase.el | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lisp/emacs-lisp/pcase.el b/lisp/emacs-lisp/pcase.el index 57c2d6c3cb..ff59d2c3a0 100644 --- a/lisp/emacs-lisp/pcase.el +++ b/lisp/emacs-lisp/pcase.el @@ -139,6 +139,9 @@ pcase (F ARG1 .. ARGn) call F with ARG1..ARGn and EXPVAL as n+1'th argument +Evaluating a FUN, BOOLEXP or EXPR as described above should not have +any side effects. + FUN, BOOLEXP, EXPR, and subsequent PAT can refer to variables bound earlier in the pattern by a SYMBOL pattern. -- 2.19.1 [-- Attachment #3: Type: text/plain, Size: 20 bytes --] Thanks, Michael. ^ permalink raw reply related [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-30 17:22 ` Michael Heerdegen @ 2018-10-30 17:31 ` Stefan Monnier 2018-10-30 23:08 ` Michael Heerdegen 0 siblings, 1 reply; 375+ messages in thread From: Stefan Monnier @ 2018-10-30 17:31 UTC (permalink / raw) To: Michael Heerdegen; +Cc: emacs-devel > +Evaluating a FUN, BOOLEXP or EXPR as described above should not have > +any side effects. LGTM, thanks. We could maybe give a hint about why, e.g. saying that there are no guarantees about the order and number of times they are run. Stefan ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-30 17:31 ` Stefan Monnier @ 2018-10-30 23:08 ` Michael Heerdegen 2018-10-31 3:09 ` Stefan Monnier 0 siblings, 1 reply; 375+ messages in thread From: Michael Heerdegen @ 2018-10-30 23:08 UTC (permalink / raw) To: Stefan Monnier; +Cc: emacs-devel Stefan Monnier <monnier@IRO.UMontreal.CA> writes: > LGTM, thanks. We could maybe give a hint about why, e.g. saying that > there are no guarantees about the order and number of times they are run. Are these the only restrictions? Are there even cases where side effects can still be relied on - e.g. in #+begin_src emacs-lisp (pcase EXPR ((and P1 (guard (prog1 t (setq x 15))) P2) BODY1) ...) #+end_src is it legitimate to assume that x has been set to 15 if BODY1 is evaluated (and P1 and P2 don't touch x)? Or should we say side effects are generally disallowed - maybe also because we don't know how this could change in the future? Thanks, Michael. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-30 23:08 ` Michael Heerdegen @ 2018-10-31 3:09 ` Stefan Monnier 2018-11-05 2:01 ` Michael Heerdegen 0 siblings, 1 reply; 375+ messages in thread From: Stefan Monnier @ 2018-10-31 3:09 UTC (permalink / raw) To: Michael Heerdegen; +Cc: emacs-devel >> LGTM, thanks. We could maybe give a hint about why, e.g. saying that >> there are no guarantees about the order and number of times they are run. > Are these the only restrictions? I think so, yes. > Are there even cases where side effects can still be relied on - > e.g. in > > #+begin_src emacs-lisp > (pcase EXPR > ((and P1 (guard (prog1 t (setq x 15))) P2) BODY1) > ...) > #+end_src > > is it legitimate to assume that x has been set to 15 if BODY1 is > evaluated (and P1 and P2 don't touch x)? Yes: pcase doesn't look inside the `guard`s so in order to get to BODY1 it had to evaluate `(prog1 t (setq x 15))` at some point. But some of the preds and guards of other branches (both before and after the one of BODY1) may also be run before getting to BODY1. Stefan ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-31 3:09 ` Stefan Monnier @ 2018-11-05 2:01 ` Michael Heerdegen 2018-11-05 4:49 ` Stefan Monnier 0 siblings, 1 reply; 375+ messages in thread From: Michael Heerdegen @ 2018-11-05 2:01 UTC (permalink / raw) To: Stefan Monnier; +Cc: emacs-devel Stefan Monnier <monnier@IRO.UMontreal.CA> writes: > But some of the preds and guards of other branches (both before and > after the one of BODY1) may also be run before getting to BODY1. Does that imply that we also should remove sentences like these from the manual (last line): @item (and @var{pattern1}@dots{}) Attempts to match @var{pattern1}@dots{}, in order, until one of them fails to match. In that case, @code{and} likewise fails to match, and the rest of the sub-patterns are not tested. Michael. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-11-05 2:01 ` Michael Heerdegen @ 2018-11-05 4:49 ` Stefan Monnier 2018-11-05 23:06 ` Michael Heerdegen 0 siblings, 1 reply; 375+ messages in thread From: Stefan Monnier @ 2018-11-05 4:49 UTC (permalink / raw) To: Michael Heerdegen; +Cc: emacs-devel >> But some of the preds and guards of other branches (both before and >> after the one of BODY1) may also be run before getting to BODY1. > > Does that imply that we also should remove sentences like these from the > manual (last line): > > @item (and @var{pattern1}@dots{}) > Attempts to match @var{pattern1}@dots{}, in order, > until one of them fails to match. > In that case, @code{and} likewise fails to match, > and the rest of the sub-patterns are not tested. No, that one sounds fine. Why do you think it's inconsistent with what I said? Stefan ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-11-05 4:49 ` Stefan Monnier @ 2018-11-05 23:06 ` Michael Heerdegen 0 siblings, 0 replies; 375+ messages in thread From: Michael Heerdegen @ 2018-11-05 23:06 UTC (permalink / raw) To: Stefan Monnier; +Cc: emacs-devel Stefan Monnier <monnier@IRO.UMontreal.CA> writes: > >> But some of the preds and guards of other branches (both before and > >> after the one of BODY1) may also be run before getting to BODY1. > > > > Does that imply that we also should remove sentences like these from > > the manual (last line): > > > > @item (and @var{pattern1}@dots{}) > > Attempts to match @var{pattern1}@dots{}, in order, > > until one of them fails to match. > > In that case, @code{and} likewise fails to match, > > and the rest of the sub-patterns are not tested. > > No, that one sounds fine. > Why do you think it's inconsistent with what I said? I wondered if what you said about the preds and guards of other branches is also true about preds and guards in other "branches" in ors and ands. With other words, I wonder when we say > > In that case, @code{and} likewise fails to match, > > and the rest of the sub-patterns are not tested. if what users expects to be the "rest" of subpatterns is always the patterns lexically following the one that failed. Are patterns in or and and always tested in order? And, if these include preds or guards, always exactly once? Michael. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-29 21:08 ` Stefan Monnier ` (3 preceding siblings ...) 2018-10-30 17:22 ` Michael Heerdegen @ 2018-10-30 18:09 ` Alan Mackenzie 2018-10-30 18:17 ` Stefan Monnier 4 siblings, 1 reply; 375+ messages in thread From: Alan Mackenzie @ 2018-10-30 18:09 UTC (permalink / raw) To: Stefan Monnier; +Cc: emacs-devel Hello, Stefan. On Mon, Oct 29, 2018 at 17:08:38 -0400, Stefan Monnier wrote: > >> > Doc strings which specify fully the arguments to these macros, including > >> > their semantics, and say what the macros do. The current doc strings > >> > (at least some of them) for these macros don't do this. > >> I understand this in theory, but I don't know what it means in this > >> concrete case. > > Take a look at, for example, the doc string for pcase-dolist. In its > > entirety, it's this: > Thanks. What do you think of the patch below? I don't think it's enough. > I'd rather keep it defined in terms of its differences w.r.t `dolist`, > but if really needed, we could change the doc so it doesn't rely on > `dolist`s own doc at all. That's a bad idea if it means not saying what the macro does. Not everybody is familiar with dolist by any means. Is dolist's doc string of sufficiently high quality to act as this basis? > We do have to keep the reference to `pcase` because we don't want to > repeat the definition of what a pcase pattern can look like. Yes, I think that's right. Things I believe MUST appear explicitly in the doc string for pcase-dolist: 1. It is a loop over the elements of LIST, which must be a list. 2. It attempts to match the current list element with the supplied PATTERN, which must be a valid pcase style pattern. 3. The BODY forms are evaluated for each element of the list. 4. The purpose of the matching is to create bindings for symbols, and these bindings are in force when the BODY forms are evaluated. 5. When a pattern match fails, ..... (This needs to be stated). > Stefan > diff --git a/lisp/emacs-lisp/pcase.el b/lisp/emacs-lisp/pcase.el > index 57c2d6c3cb..861c900b21 100644 > --- a/lisp/emacs-lisp/pcase.el > +++ b/lisp/emacs-lisp/pcase.el > @@ -281,7 +281,7 @@ pcase-let* > (defmacro pcase-let (bindings &rest body) > "Like `let' but where you can use `pcase' patterns for bindings. > BODY should be a list of expressions, and BINDINGS should be a list of bindings > -of the form (PAT EXP). > +of the form (PATTERN EXP). > The macro is expanded and optimized under the assumption that those > patterns *will* match, so a mismatch may go undetected or may cause > any kind of error." > @@ -302,7 +302,12 @@ pcase-let > ;;;###autoload > (defmacro pcase-dolist (spec &rest body) > - "Like `dolist' but where the binding can be a `pcase' pattern. > + "Superset of `dolist' where the VAR binding can be a `pcase' PATTERN. > +More specifically `dolist's VAR binding is replaced by a PATTERN > +against which each element of the list is matched. > +As in the case of `pcase-let', PATTERN is matched under the assumption > +that it *will* match. > + > \n(fn (PATTERN LIST) BODY...)" > (declare (indent 1) (debug ((pcase-PAT form) body))) > (if (pcase--trivial-upat-p (car spec)) -- Alan Mackenzie (Nuremberg, Germany). ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-30 18:09 ` Alan Mackenzie @ 2018-10-30 18:17 ` Stefan Monnier 2018-10-30 19:00 ` Alan Mackenzie 0 siblings, 1 reply; 375+ messages in thread From: Stefan Monnier @ 2018-10-30 18:17 UTC (permalink / raw) To: emacs-devel > Not everybody is familiar with dolist by any means. Is dolist's doc > string of sufficiently high quality to act as this basis? If dolist's docstring is not good enough, then I don't think it's pcase-dolist's job to fix it. >> We do have to keep the reference to `pcase` because we don't want to >> repeat the definition of what a pcase pattern can look like. > > Yes, I think that's right. > > Things I believe MUST appear explicitly in the doc string for > pcase-dolist: > 1. It is a loop over the elements of LIST, which must be a list. > 2. It attempts to match the current list element with the supplied > PATTERN, which must be a valid pcase style pattern. > 3. The BODY forms are evaluated for each element of the list. > 4. The purpose of the matching is to create bindings for symbols, and > these bindings are in force when the BODY forms are evaluated. > 5. When a pattern match fails, ..... (This needs to be stated). This is highly redundant w.r.t pcase-let and dolist. Fine for the manual, but not for docstrings. You can click on the link to the docstring of `dolist` and `pcase` (tho, I now see the link should go to `pcase-let` instead). Stefan ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-30 18:17 ` Stefan Monnier @ 2018-10-30 19:00 ` Alan Mackenzie 2018-10-31 0:21 ` Andy Moreton 0 siblings, 1 reply; 375+ messages in thread From: Alan Mackenzie @ 2018-10-30 19:00 UTC (permalink / raw) To: Stefan Monnier; +Cc: emacs-devel Hello, Stefan. On Tue, Oct 30, 2018 at 14:17:10 -0400, Stefan Monnier wrote: > > Not everybody is familiar with dolist by any means. Is dolist's doc > > string of sufficiently high quality to act as this basis? > If dolist's docstring is not good enough, then I don't think it's > pcase-dolist's job to fix it. I think everybody would agree with this point. > >> We do have to keep the reference to `pcase` because we don't want to > >> repeat the definition of what a pcase pattern can look like. > > Yes, I think that's right. > > Things I believe MUST appear explicitly in the doc string for > > pcase-dolist: > > 1. It is a loop over the elements of LIST, which must be a list. > > 2. It attempts to match the current list element with the supplied > > PATTERN, which must be a valid pcase style pattern. > > 3. The BODY forms are evaluated for each element of the list. > > 4. The purpose of the matching is to create bindings for symbols, and > > these bindings are in force when the BODY forms are evaluated. > > 5. When a pattern match fails, ..... (This needs to be stated). > This is highly redundant w.r.t pcase-let and dolist. Maybe, but so what? Doc strings should be as far as is reasonable self contained. Have a look at the doc strings for let and let*. They have a great deal in common, but each is self contained. > Fine for the manual, but not for docstrings. You seem to be arguing that doc strings needn't say what de{fun,macro,var}s do and are, as long as the meaning can be acquired through the traversal of a directed acyclic graph of linked doc strings. Maybe you find this a good way of acquiring information, but I certainly don't. I just get angry and frustrated, and I'm sure I'm not the only one. > You can click on the link to the docstring of `dolist` and `pcase` > (tho, I now see the link should go to `pcase-let` instead). I can, but I'd much rather find the information in a coherent form in a single place. That's what doc strings are for. > Stefan -- Alan Mackenzie (Nuremberg, Germany). ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-30 19:00 ` Alan Mackenzie @ 2018-10-31 0:21 ` Andy Moreton 0 siblings, 0 replies; 375+ messages in thread From: Andy Moreton @ 2018-10-31 0:21 UTC (permalink / raw) To: emacs-devel On Tue 30 Oct 2018, Alan Mackenzie wrote: > Hello, Stefan. > > On Tue, Oct 30, 2018 at 14:17:10 -0400, Stefan Monnier wrote: >> > Not everybody is familiar with dolist by any means. Is dolist's doc >> > string of sufficiently high quality to act as this basis? > >> If dolist's docstring is not good enough, then I don't think it's >> pcase-dolist's job to fix it. > > I think everybody would agree with this point. > >> >> We do have to keep the reference to `pcase` because we don't want to >> >> repeat the definition of what a pcase pattern can look like. > >> > Yes, I think that's right. > >> > Things I believe MUST appear explicitly in the doc string for >> > pcase-dolist: >> > 1. It is a loop over the elements of LIST, which must be a list. >> > 2. It attempts to match the current list element with the supplied >> > PATTERN, which must be a valid pcase style pattern. >> > 3. The BODY forms are evaluated for each element of the list. >> > 4. The purpose of the matching is to create bindings for symbols, and >> > these bindings are in force when the BODY forms are evaluated. >> > 5. When a pattern match fails, ..... (This needs to be stated). > >> This is highly redundant w.r.t pcase-let and dolist. > > Maybe, but so what? > > Doc strings should be as far as is reasonable self contained. Have a > look at the doc strings for let and let*. They have a great deal in > common, but each is self contained. Exactly. For the pcase macros, the docstrings need to describe what the arguments are, and what the macro actually does. A reference to `pcase' itself to describe the patterns is fine. The last thing in the docstring should be a reference to the similarly named non-pcase construct with similar behaviour (which is the least important part). >> Fine for the manual, but not for docstrings. > > You seem to be arguing that doc strings needn't say what > de{fun,macro,var}s do and are, as long as the meaning can be acquired > through the traversal of a directed acyclic graph of linked doc strings. > Maybe you find this a good way of acquiring information, but I certainly > don't. I just get angry and frustrated, and I'm sure I'm not the only > one. Me too. Docstrings are to educate and inform users, and lead them to discover new functionality (and hopefully read the manual for more detailed discussion). A little redundancy of presentation is actually a good thing if it aids the understanding of non-experts who are trying to learn. AndyM ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-28 21:44 ` Stefan Monnier 2018-10-29 13:01 ` Alan Mackenzie @ 2018-10-29 14:47 ` Andy Moreton 2018-10-29 18:49 ` pcase-lambda usage [Was: Re: Replace trivial pcase occurrences in the Emacs sources] Garreau, Alexandre 2018-10-30 23:34 ` Replace trivial pcase occurrences in the Emacs sources Van L 2 siblings, 1 reply; 375+ messages in thread From: Andy Moreton @ 2018-10-29 14:47 UTC (permalink / raw) To: emacs-devel On Sun 28 Oct 2018, Stefan Monnier wrote: >> pcase-lambda, pcase-let, pcase-let*, and pcase-dolist still have no >> meaningful documentation, > > Not sure what kind of documentation would be more meaningful, sorry. > Do you happen to have concrete questions about them which aren't answered > by their docstrings? Here is the documentation for lambda - reasonably complete and descriptive, and with links to other referenced symbols: (lambda ARGS [DOCSTRING] [INTERACTIVE] BODY) Return a lambda expression. A call of the form (lambda ARGS DOCSTRING INTERACTIVE BODY) is self-quoting; the result of evaluating the lambda expression is the expression itself. The lambda expression may then be treated as a function, i.e., stored as the function value of a symbol, passed to ‘funcall’ or ‘mapcar’, etc. ARGS should take the same form as an argument list for a ‘defun’. DOCSTRING is an optional documentation string. If present, it should describe how to call the function. But documentation strings are usually not useful in nameless functions. INTERACTIVE should be a call to the function ‘interactive’, which see. It may also be omitted. BODY should be a list of Lisp expressions. Contrast this with the `pcase-lambda' docstring: (pcase-lambda LAMBDA-LIST &rest BODY) Like ‘lambda’ but allow each argument to be a pattern. I.e. accepts the usual &optional and &rest keywords, but every formal argument can be any pattern accepted by ‘pcase’ (a mere variable name being but a special case of it). This mentions "each argument", but the arguments shown have `LAMBDA-LIST' (which is not described) and BODY - is this an argument that can be pattern ? There is no discussion of how pattern match failure is treated - what happens ? Please note that users can only read what is in the docstring, not the unwritten intentions of the docstring author. The `pcase-let' docstring warns that it assumes patterns will match and fails arbitrarily if that is not the case. This seems a strng indicator that this macro is unsafe for use in any user code. The `pcase-let*' docstring does not mention a similar pattern matching assumption, so does it also behave randomly on pattern match failure ? The `pcase-dolist' docstring is entirely uninformative. None of the arguments are described, nor are the semantics of the macro. The docstring needs complete replacement. The pcase-exhaustive docstring mentions that an error is signalled if pattern matching fails, but which error ? How are users supposed to write code that determines that a pattern match failure has occurred rather than any other error ? Which error is signalled should be part of the interface contract here, and should be documented. There are no entry in the manual for the pcase macros, and there are no meaningful examples to show proper usage of each of the pcase match pattern types. > Could you clarify what you find problematic in those uses? Given that the documentation is insufficient to describe the syntax and semantics of these macros, how can ordinary users discern the meaning of a pcase construct that they read in code ? How can they learn to write code containing pcase macros which has the user's desired semantics ? How can users learn when these constructs may be beneficial and when they should be avoided ? AndyM ^ permalink raw reply [flat|nested] 375+ messages in thread
* pcase-lambda usage [Was: Re: Replace trivial pcase occurrences in the Emacs sources] 2018-10-29 14:47 ` Andy Moreton @ 2018-10-29 18:49 ` Garreau, Alexandre 0 siblings, 0 replies; 375+ messages in thread From: Garreau, Alexandre @ 2018-10-29 18:49 UTC (permalink / raw) To: Andy Moreton; +Cc: emacs-devel From what I learnt from pcase-lambda (I wished there were a simple `match' implemented over `cl-destructuring-bind', similar to one-matching cl implementations, on which would be based pcase (which match several alternatively), and pcase-*), here a docstring that seems better to me, probably not ideal, if anybody can improve, tell it: #+BEGIN_SRC elisp "Like `lambda' but destructure each PATTERN with `pcase'. It is not self-quoting: the result of `pcase-lambda' is a lambda expression like returned by `lambda'. Only then, the lambda expression may be stored as a function value of a symbol with `fset', passed to `funcall' or `mapcar', etc. The first argument, of the form (PATTERN...) also accepts the usual &optional and &rest keywords accepted in lambda expressions arglist, but every formal element can be any pattern accepted by `pcase' (a mere variable name being but a special case of it). PATTERN should take the same form as a `pcase' pattern. A given subpattern inside PATTERN might not match values (equality) or even types, except for each of its subsequences, which *have* to exist, have the right type, and be in the right place. DOCSTRING is an optional documentation string just as in `lambda'. Note that each PATTERN that is a special `pcase' pattern will get an automatically assigned name: you may want to put \\(fn YOUR ARGLIST (AS YOU INTENDED)) so to reflect your patterns. INTERACTIVE, should as well be a call to the function `interactive'. It may be omitted. BODY should be the usual list of Lisp expressions `lambda' takes as lasts arguments. \(fn (PATTERN...) [DOCSTRING] [INTERACTIVE] BODY)" #+END_SRC As I never saw pcase-lambda before and this was the first time I see anything about it, here a sample of the process I went trough: C-h f pcase-lambda RET => (pcase-lambda LAMBDA-LIST &rest BODY) Okay, so there’s only one pattern, so it’s not pattern matching (as its name might wrongly suggest), like in OCaml “function” operator, it’s simple destructuring, exactely like `cl-destructuring-bind', but richer. Also: no “docstring”? no “interactive”? really? doesn’t `pcase-lambda' happen to work by translating to a lambda? does it override docstrings (that might make sense, so to replace the arglist in help by the pcase pattern) and interactiveness (that doesn’t make sense at all: so we can’t define after pcase-lambda a pcase-defun and pcase-defmacro (wait, this one is already occupied… it should have been a different name then: this has gone too far)?)? let’s try: #+BEGIN_SRC emacs-lisp (global-set-key (kbd "C-c c c c") (pcase-lambda (a `(,b ,c)) "test" (interactive) (insert ?2))) #+END_SRC Then “C-c c c c”, actually inserts 2. C-h k C-c c c c => the docstring is “test”. So these must be implicitly considered as inside “body”… that doesn’t make really sense: even `lambda' explictly tells about them, while not recommanding against not using docstring in anonymous function. Docstring: > Like ‘lambda’ but allow each argument to be a pattern. > I.e. accepts the usual &optional and &rest keywords, but every > formal argument can be any pattern accepted by ‘pcase’ (a mere > variable name being but a special case of it). Oh, does that mean I can, like cl-destructuring-bind, put &optional and &rest wherever I want in any subpattern? So then pcase is strictly a superset of cl-destructuring-bind: how sad one is not implemented upon the other, then (cl-destructuring-bind ought to have a no-error function so that to be usable to build something upon it). #+BEGIN_SRC emacs-lisp (pcase-lambda (a (b c)) c) ;; => pcase--macroexpand: Unknown a pattern: (a (b c)) (pcase (list 1 (list 2 3)) ((a (b c)) c)) ;; => pcase--macroexpand: Unknown a pattern: (a (b c)) ;; Oh, I recall, pcase behaves differently than normal ;; pattern-matching, I must quote everything! (pcase-lambda '(a (b c)) c) ;; => pcase--macroexpand: Unknown a pattern: (a (b c)) ;; Uh, isn’t ' a pattern in pcase? It errs out just the same! (pcase '(1 (2 3)) ('(a (b c)) t)) ; => nil ; But… why aren’t they ; behaving the same? Why ; don’t I get an error? ;; Oh I recall! I must use “`”: (pcase '(1 (2 3)) (`(,a (,b ,c)) t)) ; => t (It Works!™) So: (pcase-lambda `(,a (,b ,c)) c) ; => Wrong type argument: symbolp, (\, a) ;; Uh, isn’t that the correct way to use pcase? ;; Let’s go back before, when it unexpectedly didn’t err, wasn’t I ;; right? (pcase '(a (b c)) ('(a (b c)) t)) ; => t (so indeed, I was right) (pcase 'a ('a t)) ; => t (indeed, when you quote you compare symbols, ; not values (nor bind anything)) ;; So let’s try the simplest case: (pcase-lambda 'a a) ; => (lambda (quote a) a) ;; Oh, if I’m right, that “quote” isn’t a quotation, but an argument ((lambda (quote a) a) 1 2) ; => 2 (it seems so) ((lambda (quote a) a) 'a) ;; => Wrong number of arguments: (lambda (quote a) a), 1 ;; it *is* so ;; Then, if I’m right, the correct usage is: (pcase-lambda (a) a) ; => (lambda (a) a) ; okay it returns clean ; lambdas if possible (pcase-lambda (a (2 3)) a) ;; => (lambda (a arg0) (let nil a)) ;; ah, I was wrong, nevermind (why this useless `let nil'?). Btw, may I ;; suggest an argument name such as `list' instead of `arg0' that would ;; indicate type, as it is traditional in lisp (and only number list0, ;; list1, etc. if there are several of them) ((pcase-lambda (a '(2 3)) a) 1 (list 2 3)) ;; => Invalid function: (pcase-lambda (a (quote (2 3)) a)) ;; oh, there must be a special elisp-related reason why even if it does ;; return a lambda it can’t be used right away (maybe because it’s a ;; lisp-2?). Since `lambda' doc says it’s “self-quoting” and “may be ;; used as a function”, and that’s not true the same way here, it should ;; be said. (funcall (pcase-lambda (a '(2 3)) a) 1 (list 2 3)) => 1 ;; Okay so since `lambda' docstring takes the time to say it works with ;; `funcall' and `mapcar', then probably `pcase-lambda' should too, so ;; an example of how to properly use it comes immediatly to mind. (funcall (pcase-lambda (a '(2 3)) a) 1 (list 1 1)) ;; Okay it’s not normal, it should give an error, or returns nil, I think. (funcall (pcase-lambda (a '(b c)) c) 1 '(2 3)) ; let’s see what’s wrong ;; => Symbol’s value as variable is void: c ;; c isn’t bound? ;; Maybe quoting, again? (funcall (pcase-lambda (a `(,b ,c)) c) 1 '(2 3)) ; => 3 (yes, quoting) ;; Let’s try again not to match: (funcall (pcase-lambda (`(1 ,b 3)) a) 2) ;; => let*: Wrong type argument: listp, 2 ;; Cool! *Now* it gives errors! (funcall (pcase-lambda (`(1 ,b 3)) b) '(2)) ;; => nil (okay… I don’t understand) (funcall (pcase-lambda (`(1 ,b 3)) b) '(1 2 4)) ;; => 2 (mmmh… seems lazy on arity and eq-uality… but picky on types) (mapcar (pcase-lambda (`(1 (2 ,c 4 . 5))) c) '((1 (2 3 4 . 5)) (1 (2)) (1 (2 3 4 5 6 . 7)))) ;; => (2 nil) (indeed, it doesn’t give a fuck about arity) (funcall (pcase-lambda (`(1 (2 ,c 4 . 5))) c) '(1 (2 . 3))) ;; => let*: Wrong type argument: listp, 3 ;; But it want sequences to be the right type (funcall (pcase-lambda (`(1 (2 ,c 4 . 5))) c) '(1 (2 3 . 4))) ;; => let*: Wrong type argument: listp, 4 ;; Even when it doesn’t need to, apparently, so it’s not even laziness (funcall (pcase-lambda (`(1 (2 ,c (4 5)))) c) '(1 (2 3))) ; => 3 (funcall (pcase-lambda (`(1 (2 ,c (4 5)))) c) '(1 (2 3 [4 5]))) ;; => let*: Wrong type argument: listp, [4 5] ;; Yeah, sequences types, only that (it should have used “elt”, so it ;; would have always worked (you then only need to have the same ;; sequences tree structure) ;; let’s try out how that acts on arglist features (funcall (pcase-lambda (a `(&rest ,rest)) rest) 1 2 3) ;; => Wrong number of arguments: (lambda (a arg0) (let* ((x (car ;; arg0)) (x (cdr arg0)) (x (car x)) (x (cdr x))) (let ((rest x)) ;; rest))), 3 ;; Ah indeed, to do that it would be: (funcall (pcase-lambda (a &rest rest) rest) 1 2 3) ; => (2 3) ;; yes &rest works ;; So, I want, with correct args: (funcall (pcase-lambda (a `(&rest ,rest)) rest) 1 '(2 3)) ; => 3 ;; UH??? (funcall (pcase-lambda (a `(,b ,c &rest ,rest)) rest) 1 '(2 3 4 5 6 7)) ;; => 5 (okay something strange is going) (funcall (pcase-lambda (a `(,b ,c &optional ,opt)) opt) 1 '(2 3 4)) (funcall (pcase-lambda (a `(,b ,c &optional ,opt)) opt) 1 '(2 3)) ;; => nil => nil (what?) (funcall (pcase-lambda (a `(,b ,c &optional ,opt)) opt) 1 '(2 3 4 5)) ;; => 5 (there’s one argument too much) ;; Don’t say me &optional is matched as an argument? (funcall (pcase-lambda (a `(,b ,c &optional ,opt)) (list b c opt)) 1 '(2 3 4 5)) ; => (2 3 5) ;; Is seems to >< so in the end it doesn’t work? (funcall (pcase-lambda (a &optional ,opt) (cons a opt)) 1 '(2 3 4 5)) ;; => pcase--macroexpand: Unknown , pattern: (\, opt) (funcall (pcase-lambda (a &optional opt) (cons a opt)) 1 2) ; => (1 . 2) (funcall (pcase-lambda (a &optional opt) (cons a opt)) 1) ; => (1) ;; Isn’t behavior not supposed to change depending on nesting? (apply (pcase-lambda (a (b (c))) (cons a c)) '(a (b (c)))) ;; => pcase--macroexpand: Unknown b pattern: (b (c)) ;; It seems it becomes real `pcase' only from second level: (apply (pcase-lambda (a `(,b (,c))) (cons a c)) '(a (b (c)))) ;; => (a . c) ;; So first level is what normal lambda (or destructuring-bind) does, ;; that looks like real pattern matching that look like the matched ;; data, like in ocaml, haskell, etc. and second level is pcase syntax… #+END_SRC ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-28 21:44 ` Stefan Monnier 2018-10-29 13:01 ` Alan Mackenzie 2018-10-29 14:47 ` Andy Moreton @ 2018-10-30 23:34 ` Van L 2018-10-31 3:14 ` Stefan Monnier 2 siblings, 1 reply; 375+ messages in thread From: Van L @ 2018-10-30 23:34 UTC (permalink / raw) To: Emacs developers > I obviously can't judge fairly how hard it is to use, but I don't find > any of the examples posted here as evidence of problematic use and even > less misuse (they look perfectly correct to me). That would be because you are an expert and you’ve lost reachability to your beginner’s mind. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-30 23:34 ` Replace trivial pcase occurrences in the Emacs sources Van L @ 2018-10-31 3:14 ` Stefan Monnier 0 siblings, 0 replies; 375+ messages in thread From: Stefan Monnier @ 2018-10-31 3:14 UTC (permalink / raw) To: emacs-devel >> I obviously can't judge fairly how hard it is to use, but I don't find >> any of the examples posted here as evidence of problematic use and even >> less misuse (they look perfectly correct to me). > > That would be because you are an expert and > you’ve lost reachability to your beginner’s > mind. That's undoubtly true w.r.t "evidence of problematic use" (so I need someone to explain to me what's problematic about it since I'm too used to see it), but not w.r.t misuse where it should not be an obstacle to judge what is a misuse. Stefan ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-23 15:17 ` Replace trivial pcase occurrences in the Emacs sources (was: The poor state of documentation of pcase like things.) Eli Zaretskii 2018-10-23 17:14 ` Replace trivial pcase occurrences in the Emacs sources Stefan Monnier @ 2018-10-23 17:22 ` John Wiegley 1 sibling, 0 replies; 375+ messages in thread From: John Wiegley @ 2018-10-23 17:22 UTC (permalink / raw) To: Eli Zaretskii; +Cc: Michael Heerdegen, monnier, emacs-devel >>>>> "EZ" == Eli Zaretskii <eliz@gnu.org> writes: >> I would like to do that now. EZ> Thank you. If you find places where pcase is used, but a simple cond will EZ> do (without obfuscating the code, of course), please use cond where EZ> appropriate. I'm also all for a gain in simplicity, even though I'm a pcase-lover myself. -- John Wiegley GPG fingerprint = 4710 CF98 AF9B 327B B80F http://newartisans.com 60E1 46C4 BD1A 7AC1 4BA2 ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: Replace trivial pcase occurrences in the Emacs sources 2018-10-23 13:04 ` Replace trivial pcase occurrences in the Emacs sources (was: The poor state of documentation of pcase like things.) Michael Heerdegen 2018-10-23 14:43 ` Clément Pit-Claudel 2018-10-23 15:17 ` Replace trivial pcase occurrences in the Emacs sources (was: The poor state of documentation of pcase like things.) Eli Zaretskii @ 2018-10-23 17:16 ` Stefan Monnier 2 siblings, 0 replies; 375+ messages in thread From: Stefan Monnier @ 2018-10-23 17:16 UTC (permalink / raw) To: Michael Heerdegen; +Cc: Eli Zaretskii, emacs-devel > In a second step, I also would want to replace the unnecessarily > backquoted patterns to use quotes, i.e. `DOESNT-UNQUOTE -> > 'DOESNT-UNQUOTE (the `ATOM patterns go back to a time where the quoted > syntax wasn't yet implemented). Sounds good to me, Stefan ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: The poor state of documentation of pcase like things. 2016-01-03 15:52 ` David Kastrup 2016-01-03 15:59 ` Dmitry Gutov @ 2016-01-04 2:54 ` Michael Heerdegen 1 sibling, 0 replies; 375+ messages in thread From: Michael Heerdegen @ 2016-01-04 2:54 UTC (permalink / raw) To: emacs-devel David Kastrup <dak@gnu.org> writes: > However, it would seem to indicate that the proponents of pcase do not > want to see their actions discussed, so I'm not going to respond to this > thread anymore either way. It would appear that we are on course > replacing consensual agreed-upon action with battling commits and > stifling speech. I've got a very similar impression from "your" side. Maybe we should all read a book about how to manage such discussions. This was not fun. Michael. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: The poor state of documentation of pcase like things. 2016-01-01 18:39 ` David Kastrup 2016-01-01 19:05 ` Daniel Colascione @ 2016-01-02 1:15 ` Richard Copley 2016-01-02 3:50 ` Drew Adams 1 sibling, 1 reply; 375+ messages in thread From: Richard Copley @ 2016-01-02 1:15 UTC (permalink / raw) To: David Kastrup; +Cc: Michael Heerdegen, Eli Zaretskii, Emacs Development On 1 January 2016 at 18:39, David Kastrup <dak@gnu.org> wrote: > John Wiegley <jwiegley@gmail.com> writes: > >>>>>>> Eli Zaretskii <eliz@gnu.org> writes: >> >>> (pcase skip >>> (`nil nil) >>> (`0 t) >>> (_ (setq i (+ i skip -1)) (funcall get-next-frame))))))) >> >> (cond ((null skip)) >> ((eq skip 0) t) >> (t (setq i (+ i skip -1)) >> (funcall get-next-frame))) >> >> Not much difference. > > If skip is nil, the first returns probably nil and the second t. One > could probably do > > (and skip > (or (eql skip 0) > (setq ...))) True, but only an unintentional slip. I think the charitable interpretation is (cond ((null skip) nil) [...]) > I'm not fond of eq for numeric comparisons: that's an Elispism. That's Elisp programs for you. I'd have used zerop. ^ permalink raw reply [flat|nested] 375+ messages in thread
* RE: The poor state of documentation of pcase like things. 2016-01-02 1:15 ` Richard Copley @ 2016-01-02 3:50 ` Drew Adams 0 siblings, 0 replies; 375+ messages in thread From: Drew Adams @ 2016-01-02 3:50 UTC (permalink / raw) To: Richard Copley, David Kastrup Cc: Michael Heerdegen, Eli Zaretskii, Emacs Development > > I'm not fond of eq for numeric comparisons: that's an Elispism. > > That's Elisp programs for you. I'd have used zerop. Only if you can be sure that `skip' is a number, or you want to raise an error if it is not. ^ permalink raw reply [flat|nested] 375+ messages in thread
* RE: The poor state of documentation of pcase like things. 2016-01-01 17:46 ` John Wiegley 2016-01-01 18:39 ` David Kastrup @ 2016-01-02 3:51 ` Drew Adams 1 sibling, 0 replies; 375+ messages in thread From: Drew Adams @ 2016-01-02 3:51 UTC (permalink / raw) To: John Wiegley, Eli Zaretskii; +Cc: Michael Heerdegen, emacs-devel > > (pcase skip > > (`nil nil) > > (`0 t) > > (_ (setq i (+ i skip -1)) (funcall get-next-frame))) > > (cond ((null skip)) > ((eq skip 0) t) > (t (setq i (+ i skip -1)) > (funcall get-next-frame))) Agreed. If you don't need decomposition by pattern matching, why would you need `pcase'? (But as pointed out, the first clause should be ((null skip) nil). (The `cond' is 10 chars more to type in this case, not counting insignificant whitespace. But that is not important.) Or: (cl-case skip ((nil) nil) (0 t) (t (setq i (+ i skip -1)) (funcall get-next-frame))) (Same number of chars as `pcase'. Or 3 fewer, if you use alias\ `case'. But, again, not important.) Or: (and skip (or (eql 0 skip) (progn (setq i (+ i skip -1)) (funcall get-next-frame)))) (3 chars more than the `pcase'. But not important.) > Not much difference. Also, `0 could just be 0. > > One thing it does do: avoids repeating "skip" in the first two tests. That's > the only merit I can see, but would have been more worthwhile if there were, > say, 10 value tests. The same is true of `cl-case' (it is one of the reasons for that macro). But otherwise, just use `let': (let ((sk skip)) (and sk (or (eql 0 sk) (progn (setq i (+ i skip -1)) (funcall get-next-frame)))) ^ permalink raw reply [flat|nested] 375+ messages in thread
[parent not found: <<83y4c9ag06.fsf@gnu.org>]
* RE: The poor state of documentation of pcase like things. [not found] ` <<83y4c9ag06.fsf@gnu.org> @ 2016-01-01 15:18 ` Drew Adams 0 siblings, 0 replies; 375+ messages in thread From: Drew Adams @ 2016-01-01 15:18 UTC (permalink / raw) To: Eli Zaretskii, Michael Heerdegen, John Wiegley; +Cc: emacs-devel > Btw, could someone please tell what are the benefits of using 'pcase' > in snippets like this one: > > (pcase skip > (`nil nil) > (`0 t) > (_ (setq i (+ i skip -1)) (funcall get-next-frame))))))) > > How is this different from using 'cond' in trivial ways? > > (I see quite a few of such uses of 'pcase' in the sources, and when I > read them, I always wonder what is it that I'm missing about that > code.) FWIW, I noticed the same thing a while ago. Seems like someone went on a `pcase' rampage, or perhaps was just overly enthusiastic with a new toy. ("Ooooh - shiny!") We should use `pcase' when it really helps, including helps make reading the code easier. And hopefully some real use of pattern matching would typically be involved (i.e., decomposition, not just matching `nil' or `0' or "abc" literally). ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: The poor state of documentation of pcase like things. 2015-12-26 17:10 ` Michael Heerdegen 2015-12-26 20:52 ` Aaron Ecay @ 2015-12-27 2:53 ` Richard Stallman 1 sibling, 0 replies; 375+ messages in thread From: Richard Stallman @ 2015-12-27 2:53 UTC (permalink / raw) To: Michael Heerdegen; +Cc: emacs-devel [[[ 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. ]]] > Just changing what _ does in pcase's ` to save a comma would IMHO be > what we call in German "verschlimmbessern" (my dictionary says you can > translate that into "disimprove"). I don't think so. A special exception for a particular common case is found in many programming languages, and it is not hard for programmers to understand. -- Dr Richard Stallman President, Free Software Foundation (gnu.org, fsf.org) Internet Hall-of-Famer (internethalloffame.org) Skype: No way! See stallman.org/skype.html. ^ permalink raw reply [flat|nested] 375+ messages in thread
* RE: The poor state of documentation of pcase like things. 2015-12-16 20:26 The poor state of documentation of pcase like things Alan Mackenzie 2015-12-16 20:53 ` Kaushal Modi @ 2015-12-16 21:01 ` Drew Adams 2015-12-17 13:59 ` Phillip Lord 2015-12-19 15:26 ` Michael Heerdegen 3 siblings, 0 replies; 375+ messages in thread From: Drew Adams @ 2015-12-16 21:01 UTC (permalink / raw) To: Alan Mackenzie, emacs-devel Drive-by implementation? Too clever by half? (We don' need no stinkin' doc. The code is the doc. Anyone who needs doc is a wimp. Etc.) ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: The poor state of documentation of pcase like things. 2015-12-16 20:26 The poor state of documentation of pcase like things Alan Mackenzie 2015-12-16 20:53 ` Kaushal Modi 2015-12-16 21:01 ` Drew Adams @ 2015-12-17 13:59 ` Phillip Lord 2015-12-17 17:06 ` Alan Mackenzie 2015-12-19 15:26 ` Michael Heerdegen 3 siblings, 1 reply; 375+ messages in thread From: Phillip Lord @ 2015-12-17 13:59 UTC (permalink / raw) To: Alan Mackenzie; +Cc: emacs-devel Alan Mackenzie <acm@muc.de> writes: > Some of these doc strings are patronising indeed. They all seem to say, > implicitly, "the author's time is far too valuable to waste in writing > meaningful documentation". I think it's probably better to make your points (which are reasonable) without making such aspersions. The author in question has been extremely generous with their time. > > Particularly egregious is the doc string for pcase-exhaustive: "The > exhaustive version of `pcase' (which see).". Uhh???? Needless to say, > the doc string of pcase makes no mention of "exhaustive". > > Let us analyse the documentation of the one macro which is documented to > any meaningful extent, pcase itself: > > The article in the Elisp manual for pcase starts well, documenting the > basic form and outlining the basic semantics, but then starts rambling > on like a tutorial, rather than filling in the semantic details. Here > is a partial list of what is missing from that manual page: > > (i) A @dfn{U-PATTERN}. > (ii) A @dfn{Q-PATTERN}. > These two things are described only in terms of their structure, not > what they are conceptually. What do "U" and "Q" stand for? What is the > semantic significance of a Q-PATTERN? These defined in terms, but unfortunately, the definition is a bit recursive -- so a Q-PATTERN is defined in terms of other Q-PATTERNs (or an atom). > It would appear that Lisp programmers are expected to absorb the > semantics (and sometimes even the syntax) of pcase-* by osmosis: > studying and imitating examples. This is a Bad Thing. I am not 100% convinced that this is a bad thing. The actual semantics of pcase do mess your head up a bit. The first part, the tutorial section, is for me one of the clearest sections. I think it's something that we should have more off, personally. > Most (?all) of the rest of Emacs Lisp is effectively and rigorously > documented. For example, both the Elisp manual entry and the doc string > for cond are effective. > > There are people on this list who are using pcase like things, and so > clearly understand their syntax and semantics. Could these people > PLEASE document these things, and do so before the release of Emacs > 25.1. Preferably well before. It is indeed worth doing these things. Phil ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: The poor state of documentation of pcase like things. 2015-12-17 13:59 ` Phillip Lord @ 2015-12-17 17:06 ` Alan Mackenzie 0 siblings, 0 replies; 375+ messages in thread From: Alan Mackenzie @ 2015-12-17 17:06 UTC (permalink / raw) To: Phillip Lord; +Cc: emacs-devel Hello, Phillip. On Thu, Dec 17, 2015 at 01:59:56PM +0000, Phillip Lord wrote: > Alan Mackenzie <acm@muc.de> writes: > > Some of these doc strings are patronising indeed. They all seem to say, > > implicitly, "the author's time is far too valuable to waste in writing > > meaningful documentation". > I think it's probably better to make your points (which are reasonable) > without making such aspersions. The author in question has been > extremely generous with their time. I'm aware of this, and I'm not making any such asperesions. I'm merely trying to point out how these doc strings will be perceived by users, should they still be in their current state at the 25.1 release. [ .... ] > Phil -- Alan Mackenzie (Nuremberg, Germany). ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: The poor state of documentation of pcase like things. 2015-12-16 20:26 The poor state of documentation of pcase like things Alan Mackenzie ` (2 preceding siblings ...) 2015-12-17 13:59 ` Phillip Lord @ 2015-12-19 15:26 ` Michael Heerdegen 2015-12-19 16:04 ` Michael Heerdegen ` (2 more replies) 3 siblings, 3 replies; 375+ messages in thread From: Michael Heerdegen @ 2015-12-19 15:26 UTC (permalink / raw) To: Alan Mackenzie; +Cc: emacs-devel Alan Mackenzie <acm@muc.de> writes: > Hello, Emacs. Hello. (no, I'm not Emacs) > Months after recognising that the documentation of pcase like things > is in need of vast improvement, we haven't advanced significantly. I wished you had not raised this issue so shortly before Christmas. > We appear to have the following functions/macros: pcase, pcase-let, > pcase-let*, pcase-codegen, pcase-defmacro, pcase-dolist, > pcase-exhaustive, and pcase-lambda. > > NONE OF THESE, with the exception of pcase itself, IS EVEN MENTIONED IN > THE ELISP MANUAL. > > NONE OF THESE, with the exception of pcase itself, HAS A MEANINGFUL DOC > STRING. > > Some of these doc strings are patronising indeed. They all seem to say, > implicitly, "the author's time is far too valuable to waste in writing > meaningful documentation". As far as I understand how Stefan used to work, most of the semantics of most of the pcase derivatives, like `pcase-let', are not yet 100% fixed, we are not yet sure how useful we are, or if they may later be better be replaced by other forms that are more general, etc. IMHO it's good to leave the documentation of the derivatives as is for now. > What do "U" and "Q" stand for? > There are people on this list who are using pcase like things, and so > clearly understand their syntax and semantics. Could these people > PLEASE document these things, and do so before the release of Emacs > 25.1. Preferably well before. To be honest, I tweaked some of the pcase related documentation, and was quite happy with it. I think the pcase docstring is quite good. A tutorial is missing though, clearly. Michael. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: The poor state of documentation of pcase like things. 2015-12-19 15:26 ` Michael Heerdegen @ 2015-12-19 16:04 ` Michael Heerdegen 2015-12-19 19:29 ` Phillip Lord 2015-12-19 16:47 ` Eli Zaretskii 2015-12-19 18:30 ` Alan Mackenzie 2 siblings, 1 reply; 375+ messages in thread From: Michael Heerdegen @ 2015-12-19 16:04 UTC (permalink / raw) To: Alan Mackenzie; +Cc: emacs-devel Michael Heerdegen <michael_heerdegen@web.de> writes: > As far as I understand how Stefan used to work, most of the semantics of > most of the pcase derivatives, like `pcase-let', are not yet 100% fixed, > we are not yet sure how useful we are, or if they may later be better be > replaced by other forms that are more general, etc. BTW1, there is also a (not PATTERN) pattern form that already works but is not yet optimized, thus fully undocumented. BTW2, I discussed with Stefan the semantics of a `pcase-setq', and how it could be connected with generalized variables. BTW3, we were not yet all agreed how the semantics of `pcase-dolist' should be when the pattern doesn't match (currently, AFAIK, it loops nonetheless). Similarly for pcase-let and pcase-lambda. For some of these forms, we do not yet know how useful they are. Just some examples of open questions that shows that some stuff is still a bit of work in progress. Michael. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: The poor state of documentation of pcase like things. 2015-12-19 16:04 ` Michael Heerdegen @ 2015-12-19 19:29 ` Phillip Lord 2015-12-19 21:14 ` Michael Heerdegen 0 siblings, 1 reply; 375+ messages in thread From: Phillip Lord @ 2015-12-19 19:29 UTC (permalink / raw) To: Michael Heerdegen; +Cc: Alan Mackenzie, emacs-devel Michael Heerdegen <michael_heerdegen@web.de> writes: > Michael Heerdegen <michael_heerdegen@web.de> writes: > >> As far as I understand how Stefan used to work, most of the semantics of >> most of the pcase derivatives, like `pcase-let', are not yet 100% fixed, >> we are not yet sure how useful we are, or if they may later be better be >> replaced by other forms that are more general, etc. > > BTW3, we were not yet all agreed how the semantics of `pcase-dolist' > should be when the pattern doesn't match (currently, AFAIK, it loops > nonetheless). Similarly for pcase-let and pcase-lambda. For some of > these forms, we do not yet know how useful they are. pcase-lambda seems useful to me, seems to only take a single pattern, like so: (funcall (pcase-lambda (`(,x ,y)) y) '(1 2)) To me, it would be more useful if it supported multiple patterns. (funcall (pcase-lambda ((1) (message "Is a one")) (`(,_) (message "is a list"))) 1) The non-matching situation would then be in the hands of the user. Or it would be possible to make a "pcase-lambda-exhaustive" macro (probably with a better name". I'd also rename "pcase.el" to "p.el" but hey, that's a different story. > Just some examples of open questions that shows that some stuff is still > a bit of work in progress. One that's already getting quite a bit of use. Phil ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: The poor state of documentation of pcase like things. 2015-12-19 19:29 ` Phillip Lord @ 2015-12-19 21:14 ` Michael Heerdegen 2015-12-19 22:06 ` Phillip Lord 0 siblings, 1 reply; 375+ messages in thread From: Michael Heerdegen @ 2015-12-19 21:14 UTC (permalink / raw) To: Phillip Lord; +Cc: Alan Mackenzie, emacs-devel phillip.lord@russet.org.uk (Phillip Lord) writes: > I'd also rename "pcase.el" to "p.el" but hey, that's a different > story. and `pcase-let' to `plet' etc. A valid issue IMHO. Michael. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: The poor state of documentation of pcase like things. 2015-12-19 21:14 ` Michael Heerdegen @ 2015-12-19 22:06 ` Phillip Lord 0 siblings, 0 replies; 375+ messages in thread From: Phillip Lord @ 2015-12-19 22:06 UTC (permalink / raw) To: Michael Heerdegen; +Cc: Alan Mackenzie, emacs-devel Michael Heerdegen <michael_heerdegen@web.de> writes: > phillip.lord@russet.org.uk (Phillip Lord) writes: > >> I'd also rename "pcase.el" to "p.el" but hey, that's a different >> story. > > and `pcase-let' to `plet' etc. A valid issue IMHO. The standard would be "p-case" and "p-let" I think. A standard (short) suffix for "exhaustive" (which I interpret to mean "must match or error") would be nice also. That would make the entry points p-case p-let p-let* p-dolist p-lambda as well as p-case-ex p-let-ex and so on. Once the semantics of p-lambda is clear, it would probably also make sense to add "p-defun". And possibly "p-macro". Although this would then clash with the current "pcase-macro" which would naturally translate to p-macro also. So, I'd call this "p-defpattern". Against this, there is a slight concern about proliferation of single symbol packages (dash, s, f and the like) in the outside world. Phil ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: The poor state of documentation of pcase like things. 2015-12-19 15:26 ` Michael Heerdegen 2015-12-19 16:04 ` Michael Heerdegen @ 2015-12-19 16:47 ` Eli Zaretskii 2015-12-19 17:24 ` Michael Heerdegen 2015-12-22 5:25 ` John Wiegley 2015-12-19 18:30 ` Alan Mackenzie 2 siblings, 2 replies; 375+ messages in thread From: Eli Zaretskii @ 2015-12-19 16:47 UTC (permalink / raw) To: Michael Heerdegen; +Cc: acm, emacs-devel > From: Michael Heerdegen <michael_heerdegen@web.de> > Date: Sat, 19 Dec 2015 16:26:52 +0100 > Cc: emacs-devel@gnu.org > > As far as I understand how Stefan used to work, most of the semantics of > most of the pcase derivatives, like `pcase-let', are not yet 100% fixed, > we are not yet sure how useful we are, or if they may later be better be > replaced by other forms that are more general, etc. > > IMHO it's good to leave the documentation of the derivatives as is for > now. Grepping for "pcase-let" brings about 90 hits (including pcase-let*), so leaving that undocumented is no longer an option, IMO. > To be honest, I tweaked some of the pcase related documentation, and was > quite happy with it. I think the pcase docstring is quite good. Thank you for your efforts. > A tutorial is missing though, clearly. Tutorials are always good to have, but they cannot replace good documentation in the manual. We should strive to provide manuals that are self-contained and don't require any tutorial reading for acquiring a full understanding of an issue and an unimpeded capability of using it in Lisp programs. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: The poor state of documentation of pcase like things. 2015-12-19 16:47 ` Eli Zaretskii @ 2015-12-19 17:24 ` Michael Heerdegen 2015-12-22 5:25 ` John Wiegley 1 sibling, 0 replies; 375+ messages in thread From: Michael Heerdegen @ 2015-12-19 17:24 UTC (permalink / raw) To: Eli Zaretskii; +Cc: acm, emacs-devel Eli Zaretskii <eliz@gnu.org> writes: > > A tutorial is missing though, clearly. > > Tutorials are always good to have, but they cannot replace good > documentation in the manual. We should strive to provide manuals that > are self-contained and don't require any tutorial reading for > acquiring a full understanding of an issue and an unimpeded capability > of using it in Lisp programs. I agree. Michael. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: The poor state of documentation of pcase like things. 2015-12-19 16:47 ` Eli Zaretskii 2015-12-19 17:24 ` Michael Heerdegen @ 2015-12-22 5:25 ` John Wiegley 1 sibling, 0 replies; 375+ messages in thread From: John Wiegley @ 2015-12-22 5:25 UTC (permalink / raw) To: Eli Zaretskii; +Cc: Michael Heerdegen, acm, emacs-devel >>>>> Eli Zaretskii <eliz@gnu.org> writes: > Tutorials are always good to have, but they cannot replace good > documentation in the manual. We should strive to provide manuals that are > self-contained and don't require any tutorial reading for acquiring a full > understanding of an issue and an unimpeded capability of using it in Lisp > programs. Agreed. After I have absorbed all feedback on my proposed tutorial, I'll recast it into the language of the Elisp manual and include it there. -- John Wiegley GPG fingerprint = 4710 CF98 AF9B 327B B80F http://newartisans.com 60E1 46C4 BD1A 7AC1 4BA2 ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: The poor state of documentation of pcase like things. 2015-12-19 15:26 ` Michael Heerdegen 2015-12-19 16:04 ` Michael Heerdegen 2015-12-19 16:47 ` Eli Zaretskii @ 2015-12-19 18:30 ` Alan Mackenzie 2015-12-19 20:42 ` Michael Heerdegen 2 siblings, 1 reply; 375+ messages in thread From: Alan Mackenzie @ 2015-12-19 18:30 UTC (permalink / raw) To: Michael Heerdegen; +Cc: emacs-devel Hello, Michael. On Sat, Dec 19, 2015 at 04:26:52PM +0100, Michael Heerdegen wrote: > Alan Mackenzie <acm@muc.de> writes: > > Months after recognising that the documentation of pcase like things > > is in need of vast improvement, we haven't advanced significantly. > I wished you had not raised this issue so shortly before Christmas. My level of frustration and annoyance is steadily rising despite the imminence of Yuletide. I wish you a happy one, though. > > We appear to have the following functions/macros: pcase, pcase-let, > > pcase-let*, pcase-codegen, pcase-defmacro, pcase-dolist, > > pcase-exhaustive, and pcase-lambda. > > NONE OF THESE, with the exception of pcase itself, IS EVEN MENTIONED IN > > THE ELISP MANUAL. > > NONE OF THESE, with the exception of pcase itself, HAS A MEANINGFUL DOC > > STRING. > > Some of these doc strings are patronising indeed. They all seem to say, > > implicitly, "the author's time is far too valuable to waste in writing > > meaningful documentation". > As far as I understand how Stefan used to work, most of the semantics of > most of the pcase derivatives, like `pcase-let', are not yet 100% fixed, > we are not yet sure how useful we are, or if they may later be better be > replaced by other forms that are more general, etc. Yet the said functions have been committed on the release branch and are already in widespread use throughout the Emacs sources. As Eli notes, there're around 90 uses of pcase-let and pcase-let*. I count 18 occurrences of pcase-dolist outside of pcase.el. And so on. > IMHO it's good to leave the documentation of the derivatives as is for > now. They're essentially undocumented. That makes the code that uses them essentially unmaintainable, except by those who know, or are prepared to guess, what these functions do. I can't agree with you that this is good. > > What do "U" and "Q" stand for? > > There are people on this list who are using pcase like things, and so > > clearly understand their syntax and semantics. Could these people > > PLEASE document these things, and do so before the release of Emacs > > 25.1. Preferably well before. > To be honest, I tweaked some of the pcase related documentation, and was > quite happy with it. I think the pcase docstring is quite good. A > tutorial is missing though, clearly. The pcase docstring is getting better, yes. It stil doesn't document explicitly that the normal meanings of ` and , are suspended. There is still no explicit statement of what pcase's ` and , mean. Maybe I'm expecting too much, and ` and , have no intrinsic meanings in pcase. But I don't believe that is the case. > Michael. -- Alan Mackenzie (Nuremberg, Germany). ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: The poor state of documentation of pcase like things. 2015-12-19 18:30 ` Alan Mackenzie @ 2015-12-19 20:42 ` Michael Heerdegen 2015-12-19 22:25 ` Alan Mackenzie 0 siblings, 1 reply; 375+ messages in thread From: Michael Heerdegen @ 2015-12-19 20:42 UTC (permalink / raw) To: Alan Mackenzie; +Cc: emacs-devel Alan Mackenzie <acm@muc.de> writes: > I wish you a happy one, though. You too! > > As far as I understand how Stefan used to work, most of the semantics of > > most of the pcase derivatives, like `pcase-let', are not yet 100% fixed, > > we are not yet sure how useful we are, or if they may later be better be > > replaced by other forms that are more general, etc. > > Yet the said functions have been committed on the release branch I think Stefan used the term "don't advertise them yet too much" for such things. > and are already in widespread use throughout the Emacs sources. As > Eli notes, there're around 90 uses of pcase-let and pcase-let*. Could be they have nearly all been placed there by Stefan ;-) > They're essentially undocumented. That makes the code that uses them > essentially unmaintainable, except by those who know, or are prepared to > guess, what these functions do. I can't agree with you that this is > good. This can't be the final state, no doubt. It must be fixed. But we have to do it very carefully, and maybe not completely now: if even Stefan was not sure everywhere what could be written in the documentation and if the code makes much sense, let's not engrave in stone details we are not sure about whether they are true or intended or useful. This does not so much apply to `pcase-let' - I think it's quite clear what it does, though I didn't use it often myself. OTOH, I'm not so sure about `pcase-lambda' for example. How does/should a `pcase-lambda' behave when applied to something that it's "signature" doesn't match? Is it maybe cleaner to move a pcase call just inside the `lambda'? Is the semantics of pcase really the best thing one can use to hook pattern matching into a function, or is there a better one? In practice, only a subset of pcase semantics makes sense for `pcase-lambda' most of the time (mostly, destructuring), you can have "only one clause" contrary to `pcase' - is the resulting code readable?; is `pcase-lambda' a good abstraction/idea? If later we find it's a bad idea, it's not good if we advertise it too much in the manual, because we can't remove it so easily then. > The pcase docstring is getting better, yes. It stil doesn't document > explicitly that the normal meanings of ` and , are suspended. Mmh, but it also doesn't say that the normal meanings of and, or, ' and let are suspended. I think it doesn't have to, because a pcase pattern is not an expression that is evaluated, so symbols with known names can't have the same semantics as a pattern than as a defined function. > There is still no explicit statement of what pcase's ` and , mean. But do we agree that the current docstring completely explains the semantics, even if the definition is recursive? > Maybe I'm expecting too much, and ` and , have no intrinsic meanings in > pcase. But I don't believe that is the case. ``' is a pcase macro (at least now). pcase macros are like Lisp macros, but while Lisp macros expand to Lisp code, pcase macros expand to pcase patterns. The backquote macro ``' in Lisp is a utility that is used to build lists. pcase's ``' is used to build patterns that match lists. The only difference for unquoting (`,'), so to say, is that in the first case it "inserts" an arbitrary "value" at that position, and in the second case, "inserts" an arbitrary pcase pattern (that is responsible to match the element at that place, instead of being a specified constant that matches only itself via `equal'.) If you only unquote symbols, like in `(1 2 ,x) you can imagine that x is already bound to the "right" value, then the thing works much like the standard backquote. That analogy is not so useful for things like `(1 2 ,(pred stringp)) I guess, though you still can imagine that the pattern matches any three-element list whose first two elements are 1, 2, and as third element, anything that fulfills the predicate "stringp" can be "inserted". You can verify by yourself that elements in a backquoted list in pcase "behave" as if they were quoted with a quote (see the 'VAL form) - thus the name "QPattern" - and that the rules for quoted atoms apply as expected, and such things. [ While writing this, I see now that the doc of ``' in the pcase doc is a typical mathematical definition: it is absolutely correct, but doesn't say "what it's good for" and "how to use it". To be honest I also had much trouble to understand it when I learned `pcase'. ] BTW, there is no `,@' unquote splicing in pcase's backquote because it can lead to ambiguity when matching (and would be slow). Regards, Michael. ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: The poor state of documentation of pcase like things. 2015-12-19 20:42 ` Michael Heerdegen @ 2015-12-19 22:25 ` Alan Mackenzie 2015-12-20 13:11 ` Michael Heerdegen 0 siblings, 1 reply; 375+ messages in thread From: Alan Mackenzie @ 2015-12-19 22:25 UTC (permalink / raw) To: Michael Heerdegen; +Cc: emacs-devel Hello, Michael. On Sat, Dec 19, 2015 at 09:42:01PM +0100, Michael Heerdegen wrote: > Alan Mackenzie <acm@muc.de> writes: > > I wish you a happy one, though. > You too! Thanks! > > > As far as I understand how Stefan used to work, most of the semantics of > > > most of the pcase derivatives, like `pcase-let', are not yet 100% fixed, > > > we are not yet sure how useful we are, or if they may later be better be > > > replaced by other forms that are more general, etc. > > Yet the said functions have been committed on the release branch > I think Stefan used the term "don't advertise them yet too much" for > such things. > > and are already in widespread use throughout the Emacs sources. As > > Eli notes, there're around 90 uses of pcase-let and pcase-let*. > Could be they have nearly all been placed there by Stefan ;-) I think that's probable rather than possible. > > They're essentially undocumented. That makes the code that uses them > > essentially unmaintainable, except by those who know, or are prepared to > > guess, what these functions do. I can't agree with you that this is > > good. > This can't be the final state, no doubt. It must be fixed. Glad you agree. > But we have to do it very carefully, and maybe not completely now: if > even Stefan was not sure everywhere what could be written in the > documentation and if the code makes much sense, let's not engrave in > stone details we are not sure about whether they are true or intended or > useful. I don't really know what pcase-let does. I haven't a clue what pcase-lambda, pcase-defmacro, ... do. > This does not so much apply to `pcase-let' - I think it's quite clear > what it does, though I didn't use it often myself. It's not clear to me. I resent being forced to guess, read the pcase.el source, or give up on trying to understand significant portions of the Emacs source code. So, yes, I think `pcase-let' should be documented. > OTOH, I'm not so sure about `pcase-lambda' for example. How does/should > a `pcase-lambda' behave when applied to something that it's "signature" > doesn't match? Is it maybe cleaner to move a pcase call just inside the > `lambda'? Is the semantics of pcase really the best thing one can use > to hook pattern matching into a function, or is there a better one? In > practice, only a subset of pcase semantics makes sense for > `pcase-lambda' most of the time (mostly, destructuring), you can have > "only one clause" contrary to `pcase' - is the resulting code readable?; > is `pcase-lambda' a good abstraction/idea? If later we find it's a bad > idea, it's not good if we advertise it too much in the manual, because > we can't remove it so easily then. > > The pcase docstring is getting better, yes. It stil doesn't document > > explicitly that the normal meanings of ` and , are suspended. > Mmh, but it also doesn't say that the normal meanings of and, or, ' and > let are suspended. Good point. Perhaps it should say that about these symbols, too. And perhaps the entries in the Elisp manual for `and', `or', ``', `,', etc. should warn about the non-uniform meanings within pcase. The notion of kicking a wasp's nest springs to mind. > I think it doesn't have to, because a pcase pattern is not an > expression that is evaluated, so symbols with known names can't have > the same semantics as a pattern than as a defined function. That would be a good argument if only experts read the doc string. Thoroughly confused people also read doc strings. I don't think we should presuppose such sophisticated discernment in the typical reader. > > There is still no explicit statement of what pcase's ` and , mean. > But do we agree that the current docstring completely explains the > semantics, even if the definition is recursive? I don't agree. Completely missing is something like "pcase compares the value with each pattern in turn until one matches, and it then evaluates the corresponding BODY, returning the result of the last body form evaluated. If no pattern matches, nil is returned.". The somewhat offensive "perform ML-style pattern matching on that value" is no substitute for this. There is no mention of ``' and `,' in the section on patterns. Or is \\='VAL really meant to be \\=`VAL? > > Maybe I'm expecting too much, and ` and , have no intrinsic meanings in > > pcase. But I don't believe that is the case. > ``' is a pcase macro (at least now). pcase macros are like Lisp macros, > but while Lisp macros expand to Lisp code, pcase macros expand to pcase > patterns. > The backquote macro ``' in Lisp is a utility that is used to build > lists. pcase's ``' is used to build patterns that match lists. The > only difference for unquoting (`,'), so to say, is that in the first > case it "inserts" an arbitrary "value" at that position, and in the > second case, "inserts" an arbitrary pcase pattern (that is responsible to > match the element at that place, instead of being a specified constant > that matches only itself via `equal'.) But what does ``' _do_? What it normally does is well explained in its own doc string (which will need modification for pcase). But what does ``' _do_ within pcase? Saying "it is used to build patterns ...." is a cop out. The difficulty in describing its (and `,''s) semantics seems to be a weakness in pcase. > If you only unquote symbols, like in > `(1 2 ,x) > you can imagine that x is already bound to the "right" value, then the > thing works much like the standard backquote. That analogy is not so > useful for things like > `(1 2 ,(pred stringp)) > I guess, though you still can imagine that the pattern matches any > three-element list whose first two elements are 1, 2, and as third > element, anything that fulfills the predicate "stringp" can be > "inserted". > You can verify by yourself that elements in a backquoted list in pcase > "behave" as if they were quoted with a quote (see the 'VAL form) - thus > the name "QPattern" - and that the rules for quoted atoms apply as > expected, and such things. Are you saying that "QPattern" has no more conceptual meaning than "patterns which are backquoted"? > [ While writing this, I see now that the doc of ``' in the pcase doc is > a typical mathematical definition: it is absolutely correct, but > doesn't say "what it's good for" and "how to use it". To be honest I > also had much trouble to understand it when I learned `pcase'. ] I think I've got some reasonable partial understanding of ``', but I'm unhappy that there's no concise description of what it does. > BTW, there is no `,@' unquote splicing in pcase's backquote because it > can lead to ambiguity when matching (and would be slow). OK. > Regards, > Michael. -- Alan Mackenzie (Nuremberg, Germany). ^ permalink raw reply [flat|nested] 375+ messages in thread
* Re: The poor state of documentation of pcase like things. 2015-12-19 22:25 ` Alan Mackenzie @ 2015-12-20 13:11 ` Michael Heerdegen 0 siblings, 0 replies; 375+ messages in thread From: Michael Heerdegen @ 2015-12-20 13:11 UTC (permalink / raw) To: Alan Mackenzie; +Cc: emacs-devel Alan Mackenzie <acm@muc.de> writes: > I don't really know what pcase-let does. I haven't a clue what > pcase-lambda, pcase-defmacro, ... do. The doc of `pcase-defmacro' is very terse, but I find the docs of `pcase-lambda' and `pcase-let' understandable. What's wrong with these? > > Mmh, but it also doesn't say that the normal meanings of and, or, ' and > > let are suspended. > > I think it doesn't have to, because a pcase pattern is not an > > expression that is evaluated, so symbols with known names can't have > > the same semantics as a pattern than as a defined function. > > That would be a good argument if only experts read the doc string. > Thoroughly confused people also read doc strings. I don't think we > should presuppose such sophisticated discernment in the typical > reader. Ok, speaking it out is a good idea. But I would prefer the (improved) manual section. > > > There is still no explicit statement of what pcase's ` and , mean. > > > But do we agree that the current docstring completely explains the > > semantics, even if the definition is recursive? > > I don't agree. Completely missing is something like "pcase compares the > value with each pattern in turn until one matches, and it then evaluates > the corresponding BODY, returning the result of the last body form > evaluated. If no pattern matches, nil is returned.". The somewhat > offensive "perform ML-style pattern matching on that value" is no > substitute for this. I agree, but that is unrelated to backquote. > There is no mention of ``' and `,' in the section on patterns. Or is > \\='VAL really meant to be \\=`VAL? No. Since it's defined with `pcase-defmacro' now, it's listed later in the section describing all additional pattern types: ,---------------------------------------------------------------------- | -- `QPAT | | Backquote-style pcase patterns. | QPAT can take the following forms: | (QPAT1 . QPAT2) matches if QPAT1 matches the car and QPAT2 the cdr. | [QPAT1 QPAT2..QPATn] matches a vector of length n and QPAT1..QPATn match | its 0..(n-1)th elements, respectively. | ,PAT matches if the pcase pattern PAT matches. | ATOM matches if the object is ‘equal’ to ATOM. | ATOM can be a symbol, an integer, or a | string. `---------------------------------------------------------------------- Did you miss it all the time? > But what does ``' _do_? What it normally does is well explained in its > own doc string (which will need modification for pcase). No, pcase just uses the symbol ``'. What ``' "means" in pcase doesn't belong in the docstring of `backquote', those are two completely unrelated things, there is just some analogy (which led Stefan to use a backquote for the syntax). > Are you saying that "QPattern" has no more conceptual meaning than > "patterns which are backquoted"? That's were the name comes from. But the forms a QPAT can have are different from the "normal" pcase pattern types. See the -- `QPAT section I quoted. Regards, Michael. P.S. I'll be on a trip for the next two days in ~ two hours and will not be able to read this list in that time. ^ permalink raw reply [flat|nested] 375+ messages in thread
end of thread, other threads:[~2018-11-27 5:35 UTC | newest] Thread overview: 375+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2015-12-16 20:26 The poor state of documentation of pcase like things Alan Mackenzie 2015-12-16 20:53 ` Kaushal Modi 2015-12-17 16:34 ` John Wiegley 2015-12-17 19:22 ` Kaushal Modi 2015-12-17 21:16 ` Phillip Lord 2015-12-17 21:56 ` Drew Adams 2015-12-17 22:22 ` Phillip Lord 2015-12-18 7:15 ` Eli Zaretskii 2015-12-18 9:12 ` Rasmus 2015-12-18 9:21 ` Eli Zaretskii 2015-12-18 9:57 ` Rasmus 2015-12-18 10:13 ` David Kastrup 2015-12-18 10:47 ` Eli Zaretskii 2015-12-18 16:44 ` Phillip Lord 2015-12-18 17:17 ` Eli Zaretskii 2015-12-18 17:24 ` David Kastrup 2015-12-18 18:47 ` Eli Zaretskii 2015-12-19 11:23 ` Eli Zaretskii 2015-12-19 11:39 ` David Kastrup 2015-12-19 12:15 ` Eli Zaretskii 2015-12-19 20:35 ` Phillip Lord 2015-12-19 20:58 ` Eli Zaretskii 2015-12-19 22:23 ` Phillip Lord 2015-12-20 3:38 ` Eli Zaretskii 2015-12-20 22:54 ` Phillip Lord 2015-12-20 14:16 ` Michael Heerdegen 2015-12-18 12:23 ` Marcin Borkowski 2015-12-18 10:30 ` Phillip Lord 2015-12-18 12:21 ` Marcin Borkowski 2015-12-22 5:20 ` John Wiegley 2015-12-17 21:26 ` Alan Mackenzie 2015-12-17 23:34 ` John Wiegley 2015-12-18 7:16 ` Eli Zaretskii 2015-12-19 15:31 ` Michael Heerdegen 2015-12-22 5:25 ` John Wiegley 2015-12-22 13:16 ` Michael Heerdegen 2015-12-18 0:42 ` John Wiegley 2015-12-18 4:07 ` Richard Stallman 2015-12-18 10:39 ` Phillip Lord 2015-12-19 15:14 ` Michael Heerdegen 2015-12-19 19:23 ` Phillip Lord 2015-12-19 21:09 ` Michael Heerdegen 2015-12-19 21:57 ` Phillip Lord 2015-12-20 5:13 ` Richard Stallman 2015-12-20 9:25 ` Phillip Lord 2015-12-21 5:04 ` Richard Stallman 2015-12-21 10:15 ` Phillip Lord 2015-12-22 5:18 ` John Wiegley 2015-12-20 13:45 ` Michael Heerdegen 2015-12-20 13:33 ` Michael Heerdegen 2015-12-20 18:51 ` Phillip Lord 2015-12-24 17:46 ` Michael Heerdegen 2015-12-24 17:51 ` John Wiegley 2015-12-24 19:10 ` Michael Heerdegen 2015-12-19 19:24 ` Phillip Lord 2015-12-18 8:55 ` Eli Zaretskii 2015-12-19 15:18 ` Michael Heerdegen 2015-12-22 5:22 ` John Wiegley 2015-12-19 15:55 ` Michael Heerdegen 2015-12-19 17:08 ` Eli Zaretskii 2015-12-19 17:19 ` Eli Zaretskii 2015-12-19 21:03 ` Michael Heerdegen 2015-12-19 17:40 ` Michael Heerdegen 2015-12-22 5:21 ` John Wiegley 2015-12-19 15:44 ` Michael Heerdegen 2015-12-19 17:02 ` Eli Zaretskii 2015-12-19 20:58 ` Michael Heerdegen 2015-12-22 5:28 ` John Wiegley 2015-12-19 20:31 ` Phillip Lord 2015-12-19 21:16 ` Michael Heerdegen 2015-12-19 22:11 ` Phillip Lord 2015-12-20 12:45 ` Michael Heerdegen 2015-12-24 5:49 ` Richard Stallman 2015-12-24 6:15 ` John Wiegley 2015-12-25 5:49 ` Richard Stallman 2015-12-25 14:59 ` Michael Heerdegen 2015-12-25 16:55 ` John Wiegley 2015-12-26 6:13 ` Richard Stallman 2015-12-26 17:10 ` Michael Heerdegen 2015-12-26 20:52 ` Aaron Ecay 2015-12-26 23:17 ` Michael Heerdegen 2016-01-01 7:57 ` Eli Zaretskii 2016-01-01 17:46 ` John Wiegley 2016-01-01 18:39 ` David Kastrup 2016-01-01 19:05 ` Daniel Colascione 2016-01-02 8:16 ` Eli Zaretskii 2016-01-02 8:35 ` David Kastrup 2016-01-03 0:19 ` Michael Heerdegen 2016-01-03 2:47 ` Drew Adams 2016-01-03 3:21 ` Michael Heerdegen 2016-01-03 3:46 ` Drew Adams 2016-01-03 5:17 ` Michael Heerdegen 2016-01-03 3:45 ` Eli Zaretskii 2016-01-03 4:21 ` Michael Heerdegen 2016-01-03 9:13 ` David Kastrup 2016-01-03 16:52 ` Clément Pit--Claudel 2016-01-04 1:28 ` Michael Heerdegen 2016-01-03 15:29 ` Eli Zaretskii 2016-01-04 2:05 ` Michael Heerdegen 2016-01-03 9:03 ` David Kastrup 2016-01-04 2:08 ` Michael Heerdegen 2016-01-04 22:05 ` John Wiegley 2016-01-03 0:41 ` Dmitry Gutov 2016-01-03 1:07 ` Lars Magne Ingebrigtsen 2016-01-03 1:21 ` Dmitry Gutov 2016-01-03 2:49 ` Drew Adams 2016-01-03 10:49 ` David Kastrup 2016-01-03 1:32 ` Michael Heerdegen 2016-01-03 2:48 ` Drew Adams 2016-01-03 3:11 ` Noam Postavsky 2016-01-03 3:18 ` Dmitry Gutov 2016-01-03 3:55 ` John Wiegley 2016-01-03 3:45 ` Drew Adams 2016-01-03 3:47 ` Eli Zaretskii [not found] ` <56889EC3.3040108@yandex.ru> [not found] ` <877fjrkpdf.fsf@fencepost.gnu.org> [not found] ` <56892334.4000106@yandex.ru> [not found] ` <8760zakb7q.fsf@fencepost.gnu.org> [not found] ` <56892BDA.6060103@dancol.org> [not found] ` <871t9yk98g.fsf@fencepost.gnu.org> [not found] ` <568936F0.3060505@yandex.ru> [not found] ` <87wprqitj5.fsf@fencepost.gnu.org> [not found] ` <56893C8C.3060200@yandex.ru> 2016-01-03 15:52 ` David Kastrup 2016-01-03 15:59 ` Dmitry Gutov 2016-01-03 17:15 ` David Kastrup 2016-01-03 17:52 ` Dmitry Gutov 2016-01-03 18:17 ` David Kastrup 2016-01-04 2:34 ` Michael Heerdegen 2016-01-04 6:19 ` Drew Adams 2016-01-04 22:07 ` John Wiegley 2016-01-04 15:52 ` Eli Zaretskii 2018-10-23 13:04 ` Replace trivial pcase occurrences in the Emacs sources (was: The poor state of documentation of pcase like things.) Michael Heerdegen 2018-10-23 14:43 ` Clément Pit-Claudel 2018-10-23 14:46 ` Replace trivial pcase occurrences in the Emacs sources Michael Heerdegen 2018-10-23 14:57 ` Clément Pit-Claudel 2018-10-23 15:16 ` Michael Heerdegen 2018-10-23 15:07 ` Noam Postavsky 2018-10-23 15:24 ` Michael Heerdegen 2018-10-23 15:31 ` Noam Postavsky 2018-10-24 13:15 ` Michael Heerdegen 2018-10-23 15:17 ` Replace trivial pcase occurrences in the Emacs sources (was: The poor state of documentation of pcase like things.) Eli Zaretskii 2018-10-23 17:14 ` Replace trivial pcase occurrences in the Emacs sources Stefan Monnier 2018-10-23 17:24 ` Michael Heerdegen 2018-10-23 18:12 ` Stefan Monnier 2018-10-23 19:52 ` pcase vs. case (where it could also be used) [Was: Re: Replace trivial pcase occurrences in the Emacs sources] Garreau, Alexandre 2018-10-23 20:19 ` Stefan Monnier 2018-10-23 22:24 ` Garreau, Alexandre 2018-10-24 15:03 ` Replace trivial pcase occurrences in the Emacs sources Eli Zaretskii 2018-10-24 15:30 ` Michael Heerdegen 2018-10-24 15:40 ` Eli Zaretskii 2018-10-24 15:48 ` Michael Heerdegen 2018-10-24 17:35 ` Eli Zaretskii 2018-10-24 17:55 ` Michael Heerdegen 2018-10-24 18:32 ` Eli Zaretskii 2018-10-24 18:47 ` Garreau, Alexandre 2018-10-27 15:19 ` Michael Heerdegen 2018-10-27 16:56 ` Garreau, Alexandre 2018-10-27 22:37 ` Dmitry Gutov 2018-10-28 0:21 ` Michael Heerdegen 2018-10-28 2:07 ` Garreau, Alexandre 2018-10-28 2:44 ` pcase ` meaning [Was: Re: Replace trivial pcase occurrences in the Emacs sources] Garreau, Alexandre 2018-10-28 4:45 ` How other pattern-matching lisps do [Was: Re: pcase ` meaning [Was: Re: Replace trivial pcase occurrences in the Emacs sources]] Garreau, Alexandre 2018-10-28 13:44 ` Stefan Monnier 2018-10-28 17:57 ` Garreau, Alexandre 2018-10-28 23:16 ` Michael Heerdegen 2018-10-28 22:54 ` pcase ` meaning [Was: Re: Replace trivial pcase occurrences in the Emacs sources] Michael Heerdegen 2018-10-28 23:09 ` Garreau, Alexandre 2018-10-28 23:57 ` Michael Heerdegen 2018-10-29 10:22 ` Garreau, Alexandre 2018-10-29 21:33 ` Michael Heerdegen 2018-10-29 23:00 ` pcase ` meaning Garreau, Alexandre 2018-10-29 23:57 ` Michael Heerdegen 2018-10-30 0:17 ` Garreau, Alexandre 2018-10-30 1:40 ` Michael Heerdegen 2018-10-30 16:05 ` Yuri Khan 2018-10-29 17:26 ` pcase ` meaning [Was: Re: Replace trivial pcase occurrences in the Emacs sources] Clément Pit-Claudel 2018-10-30 0:27 ` pcase ` meaning Garreau, Alexandre 2018-10-30 13:14 ` Stefan Monnier 2018-10-31 23:13 ` Garreau, Alexandre 2018-11-01 13:22 ` Clément Pit-Claudel 2018-11-01 14:11 ` Garreau, Alexandre 2018-10-29 3:26 ` Replace trivial pcase occurrences in the Emacs sources Eli Zaretskii 2018-10-29 21:46 ` Michael Heerdegen 2018-10-30 0:36 ` What `case' have done you? [Was: Re: Replace trivial pcase occurrences in the Emacs sources] Garreau, Alexandre 2018-10-30 1:45 ` Michael Heerdegen 2018-10-30 6:31 ` Replace trivial pcase occurrences in the Emacs sources Eli Zaretskii 2018-10-30 15:47 ` Michael Heerdegen 2018-10-30 17:29 ` Eli Zaretskii 2018-10-30 22:09 ` Michael Heerdegen 2018-10-31 15:59 ` Eli Zaretskii 2018-10-31 19:37 ` Stefan Monnier 2018-10-31 20:31 ` Michael Heerdegen 2018-10-31 23:33 ` Garreau, Alexandre 2018-10-31 23:44 ` Garreau, Alexandre 2018-10-31 23:58 ` Michael Heerdegen 2018-11-01 4:15 ` Eli Zaretskii 2018-11-01 12:30 ` Stefan Monnier 2018-11-01 14:14 ` Michael Heerdegen 2018-11-01 14:18 ` Noam Postavsky 2018-11-01 14:20 ` Michael Heerdegen 2018-11-05 1:43 ` Michael Heerdegen 2018-11-05 1:46 ` Michael Heerdegen 2018-11-05 16:06 ` Eli Zaretskii 2018-11-06 1:04 ` Michael Heerdegen 2018-11-25 20:36 ` Michael Heerdegen 2018-11-25 20:42 ` Nicolas Goaziou 2018-11-25 21:46 ` Michael Heerdegen 2018-11-26 3:35 ` Eli Zaretskii 2018-11-26 20:57 ` Michael Heerdegen 2018-11-26 22:05 ` Nicolas Goaziou 2018-11-27 5:35 ` Eli Zaretskii 2018-10-24 15:47 ` Clément Pit-Claudel 2018-10-24 16:00 ` Eli Zaretskii 2018-10-24 19:00 ` Clément Pit-Claudel 2018-10-24 19:09 ` Eli Zaretskii 2018-10-24 16:12 ` Alan Mackenzie 2018-10-24 20:52 ` Stefan Monnier 2018-10-25 7:17 ` Stephen Berman 2018-10-25 14:47 ` Eli Zaretskii 2018-10-25 15:32 ` Stefan Monnier 2018-10-26 15:34 ` Stefan Monnier 2018-10-27 17:48 ` Garreau, Alexandre 2018-10-24 4:51 ` Richard Stallman 2018-10-24 8:34 ` Joost Kremers 2018-10-24 12:37 ` Stefan Monnier 2018-10-24 13:08 ` Daniel Pittman 2018-10-24 14:35 ` Stefan Monnier 2018-10-24 13:03 ` pcase pattern syntax (was: Replace trivial pcase occurrences in the Emacs sources) Stefan Monnier 2018-10-26 7:16 ` Joost Kremers 2018-10-24 10:16 ` Replace trivial pcase occurrences in the Emacs sources João Távora 2018-10-24 13:05 ` Stefan Monnier 2018-10-25 3:11 ` Richard Stallman 2018-10-25 12:42 ` Stefan Monnier 2018-10-25 23:53 ` Andy Moreton 2018-10-26 14:59 ` Stefan Monnier 2018-10-26 15:44 ` Garreau, Alexandre 2018-10-27 12:09 ` Andy Moreton 2018-10-28 21:44 ` Stefan Monnier 2018-10-29 13:01 ` Alan Mackenzie 2018-10-29 13:28 ` Stefan Monnier 2018-10-29 13:47 ` Alan Mackenzie 2018-10-29 21:08 ` Stefan Monnier 2018-10-29 21:53 ` Michael Heerdegen 2018-10-29 23:12 ` Eric Abrahamsen 2018-10-29 23:18 ` Eric Abrahamsen 2018-10-30 0:50 ` `pcase'/`case' implementation [Was: Re: Replace trivial pcase occurrences in the Emacs sources] Garreau, Alexandre 2018-10-30 13:07 ` Replace trivial pcase occurrences in the Emacs sources Stefan Monnier 2018-10-30 23:30 ` Eric Abrahamsen 2018-11-01 0:16 ` Garreau, Alexandre 2018-10-30 12:30 ` Stefan Monnier 2018-10-30 17:16 ` Stefan Monnier 2018-10-30 19:03 ` Eli Zaretskii 2018-10-30 19:21 ` Stefan Monnier 2018-10-30 19:54 ` Eli Zaretskii 2018-10-30 20:44 ` Stefan Monnier 2018-10-31 15:57 ` Eli Zaretskii 2018-10-31 19:35 ` Stefan Monnier 2018-11-01 1:40 ` Garreau, Alexandre 2018-11-01 4:10 ` Eli Zaretskii 2018-11-01 5:21 ` Garreau, Alexandre 2018-11-01 18:07 ` Eli Zaretskii 2018-11-01 19:35 ` Garreau, Alexandre 2018-11-01 19:49 ` TEIRLLM 2018-11-03 2:53 ` Richard Stallman 2018-11-04 11:35 ` Nix 2018-11-04 12:40 ` Garreau, Alexandre 2018-11-01 19:51 ` TEIRLLM 2018-11-01 20:02 ` Eli Zaretskii 2018-10-30 20:04 ` Dmitry Gutov 2018-10-30 20:46 ` Stefan Monnier 2018-10-31 13:41 ` Dmitry Gutov 2018-10-31 13:52 ` Stefan Monnier 2018-10-31 15:50 ` Eli Zaretskii 2018-10-31 16:05 ` Dmitry Gutov 2018-10-31 16:13 ` Eli Zaretskii 2018-10-31 16:27 ` Dmitry Gutov 2018-10-31 16:33 ` Dmitry Gutov 2018-10-31 16:54 ` Eli Zaretskii 2018-10-31 16:58 ` Dmitry Gutov 2018-10-31 16:52 ` Eli Zaretskii 2018-10-31 18:55 ` Michael Heerdegen 2018-10-31 19:23 ` Eli Zaretskii 2018-10-31 19:50 ` Michael Heerdegen 2018-10-31 20:05 ` Eli Zaretskii 2018-10-31 20:41 ` Michael Heerdegen 2018-11-01 4:14 ` Eli Zaretskii 2018-10-31 20:06 ` Stefan Monnier 2018-10-31 20:12 ` Eli Zaretskii 2018-10-31 17:48 ` Clément Pit-Claudel 2018-10-31 18:11 ` Eli Zaretskii 2018-10-31 18:28 ` Clément Pit-Claudel 2018-10-31 18:33 ` Eli Zaretskii 2018-10-31 19:00 ` Yuri Khan 2018-10-31 19:20 ` Eli Zaretskii 2018-11-01 0:11 ` Dmitry Gutov 2018-10-31 19:21 ` Clément Pit-Claudel 2018-10-31 19:29 ` Eli Zaretskii 2018-10-31 19:31 ` Clément Pit-Claudel 2018-10-31 20:36 ` Eli Zaretskii 2018-11-01 0:13 ` Dmitry Gutov 2018-11-01 1:31 ` Garreau, Alexandre 2018-10-31 20:03 ` Stefan Monnier 2018-11-01 0:07 ` Dmitry Gutov 2018-11-01 1:34 ` Garreau, Alexandre 2018-11-03 13:15 ` Eli Zaretskii 2018-10-30 1:15 ` Garreau, Alexandre 2018-10-30 6:17 ` Eli Zaretskii 2018-10-30 12:15 ` Stefan Monnier 2018-10-30 12:38 ` Eli Zaretskii 2018-10-30 15:00 ` Stefan Monnier 2018-10-30 17:00 ` Eli Zaretskii 2018-10-30 17:27 ` Stefan Monnier 2018-10-30 17:36 ` Eli Zaretskii 2018-10-30 18:09 ` Stefan Monnier 2018-10-30 18:42 ` Eli Zaretskii 2018-10-30 18:58 ` Stefan Monnier 2018-10-31 12:08 ` Alan Mackenzie 2018-10-31 12:33 ` Stefan Monnier 2018-10-31 15:47 ` Eli Zaretskii 2018-10-31 16:07 ` Alan Mackenzie 2018-10-31 16:20 ` Eli Zaretskii 2018-11-01 8:36 ` Achim Gratz 2018-11-01 10:36 ` Alan Mackenzie 2018-11-01 12:29 ` Achim Gratz 2018-11-01 14:19 ` Michael Heerdegen 2018-11-03 13:16 ` Eli Zaretskii 2018-11-03 15:45 ` Michael Heerdegen 2018-11-03 16:25 ` Eli Zaretskii 2018-11-03 17:12 ` Michael Heerdegen 2018-11-03 17:55 ` Eli Zaretskii 2018-11-03 22:22 ` Michael Heerdegen 2018-11-04 14:16 ` Eli Zaretskii 2018-11-06 0:00 ` Michael Heerdegen 2018-11-06 3:30 ` Eli Zaretskii 2018-11-03 13:13 ` Eli Zaretskii 2018-10-30 18:24 ` Alan Mackenzie 2018-10-30 14:16 ` Andy Moreton 2018-10-30 15:05 ` Clément Pit-Claudel 2018-10-30 18:14 ` Alan Mackenzie 2018-10-30 19:56 ` Clément Pit-Claudel 2018-10-31 0:08 ` Andy Moreton 2018-10-31 3:19 ` Stefan Monnier 2018-10-31 16:23 ` Clément Pit-Claudel 2018-11-01 14:44 ` Andy Moreton 2018-11-01 15:28 ` Clément Pit-Claudel 2018-10-30 17:22 ` Michael Heerdegen 2018-10-30 17:31 ` Stefan Monnier 2018-10-30 23:08 ` Michael Heerdegen 2018-10-31 3:09 ` Stefan Monnier 2018-11-05 2:01 ` Michael Heerdegen 2018-11-05 4:49 ` Stefan Monnier 2018-11-05 23:06 ` Michael Heerdegen 2018-10-30 18:09 ` Alan Mackenzie 2018-10-30 18:17 ` Stefan Monnier 2018-10-30 19:00 ` Alan Mackenzie 2018-10-31 0:21 ` Andy Moreton 2018-10-29 14:47 ` Andy Moreton 2018-10-29 18:49 ` pcase-lambda usage [Was: Re: Replace trivial pcase occurrences in the Emacs sources] Garreau, Alexandre 2018-10-30 23:34 ` Replace trivial pcase occurrences in the Emacs sources Van L 2018-10-31 3:14 ` Stefan Monnier 2018-10-23 17:22 ` John Wiegley 2018-10-23 17:16 ` Stefan Monnier 2016-01-04 2:54 ` The poor state of documentation of pcase like things Michael Heerdegen 2016-01-02 1:15 ` Richard Copley 2016-01-02 3:50 ` Drew Adams 2016-01-02 3:51 ` Drew Adams [not found] ` <<83y4c9ag06.fsf@gnu.org> 2016-01-01 15:18 ` Drew Adams 2015-12-27 2:53 ` Richard Stallman 2015-12-16 21:01 ` Drew Adams 2015-12-17 13:59 ` Phillip Lord 2015-12-17 17:06 ` Alan Mackenzie 2015-12-19 15:26 ` Michael Heerdegen 2015-12-19 16:04 ` Michael Heerdegen 2015-12-19 19:29 ` Phillip Lord 2015-12-19 21:14 ` Michael Heerdegen 2015-12-19 22:06 ` Phillip Lord 2015-12-19 16:47 ` Eli Zaretskii 2015-12-19 17:24 ` Michael Heerdegen 2015-12-22 5:25 ` John Wiegley 2015-12-19 18:30 ` Alan Mackenzie 2015-12-19 20:42 ` Michael Heerdegen 2015-12-19 22:25 ` Alan Mackenzie 2015-12-20 13:11 ` Michael Heerdegen
Code repositories for project(s) associated with this public inbox https://git.savannah.gnu.org/cgit/emacs.git 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).