* Instead of pcase @ 2023-11-16 3:04 Richard Stallman 2023-11-16 7:37 ` Philip Kaludercic ` (4 more replies) 0 siblings, 5 replies; 342+ messages in thread From: Richard Stallman @ 2023-11-16 3:04 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. ]]] `pcase' is a big and unnecessary complication on Emacs Lisp. I think its presence worse overall. One can easily think of `pcase' as "just another feature", like each of the thousands of other predefined functions and macros in Emacs Lisp. But that picture is incorrect for `pcase', because it does not count the cost of `pcase' in complexity. What makes `pcase' such a complication is that it introduces an additional "little language" that duplicates the functionality of part of Emacs Lisp. Even worse, that little language is so concise it is downright cryptic. I can see why people want something along those lines. Using `cond' and `let' to do these jobs feels long-winded and cumbersome; they were not designed to make this easy. So we wish for something to make such code more concise. `pcase' does indeed make such code more concise, but it takes that conciseness to an extreme by defining its own cryptic little language, That is going too far. Using `pcase' in your own private code concerns you alone. Using it in released packages that others use but others rarely change or study is not a big deal for the community. However, putting `pcase' into many packages imposes this cryptic little language on all of us. There are other little languages in Emacs, but most of them are limited to special high-level purposes -- which means that hardly any of us need even be aware of them. For instance, there is a little language called "quail" which is used for concisely defining input methods. Its specific purpose is a high-level purpose. If you don't work on input methods you never need to learn quail. It's just the opposite for `pcase' -- its specific purpose is a low-level purpose, so it could appear in any part of the code of Emacs, The burden of its complexity can fall on any or all of us. Those of you who are fans of `pcase' may not recognize the cost it imposes on the Emacs Lisp language. You paid that cost already, perhaps a few years ago, and perhaps you enjoy each new language construct you learn. Perhaps, for you, the more complexity of features to be learned, the better. But don't argue that this cost does not exist, simply because it doesn't feel like a burden to you. So... I'm looking at adapting some of the features of `pcase' into other constructs, so as to make type-discrimination code more concise than in old-fashioned Lisp, but _not_ so concise as to be cryptic and burdensome. -- Dr Richard Stallman (https://stallman.org) Chief GNUisance of the GNU Project (https://gnu.org) Founder, Free Software Foundation (https://fsf.org) Internet Hall-of-Famer (https://internethalloffame.org) ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-11-16 3:04 Instead of pcase Richard Stallman @ 2023-11-16 7:37 ` Philip Kaludercic 2023-11-16 17:18 ` T.V Raman 2023-11-26 3:17 ` Richard Stallman 2023-11-16 15:06 ` Michael Heerdegen ` (3 subsequent siblings) 4 siblings, 2 replies; 342+ messages in thread From: Philip Kaludercic @ 2023-11-16 7:37 UTC (permalink / raw) To: Richard Stallman; +Cc: emacs-devel Richard Stallman <rms@gnu.org> writes: > I can see why people want something along those lines. Using `cond' > and `let' to do these jobs feels long-winded and cumbersome; they were > not designed to make this easy. So we wish for something to make such > code more concise. [...] > I'm looking at adapting some of the features of `pcase' into other > constructs, so as to make type-discrimination code more concise than > in old-fashioned Lisp, but _not_ so concise as to be cryptic and > burdensome. The critical feature of pcase is pattern matching. The complexity of `pcase' is the extensibility -- a lisp-like flexibility that makes it so attractive -- that a simpler macro might not need. The question is, if one would restrict pcase to just matching expressions using ` and , like (pcase sexp ;match various top-level constructs (`(defun ,name ,args ,body) ...) (`(defvar ,name, ,value) ...) (`(require ',symbol) ...) ...) would that be simple enough in your opinion? Anyone familiar with ML-style functional programming, Prolog or the notion of unification should be able to understand this quickly enough, I assume? ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-11-16 7:37 ` Philip Kaludercic @ 2023-11-16 17:18 ` T.V Raman 2023-11-16 17:44 ` Michael Heerdegen ` (2 more replies) 2023-11-26 3:17 ` Richard Stallman 1 sibling, 3 replies; 342+ messages in thread From: T.V Raman @ 2023-11-16 17:18 UTC (permalink / raw) To: Philip Kaludercic; +Cc: Richard Stallman, emacs-devel Philip Kaludercic <philipk@posteo.net> writes: RMS' message makes some very valuable points re specialized languages like pcase -- pcase has its strengths, but in general, it's definitely not easy to understand complex code that leverages it -- as an example: I recently tried to understand some of the completion code; -- specifically, completion-at-point, and immediately hit the pcase wall and gave up --- my lack of understanding of pcase made that code in Emacs Core read like line-noise. > Richard Stallman <rms@gnu.org> writes: > >> I can see why people want something along those lines. Using `cond' >> and `let' to do these jobs feels long-winded and cumbersome; they were >> not designed to make this easy. So we wish for something to make such >> code more concise. > > [...] > >> I'm looking at adapting some of the features of `pcase' into other >> constructs, so as to make type-discrimination code more concise than >> in old-fashioned Lisp, but _not_ so concise as to be cryptic and >> burdensome. > > The critical feature of pcase is pattern matching. The complexity of > `pcase' is the extensibility -- a lisp-like flexibility that makes it so > attractive -- that a simpler macro might not need. The question is, if > one would restrict pcase to just matching expressions using ` and , like > > (pcase sexp ;match various top-level constructs > (`(defun ,name ,args ,body) ...) > (`(defvar ,name, ,value) ...) > (`(require ',symbol) ...) > ...) > > would that be simple enough in your opinion? Anyone familiar with > ML-style functional programming, Prolog or the notion of unification > should be able to understand this quickly enough, I assume? > -- ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-11-16 17:18 ` T.V Raman @ 2023-11-16 17:44 ` Michael Heerdegen 2023-11-16 18:16 ` Philip Kaludercic 2023-11-16 19:19 ` Instead of pcase Eli Zaretskii 2023-11-16 18:21 ` Dmitry Gutov 2023-11-16 23:41 ` Emanuel Berg 2 siblings, 2 replies; 342+ messages in thread From: Michael Heerdegen @ 2023-11-16 17:44 UTC (permalink / raw) To: emacs-devel "T.V Raman" <raman@google.com> writes: > I recently tried to understand some of the completion code; -- > specifically, completion-at-point, and immediately hit the pcase wall > and gave up --- my lack of understanding of pcase made that code in > Emacs Core read like line-noise. But that pcase form is only performing trivial destructuring. Only that, nothing more. If you can read backquote expressions, you can read that with exactly the same ease. Michael. ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-11-16 17:44 ` Michael Heerdegen @ 2023-11-16 18:16 ` Philip Kaludercic 2023-11-17 8:54 ` Complex SPEC for variables/customization like font-lock-keywords/org-capture-templates/etc (was: Instead of pcase) Ihor Radchenko 2023-11-16 19:19 ` Instead of pcase Eli Zaretskii 1 sibling, 1 reply; 342+ messages in thread From: Philip Kaludercic @ 2023-11-16 18:16 UTC (permalink / raw) To: Michael Heerdegen; +Cc: emacs-devel Michael Heerdegen <michael_heerdegen@web.de> writes: > "T.V Raman" <raman@google.com> writes: > >> I recently tried to understand some of the completion code; -- >> specifically, completion-at-point, and immediately hit the pcase wall >> and gave up --- my lack of understanding of pcase made that code in >> Emacs Core read like line-noise. > > But that pcase form is only performing trivial destructuring. Only > that, nothing more. If you can read backquote expressions, you can read > that with exactly the same ease. Right, and if one wouldn't use it to destruct values, you'd end up with a lot more boiler-plate code that would be harder to maintain and more to read. If one has to talk about difficult to understand/remember domain specific languages, then `font-lock-defaults' would be a much more pressing candidate. > Michael. ^ permalink raw reply [flat|nested] 342+ messages in thread
* Complex SPEC for variables/customization like font-lock-keywords/org-capture-templates/etc (was: Instead of pcase) 2023-11-16 18:16 ` Philip Kaludercic @ 2023-11-17 8:54 ` Ihor Radchenko 2023-11-25 4:03 ` Complex SPEC for variables/customization like font-lock-keywords/org-capture-templates/etc Stefan Monnier 0 siblings, 1 reply; 342+ messages in thread From: Ihor Radchenko @ 2023-11-17 8:54 UTC (permalink / raw) To: Philip Kaludercic; +Cc: Michael Heerdegen, emacs-devel Philip Kaludercic <philipk@posteo.net> writes: > Michael Heerdegen <michael_heerdegen@web.de> writes: > > ... If one has to talk about difficult to understand/remember > domain specific languages, then `font-lock-defaults' would be a much > more pressing candidate. Or font-lock-keywords... Last time I were seriously developing new keywords, I had to do it by trial-and-error and even examine font-lock sources. We also have similar issues with complex specifications in Org mode - org-capture-templates, org-agenda-custom-commands, etc. I believe that it is a general problem relevant various non-trivial variables/customization we have across Emacs and Emacs packages - developers, or, more frequently, Emacs users have significant difficulties understanding the obscure ad-hoc languages we have to invent for font-locking, templates, etc. The most common confusions are related to: 1. Quoting deeply nested lists 2. Keeping track of what each of the list elements refers to. For example, font-lock-keywords may contain something like (lisp--match-hidden-arg (0 '(face font-lock-warning-face help-echo "Easy to misread; consider moving the element to the next line") prepend)) It is hard to parse without constantly examining the docstring. Customize interface somewhat helps with (2), but many users avoid it and instead prefer to write init.el manually. Also, developers cannot even use customize interface (for example when developing font-lock-keywords). (1) is also a rather common problem, especially when both quoted and unquoted version of a list element are technically valid (for example, consider 'face-name vs. face-name in font-lock-keywords - a rather common confusion for me). I do not know a good solution to the above, and thus would like to discuss this problem. Some possible ideas: 1. Provide some universal mechanism for type-validation of variables. Something similar to :type spec in defcustom, but for Elisp variables. This will at least catch invalid values. 2. Provide custom warning mechanism catching common mistakes in the variables SPEC. For example, 'face-name vs. face-name for font-lock-keywords in the above example. 3. Enhance eldoc to show a tip about variable value structure, similar to what is done for function arguments. -- Ihor Radchenko // yantar92, Org mode contributor, Learn more about Org mode at <https://orgmode.org/>. Support Org development at <https://liberapay.com/org-mode>, or support my work at <https://liberapay.com/yantar92> ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Complex SPEC for variables/customization like font-lock-keywords/org-capture-templates/etc 2023-11-17 8:54 ` Complex SPEC for variables/customization like font-lock-keywords/org-capture-templates/etc (was: Instead of pcase) Ihor Radchenko @ 2023-11-25 4:03 ` Stefan Monnier 0 siblings, 0 replies; 342+ messages in thread From: Stefan Monnier @ 2023-11-25 4:03 UTC (permalink / raw) To: emacs-devel; +Cc: monnier > Or font-lock-keywords... Last time I were seriously developing new > keywords, I had to do it by trial-and-error and even examine > font-lock sources. [...] > I do not know a good solution to the above, and thus would like to > discuss this problem. > > Some possible ideas: > > 1. Provide some universal mechanism for type-validation of variables. > Something similar to :type spec in defcustom, but for Elisp > variables. This will at least catch invalid values. IME, the problem usually stems from a confusion between code and data: `font-lock-keywords` should hold code (i.e. something like a function) rather than nested-lists-with-special-structure. We could then provide some kind of macro to make it easier to define these functions. That's what I tried to do with `syntax-propertize-rules`, which is otherwise very similar to the previous `font-lock-syntactic-keywords`. That's also what I did with `bindat-type`. This has the advantage that the macro can make various sanity checks (and hence detect some of the possible errors), and that we can (to some extent) Edebug the result. I intended to try and provide a similar replacement facility for `font-lock-keywords`, but haven't gotten to it. > 3. Enhance eldoc to show a tip about variable value structure, similar > to what is done for function arguments. It doesn't really work for `bindat-type`, but the use of macros should make it easier because the code tells us reliably that this is a Bindat type whereas nothing in the declaration of (defvar my-font-lock-keywords-1 <FOO>) that the <FOO> nested lists are meant to be font-lock keywords (unless we use heuristics based on var names, which quickly become ugly and brittle). Stefan ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-11-16 17:44 ` Michael Heerdegen 2023-11-16 18:16 ` Philip Kaludercic @ 2023-11-16 19:19 ` Eli Zaretskii 2023-11-17 8:02 ` Michael Heerdegen 1 sibling, 1 reply; 342+ messages in thread From: Eli Zaretskii @ 2023-11-16 19:19 UTC (permalink / raw) To: Michael Heerdegen; +Cc: emacs-devel > From: Michael Heerdegen <michael_heerdegen@web.de> > Date: Thu, 16 Nov 2023 18:44:10 +0100 > > "T.V Raman" <raman@google.com> writes: > > > I recently tried to understand some of the completion code; -- > > specifically, completion-at-point, and immediately hit the pcase wall > > and gave up --- my lack of understanding of pcase made that code in > > Emacs Core read like line-noise. > > But that pcase form is only performing trivial destructuring. If it does, then the node "Destructuring with pcase Patterns" Needs Work™, because if you try to compare this fragment from completion-at-point: (pcase res (`(,_ . ,(and (pred functionp) f)) (funcall f)) (`(,hookfun . (,start ,end ,collection . ,plist)) with the example in the manual that explains destructuring, viz.: (pcase my-list (`(add ,x ,y) (message "Contains %S and %S" x y))) you will, I hope, see the difficulty of a newcomer to 'pcase' in understanding how the code in completion-at-point is "only destructuring". IOW, if this code is "just destructuring", we don't do a good-enough job of explaining that in the manual. ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-11-16 19:19 ` Instead of pcase Eli Zaretskii @ 2023-11-17 8:02 ` Michael Heerdegen 0 siblings, 0 replies; 342+ messages in thread From: Michael Heerdegen @ 2023-11-17 8:02 UTC (permalink / raw) To: Eli Zaretskii; +Cc: emacs-devel Eli Zaretskii <eliz@gnu.org> writes: > If it does, It doesn't. Was very tired yesterday without being aware of it. Sorry again for the confusion I caused. > then the node "Destructuring with pcase Patterns" Needs > Work™, because if you try to compare this fragment from > completion-at-point: > > (pcase res > (`(,_ . ,(and (pred functionp) f)) (funcall f)) > (`(,hookfun . (,start ,end ,collection . ,plist)) The subpattern (and (pred functionp) f) contains of course more syntactical elements: `and', a `pred' test, and a variable used for binding. Which means: This matches anything fulfilling `functionp' and binds the variable `f' to the element at that position. Michael. ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-11-16 17:18 ` T.V Raman 2023-11-16 17:44 ` Michael Heerdegen @ 2023-11-16 18:21 ` Dmitry Gutov 2023-11-16 18:39 ` T.V Raman 2023-11-16 23:41 ` Emanuel Berg 2 siblings, 1 reply; 342+ messages in thread From: Dmitry Gutov @ 2023-11-16 18:21 UTC (permalink / raw) To: T.V Raman, Philip Kaludercic; +Cc: Richard Stallman, emacs-devel On 16/11/2023 19:18, T.V Raman wrote: > I recently tried to understand some of the completion code; -- > specifically, completion-at-point, and immediately hit the pcase wall > and gave up --- my lack of understanding of pcase made that code in > Emacs Core read like line-noise. Is there a general pattern matching/destructuring syntax that you find easier to read, in any language? ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-11-16 18:21 ` Dmitry Gutov @ 2023-11-16 18:39 ` T.V Raman 2023-11-16 18:47 ` Philip Kaludercic 2023-11-16 18:49 ` Dmitry Gutov 0 siblings, 2 replies; 342+ messages in thread From: T.V Raman @ 2023-11-16 18:39 UTC (permalink / raw) To: dmitry; +Cc: raman, philipk, rms, emacs-devel when-let let-alist etc have worked well for me. What threw me with pcase is there are lots of special chars in that particular example whose meaning I dont know, and looking those up and understanding their use at the same time was what chased me away Dmitry Gutov writes: > On 16/11/2023 19:18, T.V Raman wrote: > > I recently tried to understand some of the completion code; -- > > specifically, completion-at-point, and immediately hit the pcase wall > > and gave up --- my lack of understanding of pcase made that code in > > Emacs Core read like line-noise. > > Is there a general pattern matching/destructuring syntax that you find > easier to read, in any language? -- ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-11-16 18:39 ` T.V Raman @ 2023-11-16 18:47 ` Philip Kaludercic 2023-11-16 18:51 ` T.V Raman 2023-11-18 3:04 ` Richard Stallman 2023-11-16 18:49 ` Dmitry Gutov 1 sibling, 2 replies; 342+ messages in thread From: Philip Kaludercic @ 2023-11-16 18:47 UTC (permalink / raw) To: T.V Raman; +Cc: dmitry, rms, emacs-devel "T.V Raman" <raman@google.com> writes: > when-let let-alist etc have worked well for me. > > What threw me with pcase is there are lots of special chars in that > particular example whose meaning I dont know, and looking those up and > understanding their use at the same time was what chased me away Taking the concrete example you mentioned, (pcase res (`(,_ . ,(and (pred functionp) f)) (funcall f)) (`(,hookfun . (,start ,end ,collection . ,plist)) the unknown or unfamiliar characters are "`" and ",". The (dynamic) pcase documentation string is pretty straightforward in explaining what it does, or can you recall what confused you?: --8<---------------cut here---------------start------------->8--- -- `QPAT Backquote-style pcase patterns: `QPAT 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. SYMBOL matches if EXPVAL is ‘equal’ to SYMBOL. KEYWORD likewise for KEYWORD. NUMBER likewise for NUMBER. STRING likewise for STRING. The list or vector QPAT is a template. The predicate formed by a backquote-style pattern is a combination of those formed by any sub-patterns, wrapped in a top-level condition: EXPVAL must be "congruent" with the template. For example: `(technical ,forum) --8<---------------cut here---------------end--------------->8--- Or if you mean "_", then --8<---------------cut here---------------start------------->8--- PATTERN can take one of the forms: _ matches anything. --8<---------------cut here---------------end--------------->8--- which is familiar to people coming from functional languages, but even Elisp uses underscores to denote unused variables. ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-11-16 18:47 ` Philip Kaludercic @ 2023-11-16 18:51 ` T.V Raman 2023-11-18 3:04 ` Richard Stallman 1 sibling, 0 replies; 342+ messages in thread From: T.V Raman @ 2023-11-16 18:51 UTC (permalink / raw) To: philipk; +Cc: raman, dmitry, rms, emacs-devel I walked away after seeing what at the time of looking looked like line-noise to me. Now, if debugging that function was my day job, I'd have gone the next step in understanding and answering the question you ask. But given that is not the case, I just moved on. Philip Kaludercic writes: > "T.V Raman" <raman@google.com> writes: > > > when-let let-alist etc have worked well for me. > > > > What threw me with pcase is there are lots of special chars in that > > particular example whose meaning I dont know, and looking those up and > > understanding their use at the same time was what chased me away > > Taking the concrete example you mentioned, > > (pcase res > (`(,_ . ,(and (pred functionp) f)) (funcall f)) > (`(,hookfun . (,start ,end ,collection . ,plist)) > > the unknown or unfamiliar characters are "`" and ",". The (dynamic) > pcase documentation string is pretty straightforward in explaining what > it does, or can you recall what confused you?: > > --8<---------------cut here---------------start------------->8--- > -- `QPAT > > Backquote-style pcase patterns: `QPAT > 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. > SYMBOL matches if EXPVAL is ‘equal’ to SYMBOL. > KEYWORD likewise for KEYWORD. > NUMBER likewise for NUMBER. > STRING likewise for STRING. > > The list or vector QPAT is a template. The predicate formed > by a backquote-style pattern is a combination of those > formed by any sub-patterns, wrapped in a top-level condition: > EXPVAL must be "congruent" with the template. For example: > > `(technical ,forum) > --8<---------------cut here---------------end--------------->8--- > > Or if you mean "_", then > > --8<---------------cut here---------------start------------->8--- > PATTERN can take one of the forms: > > _ matches anything. > --8<---------------cut here---------------end--------------->8--- > > which is familiar to people coming from functional languages, but even > Elisp uses underscores to denote unused variables. -- ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-11-16 18:47 ` Philip Kaludercic 2023-11-16 18:51 ` T.V Raman @ 2023-11-18 3:04 ` Richard Stallman 2023-11-19 12:23 ` Michael Heerdegen 2023-11-19 13:49 ` Dmitry Gutov 1 sibling, 2 replies; 342+ messages in thread From: Richard Stallman @ 2023-11-18 3:04 UTC (permalink / raw) To: Philip Kaludercic; +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. ]]] > (`(,_ . ,(and (pred functionp) f)) (funcall f)) > (`(,hookfun . (,start ,end ,collection . ,plist)) I read the Info documentation of pcase a few days ago and I can't recall the rules for understanding those two pcase clauses. What I recall is that they are not to be interpreted as Lisp expressions. They contain code that looks like Lisp but does not have the same semantic rules as Lisp. `(,_ . ,(and (pred functionp) f)) is not Lisp. `(,hookfun . (,start ,end ,collection . ,plist) is not Lisp either. That list would be meaningful as a Lisp expression but what it means here is different. That is a consequence of the terse little language that pcase defines. -- Dr Richard Stallman (https://stallman.org) Chief GNUisance of the GNU Project (https://gnu.org) Founder, Free Software Foundation (https://fsf.org) Internet Hall-of-Famer (https://internethalloffame.org) ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-11-18 3:04 ` Richard Stallman @ 2023-11-19 12:23 ` Michael Heerdegen 2023-11-19 16:02 ` Barry Fishman 2023-11-19 13:49 ` Dmitry Gutov 1 sibling, 1 reply; 342+ messages in thread From: Michael Heerdegen @ 2023-11-19 12:23 UTC (permalink / raw) To: Richard Stallman; +Cc: Philip Kaludercic, emacs-devel Richard Stallman <rms@gnu.org> writes: > I read the Info documentation of pcase a few days ago and I can't > recall the rules for understanding those two pcase clauses. What I > recall is that they are not to be interpreted as Lisp expressions. > They contain code that looks like Lisp but does not have the same > semantic rules as Lisp. > > `(,_ . ,(and (pred functionp) f)) > > is not Lisp. > > `(,hookfun . (,start ,end ,collection . ,plist) > > is not Lisp either. I more and more come to the conclusion that the backquote syntax is more or less the central point that scares or confuses (some) people. So you would rather prefer to have a normal function that returns a matcher (if you want just "Lisp")? What functions could be used to describe a pattern matching lists of a certain structure? I guess it would be the easiest approach if we could still use the names we already know: list, car, cdr. Hmm - actually the most compact mean to construct more complicated lists is backquote. And that's what you have above. The only thing you need to remember is that elements you "insert" or "splice in" are again pattern descriptions matching the elements at that position. How could it be even simpler? Once you accepted that backquote is used for a different, but parallel semantics here, everything suddenly gets absolutely trivial. But I see your point, it's not Lisp. I guess it should be possible to change that. We could define a set of functions to construct a matcher. This would make the pattern specifications less compact and for some of us harder to read (more verbosity), but it should be possible. We could even have some kind of converter between the two representations of pattern specifications. This leads me to a realization: A "normal Lisp" approach would still need to define replacements for all of the constructs. (pred FUN . ARGS) would have to be replaced by something like (make-matching-fun FUN &optional ARGS). You would still have to remember the exactly same details: what are the semantics of the returned pattern; when there are ARGS specified, at which argument position is the matched thing specified when FUN will be called? How to correctly negate this pattern? Will the matching algorithm backtrack when the pattern is negated? So, the advantage would be more of a psychological kind: you have normal Lisp function calls, but structurally you have the same thing, and you have to remember exactly the same set of details. The complexity comes from the task, not from the implementation. Michael. ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-11-19 12:23 ` Michael Heerdegen @ 2023-11-19 16:02 ` Barry Fishman 2023-11-19 17:59 ` Dmitry Gutov 0 siblings, 1 reply; 342+ messages in thread From: Barry Fishman @ 2023-11-19 16:02 UTC (permalink / raw) To: emacs-devel On 2023-11-19 13:23:17 +01, Michael Heerdegen wrote: > So, the advantage would be more of a psychological kind: you have normal > Lisp function calls, but structurally you have the same thing, and you > have to remember exactly the same set of details. The complexity comes > from the task, not from the implementation. I submit that the opposite is true, the complexity is in its implementation, not the task. In languages like Haskell this is expressed in a very simple way, so the task is not in itself hard to understand. For example, one implementation might be to use the form: (proto-case x (typeproto guard expressions...) ...) The typeproto would be a type, or a list made up of the type and a variable that could be use in the expression. The guard would be an expression which is required to be true before a match can be declared. Composite types like pair, list, vector, or list*, would have typeproto's for their arguments when they are expanded as a list): (proto-case x ((list string integer) t ...)) which would match a list of two element, the first a string, and the second an integer. The guard (t) would always consider it a match. The list arguments which are typeproto's themselves, could be made into assignments with using a list, as above. If x is a list with its first element a string "foo" and the second an integer, remove it from x and add the second element to total: (proto-case x ((list* (string name) (integer count) (t rest)) (string-equal name "foo") (set! total (+ total count)) (set! x rest))) This is just one of many other ways one could setup a matching expression in elisp, the best is a balance between implementation efficiency and readability. I think the complexity doesn't come from the task, but comes from the choice of implementation. So its the complexity of the implementation that should determines whether it is worth while implementing. Although back-quoting is part of Lisp, it was added to solve a specific problem, and unfortunately added new syntax tokens to Lisp, which it otherwise avoids. -- Barry Fishman ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-11-19 16:02 ` Barry Fishman @ 2023-11-19 17:59 ` Dmitry Gutov 2023-11-19 19:31 ` Eric Abrahamsen 2023-11-19 21:15 ` Barry Fishman 0 siblings, 2 replies; 342+ messages in thread From: Dmitry Gutov @ 2023-11-19 17:59 UTC (permalink / raw) To: Barry Fishman, emacs-devel On 19/11/2023 18:02, Barry Fishman wrote: > On 2023-11-19 13:23:17 +01, Michael Heerdegen wrote: >> So, the advantage would be more of a psychological kind: you have normal >> Lisp function calls, but structurally you have the same thing, and you >> have to remember exactly the same set of details. The complexity comes >> from the task, not from the implementation. > > I submit that the opposite is true, the complexity is in its > implementation, not the task. > > In languages like Haskell this is expressed in a very simple way, so the > task is not in itself hard to understand. Haskell is notable for using the same (or similar) syntax for destructuring as it uses for constructing expressions. pcase actually follows that practice with backquotes and commas. And in both matching and destructuring are done in the same expression (the presence of the latter is determined by whether a pattern contains variable bindindgs). > If x is a list with its first element a string "foo" and the second an > integer, remove it from x and add the second element to total: > > (proto-case x > ((list* (string name) (integer count) (t rest)) > (string-equal name "foo") > (set! total (+ total count)) > (set! x rest))) > > This is just one of many other ways one could setup a matching > expression in elisp, the best is a balance between implementation > efficiency and readability. And this divorces matching from destructuring. I suggest you try rewriting one of the more complex pcase usages into this syntax and see what people think of the result. ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-11-19 17:59 ` Dmitry Gutov @ 2023-11-19 19:31 ` Eric Abrahamsen 2023-11-25 4:23 ` Stefan Monnier via Emacs development discussions. 2023-11-19 21:15 ` Barry Fishman 1 sibling, 1 reply; 342+ messages in thread From: Eric Abrahamsen @ 2023-11-19 19:31 UTC (permalink / raw) To: emacs-devel Dmitry Gutov <dmitry@gutov.dev> writes: > On 19/11/2023 18:02, Barry Fishman wrote: >> On 2023-11-19 13:23:17 +01, Michael Heerdegen wrote: >>> So, the advantage would be more of a psychological kind: you have normal >>> Lisp function calls, but structurally you have the same thing, and you >>> have to remember exactly the same set of details. The complexity comes >>> from the task, not from the implementation. >> I submit that the opposite is true, the complexity is in its >> implementation, not the task. >> In languages like Haskell this is expressed in a very simple way, so >> the >> task is not in itself hard to understand. > > Haskell is notable for using the same (or similar) syntax for > destructuring as it uses for constructing expressions. > > pcase actually follows that practice with backquotes and commas. > > And in both matching and destructuring are done in the same expression > (the presence of the latter is determined by whether a pattern > contains variable bindindgs). +1, thanks for stating this so clearly in this and your earlier message. I agree that once you introduce guards/predicates, pcase gets ugly fast, but as you and Michael say, the core conceit is already as simple as it could be, and is deeply consonant with the already-understood meaning of the backquote. ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-11-19 19:31 ` Eric Abrahamsen @ 2023-11-25 4:23 ` Stefan Monnier via Emacs development discussions. 2023-11-27 3:12 ` Richard Stallman 0 siblings, 1 reply; 342+ messages in thread From: Stefan Monnier via Emacs development discussions. @ 2023-11-25 4:23 UTC (permalink / raw) To: emacs-devel > I agree that once you introduce guards/predicates, pcase gets ugly fast, Yeah, it's also my experience (tho a single `pred` is usually OK as long as you don't also need to bind the value, thus forcing you into the ugly `(and (pred PRED) VAR)` thingy). I have toyed with the idea of providing the guards separately from the patterns, but not enough to find something satisfactory. Stefan ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-11-25 4:23 ` Stefan Monnier via Emacs development discussions. @ 2023-11-27 3:12 ` Richard Stallman 0 siblings, 0 replies; 342+ messages in thread From: Richard Stallman @ 2023-11-27 3:12 UTC (permalink / raw) To: Stefan Monnier; +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. ]]] > I have toyed with the idea of providing the guards separately from the > patterns, but not enough to find something satisfactory. Would you like to try writing such cases for `cond*', and report on cases that are natural or not? -- Dr Richard Stallman (https://stallman.org) Chief GNUisance of the GNU Project (https://gnu.org) Founder, Free Software Foundation (https://fsf.org) Internet Hall-of-Famer (https://internethalloffame.org) ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-11-19 17:59 ` Dmitry Gutov 2023-11-19 19:31 ` Eric Abrahamsen @ 2023-11-19 21:15 ` Barry Fishman 2023-11-20 1:15 ` Dmitry Gutov 2023-11-20 15:32 ` Michael Heerdegen 1 sibling, 2 replies; 342+ messages in thread From: Barry Fishman @ 2023-11-19 21:15 UTC (permalink / raw) To: emacs-devel On 2023-11-19 19:59:42 +02, Dmitry Gutov wrote: > On 19/11/2023 18:02, Barry Fishman wrote: >> On 2023-11-19 13:23:17 +01, Michael Heerdegen wrote: >>> So, the advantage would be more of a psychological kind: you have normal >>> Lisp function calls, but structurally you have the same thing, and you >>> have to remember exactly the same set of details. The complexity comes >>> from the task, not from the implementation. >> I submit that the opposite is true, the complexity is in its >> implementation, not the task. >> In languages like Haskell this is expressed in a very simple way, so >> the >> task is not in itself hard to understand. > > Haskell is notable for using the same (or similar) syntax for > destructuring as it uses for constructing expressions. > > pcase actually follows that practice with backquotes and commas. Really? I thought back-quoting was used (as an alternative way) to construct nested lists, to express more simply the piecing together and concatenating nested list pieces, particularly in macroes, and its expansion at compile time is fairly obvious. I guess what pcase is trying to do is the similar, but it is expressing something that, to me, seem far more complex to use. Its also mixing "destructuring" and "guard"s, all in one "super" domain specific language. Like loop, it can be powerful, but intimidating to people that don't use it a lot. But its usefulness to those that know it, encourages its use in the code base. But exiting Lisp destructuring via destructuring-bind and lambda arguments, don't use backquoting. One thing I did change was to reverse the defmethod style of (variable type) to (type variable) to try to simplify recursion in the typeproto syntax. > And in both matching and destructuring are done in the same expression > (the presence of the latter is determined by whether a pattern > contains variable bindindgs). > >> If x is a list with its first element a string "foo" and the second an >> integer, remove it from x and add the second element to total: >> (proto-case x >> ((list* (string name) (integer count) (t rest)) >> (string-equal name "foo") >> (set! total (+ total count)) >> (set! x rest))) >> This is just one of many other ways one could setup a matching >> expression in elisp, the best is a balance between implementation >> efficiency and readability. > > And this divorces matching from destructuring. I suggest you try > rewriting one of the more complex pcase usages into this syntax and > see what people think of the result. You want me to guess what you have in mind? I have no idea. I'll take the example pcase code from the Emacs manual: (pcase (get-return-code x) ;; string ((and (pred stringp) msg) (message "%s" msg)) ;; symbol ('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")) ;; default (code (message "Unknown return code %S" code))) This is a simple use case, so its hard to use to draw any conclusions. This is mostly value handling for a known type, which is to me a different problem than destructuring, and be handled better by a generalized value case structure. But still: (let ((msglist '((success . "Done!") (would-block . "Sorry, can't do it now") (read-only . "The shmliblick is read-only") (access-denied . "You do not have the needed rights")))) (proto-case (get-return-code x) ((string msg) t (message "%s" msg)) ((symbol sym) t (let ((pair (assq sym msglist))) (if pair (message (cdr pair)) (message "Unknown return symbol %S" sym)))) ((t code) t (message "Unknown return type %S" code)))) In this situation pcase situation is a slightly better, to my sensibility's. [Now that pcase is written] One could also define a value oriented traditional style case: (vcase (x typecmp default) ((value expression ...) ...)) Which tests x using (funcall typecmp x value), and returns default if there is no match. And avoid the proto-case all together: (let ((code (get-return-code))) (cond ((stringp code) (message "%s" msg)) ((symbolp code) (or (vcase (sym eq nil) ('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"))) (message "Unknown return code %S" sym))) (t (message "Unknown return type %S" code)))) -- Barry Fishman ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-11-19 21:15 ` Barry Fishman @ 2023-11-20 1:15 ` Dmitry Gutov 2023-11-20 15:32 ` Michael Heerdegen 1 sibling, 0 replies; 342+ messages in thread From: Dmitry Gutov @ 2023-11-20 1:15 UTC (permalink / raw) To: Barry Fishman, emacs-devel On 19/11/2023 23:15, Barry Fishman wrote: >> Haskell is notable for using the same (or similar) syntax for >> destructuring as it uses for constructing expressions. >> >> pcase actually follows that practice with backquotes and commas. > > Really? I thought back-quoting was used (as an alternative way) to > construct nested lists, to express more simply the piecing together and > concatenating nested list pieces, particularly in macroes, and its > expansion at compile time is fairly obvious. > > I guess what pcase is trying to do is the similar, The reverse, to be more exact. > but it is expressing > something that, to me, seem far more complex to use. I don't blame you, FWIW. But I've yet to see a "simpler" solution which would provide comparable functionality. > Its also mixing "destructuring" and "guard"s, all in one "super" domain > specific language. > > Like loop, it can be powerful, but intimidating to people that don't use > it a lot. But its usefulness to those that know it, encourages its > use in the code base. > > But exiting Lisp destructuring via destructuring-bind and lambda > arguments, don't use backquoting. They also don't provide any pattern matching of case-like functionality. When you don't need a way to distinguish literals from variables, (un)quoting is indeed not needed. > One thing I did change was to reverse the defmethod style of (variable > type) to (type variable) to try to simplify recursion in the typeproto > syntax. > >> And in both matching and destructuring are done in the same expression >> (the presence of the latter is determined by whether a pattern >> contains variable bindindgs). >> >>> If x is a list with its first element a string "foo" and the second an >>> integer, remove it from x and add the second element to total: >>> (proto-case x >>> ((list* (string name) (integer count) (t rest)) >>> (string-equal name "foo") >>> (set! total (+ total count)) >>> (set! x rest))) >>> This is just one of many other ways one could setup a matching >>> expression in elisp, the best is a balance between implementation >>> efficiency and readability. >> >> And this divorces matching from destructuring. I suggest you try >> rewriting one of the more complex pcase usages into this syntax and >> see what people think of the result. > > You want me to guess what you have in mind? I have no idea. I meant that you could try to take an example of a complex usage of pcase (one that seemed complex to you), some big expression or at least one that exhibits most of pcase's functionalities, and try rewriting it using an alternative syntax. And then judge for yourself, and then maybe poll others, which solution looks more readable and easier to understand. > I'll take the example pcase code from the Emacs manual: > > (pcase (get-return-code x) > ;; string > ((and (pred stringp) msg) > (message "%s" msg)) > ;; symbol > ('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")) > ;; default > (code (message "Unknown return code %S" code))) > > This is a simple use case, so its hard to use to draw any conclusions. > > This is mostly value handling for a known type, which is to me a > different problem than destructuring, and be handled better by a > generalized value case structure. But still: > > (let ((msglist > '((success . "Done!") > (would-block . "Sorry, can't do it now") > (read-only . "The shmliblick is read-only") > (access-denied . "You do not have the needed rights")))) > (proto-case (get-return-code x) > ((string msg) t (message "%s" msg)) > ((symbol sym) t (let ((pair (assq sym msglist))) > (if pair > (message (cdr pair)) > (message "Unknown return symbol %S" sym)))) > ((t code) t (message "Unknown return type %S" code)))) > > In this situation pcase situation is a slightly better, to my > sensibility's. [Now that pcase is written] Indeed, I don't see an improvement either. I'd say it looks worse because of the slight increase in verbosity, but they're close enough. That's why I suggested picking some relatively complex example to rewrite: more potential to show a difference. ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-11-19 21:15 ` Barry Fishman 2023-11-20 1:15 ` Dmitry Gutov @ 2023-11-20 15:32 ` Michael Heerdegen 2023-11-23 2:57 ` Richard Stallman 1 sibling, 1 reply; 342+ messages in thread From: Michael Heerdegen @ 2023-11-20 15:32 UTC (permalink / raw) To: emacs-devel Barry Fishman <barry@ecubist.org> writes: > Its also mixing "destructuring" and "guard"s, all in one "super" > domain specific language. This is the requirement: in some situations a code path should only be chosen when a certain structure is present and certain requirements for certain parts of the structure are fulfilled. When you separate these two things artificially you will make the thing more complicated, you need to introduce extra bindings (for the tests) that the BODY doesn't use, resulting in poorly readable code. > I'll take the example pcase code from the Emacs manual: > [...] > and be handled better by a generalized value case structure. These examples have been added to ease learning. They are not typical use cases of course. Michael. ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-11-20 15:32 ` Michael Heerdegen @ 2023-11-23 2:57 ` Richard Stallman 2023-11-24 17:14 ` Dmitry Gutov 2023-11-24 18:14 ` Michael Heerdegen 0 siblings, 2 replies; 342+ messages in thread From: Richard Stallman @ 2023-11-23 2:57 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. ]]] > This is the requirement: in some situations a code path should only be > chosen when a certain structure is present and certain requirements for > certain parts of the structure are fulfilled. When you separate these > two things artificially you will make the thing more complicated, you > need to introduce extra bindings (for the tests) that the BODY doesn't > use, resulting in poorly readable code. Would you be willing to show me two or thhree examples of this, so I cam make sure those are natural enough in the framework I'm designing? -- Dr Richard Stallman (https://stallman.org) Chief GNUisance of the GNU Project (https://gnu.org) Founder, Free Software Foundation (https://fsf.org) Internet Hall-of-Famer (https://internethalloffame.org) ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-11-23 2:57 ` Richard Stallman @ 2023-11-24 17:14 ` Dmitry Gutov 2023-11-27 3:09 ` Richard Stallman 2023-11-28 2:44 ` Richard Stallman 2023-11-24 18:14 ` Michael Heerdegen 1 sibling, 2 replies; 342+ messages in thread From: Dmitry Gutov @ 2023-11-24 17:14 UTC (permalink / raw) To: rms, Michael Heerdegen; +Cc: emacs-devel On 23/11/2023 04:57, Richard Stallman wrote: > > This is the requirement: in some situations a code path should only be > > chosen when a certain structure is present and certain requirements for > > certain parts of the structure are fulfilled. When you separate these > > two things artificially you will make the thing more complicated, you > > need to introduce extra bindings (for the tests) that the BODY doesn't > > use, resulting in poorly readable code. > > Would you be willing to show me two or thhree examples of this, so I > cam make sure those are natural enough in the framework I'm designing? I suggest you try rewriting the definition of completion-help-at-point using your alternative construct. We just discussed what the pcase clauses there do, and they are small enough so this won't be a lot of work, while at the same time they exhibit several of the important features of pcase. ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-11-24 17:14 ` Dmitry Gutov @ 2023-11-27 3:09 ` Richard Stallman 2023-11-27 12:21 ` Dmitry Gutov 2023-11-28 2:44 ` Richard Stallman 1 sibling, 1 reply; 342+ messages in thread From: Richard Stallman @ 2023-11-27 3:09 UTC (permalink / raw) To: Dmitry Gutov; +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. ]]] > I suggest you try rewriting the definition of completion-help-at-point > using your alternative construct. I tried to do this, and it isn't hard to do this by formulating each clause to use :match. However, to make the simplest possible result, I need to know all the kinds of values that RES can have. For instance, at this point, (`(,hookfun . ,_) ;; The hook function already performed completion :-( ;; Not much we can do at this point. (message "%s already performed completion!" hookfun) nil) what are the possible values of RES that will NOT match that pattern? -- Dr Richard Stallman (https://stallman.org) Chief GNUisance of the GNU Project (https://gnu.org) Founder, Free Software Foundation (https://fsf.org) Internet Hall-of-Famer (https://internethalloffame.org) ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-11-27 3:09 ` Richard Stallman @ 2023-11-27 12:21 ` Dmitry Gutov 2023-11-29 3:42 ` Richard Stallman 0 siblings, 1 reply; 342+ messages in thread From: Dmitry Gutov @ 2023-11-27 12:21 UTC (permalink / raw) To: rms; +Cc: michael_heerdegen, emacs-devel On 27/11/2023 05:09, 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. ]]] > > > I suggest you try rewriting the definition of completion-help-at-point > > using your alternative construct. > > I tried to do this, and it isn't hard to do this by formulating each clause > to use :match. I didn't think it would be difficult. But then one would compare the solutions. > However, to make the simplest possible result, I need to know > all the kinds of values that RES can have. For instance, at this point, > > (`(,hookfun . ,_) > ;; The hook function already performed completion :-( > ;; Not much we can do at this point. > (message "%s already performed completion!" hookfun) > nil) > > what are the possible values of RES that will NOT match that pattern? Since "_" means "anything", the pcase form does enumerate all possible options (anything else would be a bug in the code producing res). ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-11-27 12:21 ` Dmitry Gutov @ 2023-11-29 3:42 ` Richard Stallman 2023-11-29 12:56 ` Dmitry Gutov 0 siblings, 1 reply; 342+ messages in thread From: Richard Stallman @ 2023-11-29 3:42 UTC (permalink / raw) To: Dmitry Gutov; +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. ]]] > > However, to make the simplest possible result, I need to know > > all the kinds of values that RES can have. For instance, at this point, > > > > (`(,hookfun . ,_) > > ;; The hook function already performed completion :-( > > ;; Not much we can do at this point. > > (message "%s already performed completion!" hookfun) > > nil) > > > > what are the possible values of RES that will NOT match that pattern? > Since "_" means "anything", the pcase form does enumerate all possible > options We had a miscommunication. Your answer tells me what that pcase clause recognizes, but the question I am asking is a different one. My question is about what values of RES are _valid_ at that point in the code. (anything else would be a bug in the code producing res). My question is about the code producing RES. What are the values it can produce, and what do they mean? -- Dr Richard Stallman (https://stallman.org) Chief GNUisance of the GNU Project (https://gnu.org) Founder, Free Software Foundation (https://fsf.org) Internet Hall-of-Famer (https://internethalloffame.org) ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-11-29 3:42 ` Richard Stallman @ 2023-11-29 12:56 ` Dmitry Gutov 2023-12-01 3:17 ` Richard Stallman 0 siblings, 1 reply; 342+ messages in thread From: Dmitry Gutov @ 2023-11-29 12:56 UTC (permalink / raw) To: rms; +Cc: michael_heerdegen, emacs-devel On 29/11/2023 05:42, 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. ]]] > > > > However, to make the simplest possible result, I need to know > > > all the kinds of values that RES can have. For instance, at this point, > > > > > > (`(,hookfun . ,_) > > > ;; The hook function already performed completion 🙁 > > > ;; Not much we can do at this point. > > > (message "%s already performed completion!" hookfun) > > > nil) > > > > > > what are the possible values of RES that will NOT match that pattern? > > > Since "_" means "anything", the pcase form does enumerate all possible > > options > > We had a miscommunication. Your answer tells me what that pcase > clause recognizes, but the question I am asking is a different one. > My question is about what values of RES are_valid_ at that point in > the code. > > (anything else would be a bug in the code producing res). > > My question is about the code producing RES. > What are the values it can produce, and what do they mean? I'm not sure it's productive to explain the whole completion mechanism here, and which bits are involved in it. I just wanted you to assume that the existing code does what it should do (there exist only those cases that pcase matches, and the ones it does not, should not exist), and to try to rewrite it using a different syntax. ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-11-29 12:56 ` Dmitry Gutov @ 2023-12-01 3:17 ` Richard Stallman 0 siblings, 0 replies; 342+ messages in thread From: Richard Stallman @ 2023-12-01 3:17 UTC (permalink / raw) To: Dmitry Gutov; +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. ]]] > I just wanted you to assume that the existing code does what it should > do (there exist only those cases that pcase matches, and the ones it > does not, should not exist), and to try to rewrite it using a different > syntax. What I wanted, when I saw that code, was something different. I wanted to rewrite it in a way that I would find cleaner. -- Dr Richard Stallman (https://stallman.org) Chief GNUisance of the GNU Project (https://gnu.org) Founder, Free Software Foundation (https://fsf.org) Internet Hall-of-Famer (https://internethalloffame.org) ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-11-24 17:14 ` Dmitry Gutov 2023-11-27 3:09 ` Richard Stallman @ 2023-11-28 2:44 ` Richard Stallman 2023-11-28 12:39 ` Dmitry Gutov 1 sibling, 1 reply; 342+ messages in thread From: Richard Stallman @ 2023-11-28 2:44 UTC (permalink / raw) To: Dmitry Gutov; +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. ]]] > I suggest you try rewriting the definition of completion-help-at-point > using your alternative construct. I did that, and found that translating that particular pcase to use cond* resulted in something about equally complex. But I recognized some changess to make in cond* as a result. Those changes are in the newer version I sent out during the weekend. Thanks. -- Dr Richard Stallman (https://stallman.org) Chief GNUisance of the GNU Project (https://gnu.org) Founder, Free Software Foundation (https://fsf.org) Internet Hall-of-Famer (https://internethalloffame.org) ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-11-28 2:44 ` Richard Stallman @ 2023-11-28 12:39 ` Dmitry Gutov 2023-11-30 3:37 ` Richard Stallman 0 siblings, 1 reply; 342+ messages in thread From: Dmitry Gutov @ 2023-11-28 12:39 UTC (permalink / raw) To: rms; +Cc: michael_heerdegen, emacs-devel On 28/11/2023 04:44, Richard Stallman wrote: > > I suggest you try rewriting the definition of completion-help-at-point > > using your alternative construct. > > I did that, and found that translating that particular pcase to use > cond* resulted in something about equally complex. I guess that's the point I wanted to underscore: that those pcase uses are more-or-less optimal in terms of complexity (for its ultimate goals), that in most cases it comes from the problem domain rather than from the solution. And I'm guessing your solutions were more verbose, if anything. > But I recognized > some changess to make in cond* as a result. Those changes are in the > newer version I sent out during the weekend. Happy to help. Though note that simply adding a new way to do the same thing that's not better by a sufficiently large margin, usually leads to "now we have N+1 standards". ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-11-28 12:39 ` Dmitry Gutov @ 2023-11-30 3:37 ` Richard Stallman 2023-12-01 0:18 ` Dmitry Gutov 0 siblings, 1 reply; 342+ messages in thread From: Richard Stallman @ 2023-11-30 3:37 UTC (permalink / raw) To: Dmitry Gutov; +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. ]]] > I guess that's the point I wanted to underscore: that those pcase uses > are more-or-less optimal in terms of complexity (for its ultimate > goals), that in most cases it comes from the problem domain rather than > from the solution. I think the way you measure "complexity" is different from the way I measure it. I suspect that your measure does not count the complexity of learning `pcase' -- that it assumes the reader knows that already. That complexitu is what I am trying to eliminate. I also think that you measure "complexity" as the opposite of terseness, so that a couple of uses of `match-set' is in your view "added complexity". However, terseness is what makes `pcase' more complex. -- Dr Richard Stallman (https://stallman.org) Chief GNUisance of the GNU Project (https://gnu.org) Founder, Free Software Foundation (https://fsf.org) Internet Hall-of-Famer (https://internethalloffame.org) ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-11-30 3:37 ` Richard Stallman @ 2023-12-01 0:18 ` Dmitry Gutov 2023-12-01 5:51 ` Emanuel Berg ` (2 more replies) 0 siblings, 3 replies; 342+ messages in thread From: Dmitry Gutov @ 2023-12-01 0:18 UTC (permalink / raw) To: rms; +Cc: michael_heerdegen, emacs-devel On 30/11/2023 05:37, 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. ]]] > > > I guess that's the point I wanted to underscore: that those pcase uses > > are more-or-less optimal in terms of complexity (for its ultimate > > goals), that in most cases it comes from the problem domain rather than > > from the solution. > > I think the way you measure "complexity" is different from the way I > measure it. I suspect that your measure does not count the complexity > of learning `pcase' -- that it assumes the reader knows that already. > > That complexitu is what I am trying to eliminate. > > I also think that you measure "complexity" as the opposite of terseness, > so that a couple of uses of `match-set' is in your view "added complexity". > However, terseness is what makes `pcase' more complex. You haven't posted your conversion, but I suspect it was not just less terse, but it also forced the programmer to repeat the same sets of information: first, in the predicate, to check that the value has a certain structure, and then in the matcher, to deconstruct the structure and create a set of variable bindings. This repetition both adds verbosity and increases the chance to make a mistake in one of the two places. But once you eliminate it, I believe the result has to look like a more verbose pcase. Choosing an new syntax should be possible (indeed, somebody posted a link to a similar construct in Racket which is more wordy), but then those who don't like high-level constructs probably won't like it either. ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-12-01 0:18 ` Dmitry Gutov @ 2023-12-01 5:51 ` Emanuel Berg 2023-12-10 8:34 ` Alfred M. Szmidt 2023-12-01 7:21 ` Eli Zaretskii 2023-12-02 3:21 ` Richard Stallman 2 siblings, 1 reply; 342+ messages in thread From: Emanuel Berg @ 2023-12-01 5:51 UTC (permalink / raw) To: emacs-devel Dmitry Gutov wrote: > Choosing an new syntax should be possible (indeed, somebody > posted a link to a similar construct in Racket which is more > wordy), but then those who don't like high-level constructs > probably won't like it either. We had a very long and unpleasant discussion, now people are instead working on things they think will be an improvement. And maybe it will be, at least to those people! So let's leave it at that for now perhaps, regardless of whatever it is a much more constructive approach. -- underground experts united https://dataswamp.org/~incal ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-12-01 5:51 ` Emanuel Berg @ 2023-12-10 8:34 ` Alfred M. Szmidt 2023-12-10 9:35 ` Eli Zaretskii 0 siblings, 1 reply; 342+ messages in thread From: Alfred M. Szmidt @ 2023-12-10 8:34 UTC (permalink / raw) To: Emanuel Berg; +Cc: emacs-devel [Seems this message didn't get pushed -- if it is a duplicate, apologies!] I am writing to express my concern about a recent change in the behavior of the jump-to-register and point-to-register commands in the master branch (Bug#66394). It is also not mentioned in NEWS; unless you consider the cryptic entry: ** 'register-preview-delay' is no longer used. Register preview is no more delayed. If you want to disable it use 'register-use-preview' instead with a boolean value. Setting register-use-preview to nil doesn't revert to the previous, ancient, behaviour. It also seems that this change removes the possibility to add a delay -- which sounds like a nice feature, specially _if_ after that delay you're asked for a explicit RET. Previously, these commands allowed users to seamlessly navigate without the need to press the RET key every time. Unfortunately, the recent modification has introduced a requirement to press RET with every use, which has proven to be quite cumbersome for me. INCF. ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-12-10 8:34 ` Alfred M. Szmidt @ 2023-12-10 9:35 ` Eli Zaretskii 2023-12-10 9:53 ` Alfred M. Szmidt 0 siblings, 1 reply; 342+ messages in thread From: Eli Zaretskii @ 2023-12-10 9:35 UTC (permalink / raw) To: Alfred M. Szmidt; +Cc: emacs-devel > From: "Alfred M. Szmidt" <ams@gnu.org> > Cc: emacs-devel@gnu.org > Date: Sun, 10 Dec 2023 03:34:26 -0500 > > It is also not mentioned in NEWS; unless you consider the cryptic entry: > > ** 'register-preview-delay' is no longer used. > Register preview is no more delayed. If you want to disable it use > 'register-use-preview' instead with a boolean value. > > Setting register-use-preview to nil doesn't revert to the previous, > ancient, behaviour. You have an outdated repository; please update from Git. > It also seems that this change removes the > possibility to add a delay -- which sounds like a nice feature, > specially _if_ after that delay you're asked for a explicit RET. That's why this is listed under "incompatible changes". The feature to disable the preview by setting the delay to a large value is preserved, as described in NEWS, but the delaying is not. ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-12-10 9:35 ` Eli Zaretskii @ 2023-12-10 9:53 ` Alfred M. Szmidt 2023-12-10 10:35 ` Eli Zaretskii 0 siblings, 1 reply; 342+ messages in thread From: Alfred M. Szmidt @ 2023-12-10 9:53 UTC (permalink / raw) To: Eli Zaretskii; +Cc: emacs-devel You have an outdated repository; please update from Git. No, I don't. register-use-preview set to nil does NOT revert to the previous behaviour, and from the looks _purposefully_ so! ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-12-10 9:53 ` Alfred M. Szmidt @ 2023-12-10 10:35 ` Eli Zaretskii 2023-12-10 11:05 ` Alfred M. Szmidt 0 siblings, 1 reply; 342+ messages in thread From: Eli Zaretskii @ 2023-12-10 10:35 UTC (permalink / raw) To: Alfred M. Szmidt; +Cc: emacs-devel > From: "Alfred M. Szmidt" <ams@gnu.org> > Cc: emacs-devel@gnu.org > Date: Sun, 10 Dec 2023 04:53:33 -0500 > > You have an outdated repository; please update from Git. > > No, I don't. register-use-preview set to nil does NOT revert to the > previous behaviour, and from the looks _purposefully_ so! The correct value is 'never', as the latest NEWS says. Not nil. ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-12-10 10:35 ` Eli Zaretskii @ 2023-12-10 11:05 ` Alfred M. Szmidt 0 siblings, 0 replies; 342+ messages in thread From: Alfred M. Szmidt @ 2023-12-10 11:05 UTC (permalink / raw) To: Eli Zaretskii; +Cc: emacs-devel > You have an outdated repository; please update from Git. > > No, I don't. register-use-preview set to nil does NOT revert to the > previous behaviour, and from the looks _purposefully_ so! The correct value is 'never', as the latest NEWS says. Not nil. Not according to the docstring. Nor does it work as advertised, since it does not revert to the previous behaviour in any shape or form. ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-12-01 0:18 ` Dmitry Gutov 2023-12-01 5:51 ` Emanuel Berg @ 2023-12-01 7:21 ` Eli Zaretskii 2023-12-01 8:03 ` Manuel Giraud via Emacs development discussions. 2023-12-02 3:21 ` Richard Stallman 2 siblings, 1 reply; 342+ messages in thread From: Eli Zaretskii @ 2023-12-01 7:21 UTC (permalink / raw) To: Dmitry Gutov; +Cc: rms, michael_heerdegen, emacs-devel > Date: Fri, 1 Dec 2023 02:18:00 +0200 > Cc: michael_heerdegen@web.de, emacs-devel@gnu.org > From: Dmitry Gutov <dmitry@gutov.dev> > > Choosing an new syntax should be possible (indeed, somebody posted a > link to a similar construct in Racket which is more wordy), but then > those who don't like high-level constructs probably won't like it > either. I think the point is not with high-level vs lower-level constructs, the point is with syntax and semantics that deviate significantly from Emacs Lisp syntax and semantics. Syntax that is natural in Emacs Lisp and uses good mnemonics in its keywords is easy to understand at a glance, whereas syntax that deviates requires a full understanding of all the details before you can interpret the code. For example, constructs such as the many with-SOMETHING macros we have in Emacs are also higher-level than the actual code they expand into, but code using these macros is very easy to understand because the syntax is normative and the names of the macros are descriptive enough to be mnemonically helpful. ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-12-01 7:21 ` Eli Zaretskii @ 2023-12-01 8:03 ` Manuel Giraud via Emacs development discussions. 0 siblings, 0 replies; 342+ messages in thread From: Manuel Giraud via Emacs development discussions. @ 2023-12-01 8:03 UTC (permalink / raw) To: Eli Zaretskii; +Cc: Dmitry Gutov, rms, michael_heerdegen, emacs-devel Eli Zaretskii <eliz@gnu.org> writes: [...] > For example, constructs such as the many with-SOMETHING macros we have > in Emacs are also higher-level than the actual code they expand into, > but code using these macros is very easy to understand because the > syntax is normative and the names of the macros are descriptive enough > to be mnemonically helpful. Yes but the with-SOMETHING macros also exist in Common Lisp and are also easy to understand. Most of the time, it reads as « execute this body with this resource taken/opened/locked and eventually do some house-keeping said resource ». A pattern matching construct will, of course, be more complex. -- Manuel Giraud ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-12-01 0:18 ` Dmitry Gutov 2023-12-01 5:51 ` Emanuel Berg 2023-12-01 7:21 ` Eli Zaretskii @ 2023-12-02 3:21 ` Richard Stallman 2 siblings, 0 replies; 342+ messages in thread From: Richard Stallman @ 2023-12-02 3:21 UTC (permalink / raw) To: Dmitry Gutov; +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. ]]] > certain structure, and then in the matcher, to deconstruct the structure > and create a set of variable bindings. I think I posted the translations I came up with. But I can't recall after this long whether there was any additional repetition. > This repetition both adds verbosity and increases the chance to make a > mistake in one of the two places. If there was any additional repetition, it was a few tokens -- nothing significant. The complexity of pcase's terse domain specific language is a significant obstacle. > This repetition both adds verbosity and increases the chance to make a > mistake in one of the two places. But once you eliminate it, I believe > the result has to look like a more verbose pcase. My current version of cond* has only a tiny fraction of the complexity of pcase. -- Dr Richard Stallman (https://stallman.org) Chief GNUisance of the GNU Project (https://gnu.org) Founder, Free Software Foundation (https://fsf.org) Internet Hall-of-Famer (https://internethalloffame.org) ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-11-23 2:57 ` Richard Stallman 2023-11-24 17:14 ` Dmitry Gutov @ 2023-11-24 18:14 ` Michael Heerdegen 2023-11-24 18:35 ` Dmitry Gutov 2023-11-27 3:14 ` Richard Stallman 1 sibling, 2 replies; 342+ messages in thread From: Michael Heerdegen @ 2023-11-24 18:14 UTC (permalink / raw) To: Richard Stallman; +Cc: emacs-devel Richard Stallman <rms@gnu.org> writes: > Would you be willing to show me two or thhree examples of this, so I > cam make sure those are natural enough in the framework I'm designing? I would suggest to look at some more complex cases where several `pcase' features appear combined. Making these complex cases not harder to read is important: a suitable replacement of `pcase' should be able to express what the code is doing in a similarly descriptive manner. [ I'm still skeptical there is so much room for improvement I must admit. ] I collected some more or less random examples that combine several `pcase' features and are not too long: ffap-other-window menu-bar-item-at-x completion-at-point byte-optimize-funcall byte-optimize-letX cl-typep I can help with the translation if this is desired. `macroexpand-1' can also help but of course it's more practical for the smaller examples. I think it would be good to try to translate such examples into the to-be-invented language before actually implementing all the details (top-down). Michael. ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-11-24 18:14 ` Michael Heerdegen @ 2023-11-24 18:35 ` Dmitry Gutov 2023-11-27 3:14 ` Richard Stallman 1 sibling, 0 replies; 342+ messages in thread From: Dmitry Gutov @ 2023-11-24 18:35 UTC (permalink / raw) To: Michael Heerdegen, Richard Stallman; +Cc: emacs-devel On 24/11/2023 20:14, Michael Heerdegen wrote: > byte-optimize-letX > cl-typep Nice examples. These two in particular showcase the benefit of terseness in the matching syntax: you can grasp the structure of the whole complicated function quickly when it fits on one screen. ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-11-24 18:14 ` Michael Heerdegen 2023-11-24 18:35 ` Dmitry Gutov @ 2023-11-27 3:14 ` Richard Stallman 2023-11-28 2:46 ` Richard Stallman 2023-12-10 15:14 ` Richard Stallman 1 sibling, 2 replies; 342+ messages in thread From: Richard Stallman @ 2023-11-27 3:14 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. ]]] > I collected some more or less random examples that combine several > `pcase' features and are not too long: > ffap-other-window > menu-bar-item-at-x > completion-at-point > byte-optimize-funcall > byte-optimize-letX > cl-typep Thanks. I will look at one or two of them tomorrow. > I would suggest to look at some more complex cases where several `pcase' > features appear combined. Would you like to pick one of them and see what rewriting it with cond* would look like? -- Dr Richard Stallman (https://stallman.org) Chief GNUisance of the GNU Project (https://gnu.org) Founder, Free Software Foundation (https://fsf.org) Internet Hall-of-Famer (https://internethalloffame.org) ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-11-27 3:14 ` Richard Stallman @ 2023-11-28 2:46 ` Richard Stallman 2023-11-28 6:35 ` Nikita Domnitskii 2023-12-10 15:14 ` Richard Stallman 1 sibling, 1 reply; 342+ messages in thread From: Richard Stallman @ 2023-11-28 2:46 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. ]]] (defun ffap-other-window (filename) "Like `ffap', but put buffer in another window. Only intended for interactive use." (interactive (list (ffap-prompter nil " other window"))) (pcase (save-window-excursion (find-file-at-point filename)) ((or (and (pred bufferp) b) `(,(and (pred bufferp) b) . ,_)) (switch-to-buffer-other-window b)))) I had to struggle to understand that use of pcase. Once I understood it, I found these ways to rewrite it. (cond* (:bind b1 (b (save-window-excursion (find-file-at-point filename)))) ((bufferp b) (setq b1 b)) ((bufferp (car-safe b)) (setq b1 (car-safe b)))) (if b1 (switch-to-buffer-other-window b))) (cond* (:bind b1 (b (save-window-excursion (find-file-at-point filename)))) ((bufferp b) (switch-to-buffer-other-window b)) ((bufferp (car-safe b)) (switch-to-buffer-other-window (car-safe b))))) I concluded it was essirable to give the macro `match-set' an optional third argument, which is an expression that does the job of what pcase calls a "guard". It is an ordinary Lisp expression. Also, to make `match-set' return t if it succeeded in matching. Thus I came up with this. (let ((b (save-window-excursion (find-file-at-point filename))) b1) (if (or (match-set b1 b (bufferp b1)) (match-set b1 (car-safe b) (bufferp b1))) (switch-to-buffer-other-window b1))) -- Dr Richard Stallman (https://stallman.org) Chief GNUisance of the GNU Project (https://gnu.org) Founder, Free Software Foundation (https://fsf.org) Internet Hall-of-Famer (https://internethalloffame.org) ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-11-28 2:46 ` Richard Stallman @ 2023-11-28 6:35 ` Nikita Domnitskii 2023-11-30 3:37 ` Richard Stallman 2023-12-02 21:37 ` Lynn Winebarger 0 siblings, 2 replies; 342+ messages in thread From: Nikita Domnitskii @ 2023-11-28 6:35 UTC (permalink / raw) To: rms, michael_heerdegen; +Cc: emacs-devel Richard Stallman <rms@gnu.org> writes: > (cond* (:bind b1 (b (save-window-excursion (find-file-at-point filename)))) > ((bufferp b) (setq b1 b)) > ((bufferp (car-safe b)) (setq b1 (car-safe b)))) > (if b1 (switch-to-buffer-other-window b))) > > (cond* (:bind b1 (b (save-window-excursion (find-file-at-point filename)))) > ((bufferp b) (switch-to-buffer-other-window b)) > ((bufferp (car-safe b)) (switch-to-buffer-other-window (car-safe b))))) > > (let ((b (save-window-excursion (find-file-at-point filename))) b1) > (if (or (match-set b1 b (bufferp b1)) > (match-set b1 (car-safe b) (bufferp b1))) > (switch-to-buffer-other-window b1))) To be honest all variants look less expressive than original pcase. Maybe instead of trying to implement cond* we should look into impoving pcase patterns? As a starting point I suggest Racket pattern matching implementation (which in my opinion is fairly readable): https://docs.racket-lang.org/reference/match.html -- Best Regards, Nikita Domnitskii ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-11-28 6:35 ` Nikita Domnitskii @ 2023-11-30 3:37 ` Richard Stallman 2023-12-02 21:37 ` Lynn Winebarger 1 sibling, 0 replies; 342+ messages in thread From: Richard Stallman @ 2023-11-30 3:37 UTC (permalink / raw) To: Nikita Domnitskii; +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. ]]] > To be honest all variants look less expressive than original > pcase. That is a strange thing to say -- "less expressive". Can you explain what "expressive" means to you? I am not sure whether that concept is one I think is desirable or perhaps the opposite of desirable. I suspect you mean they are less terse -- which is the flip side of the problem I'm planning to correct. -- Dr Richard Stallman (https://stallman.org) Chief GNUisance of the GNU Project (https://gnu.org) Founder, Free Software Foundation (https://fsf.org) Internet Hall-of-Famer (https://internethalloffame.org) ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-11-28 6:35 ` Nikita Domnitskii 2023-11-30 3:37 ` Richard Stallman @ 2023-12-02 21:37 ` Lynn Winebarger 1 sibling, 0 replies; 342+ messages in thread From: Lynn Winebarger @ 2023-12-02 21:37 UTC (permalink / raw) To: Nikita Domnitskii; +Cc: Richard Stallman, michael_heerdegen, emacs-devel [-- Attachment #1: Type: text/plain, Size: 3418 bytes --] On Tue, Nov 28, 2023, 8:54 AM Nikita Domnitskii <nikita@domnitskii.me> wrote: > Richard Stallman <rms@gnu.org> writes: > > > (cond* (:bind b1 (b (save-window-excursion (find-file-at-point > filename)))) > > ((bufferp b) (setq b1 b)) > > ((bufferp (car-safe b)) (setq b1 (car-safe b)))) > > (if b1 (switch-to-buffer-other-window b))) > > > > (cond* (:bind b1 (b (save-window-excursion (find-file-at-point > filename)))) > > ((bufferp b) (switch-to-buffer-other-window b)) > > ((bufferp (car-safe b)) (switch-to-buffer-other-window > (car-safe b))))) > > > > (let ((b (save-window-excursion (find-file-at-point filename))) b1) > > (if (or (match-set b1 b (bufferp b1)) > > (match-set b1 (car-safe b) (bufferp b1))) > > (switch-to-buffer-other-window b1))) > > To be honest all variants look less expressive than original > pcase. > > Maybe instead of trying to implement cond* we should look into impoving > pcase patterns? As a starting point I suggest Racket pattern matching > implementation (which in my opinion is fairly readable): > https://docs.racket-lang.org/reference/match.html A similar match package is available in guile: https://www.gnu.org/software/guile/manual/html_node/Pattern-Matching.html Indeed, I first saw "match" in a course on compiler theory around 2000. When I saw pcase I thought the author had based it on "match", but according to https://dl.acm.org/doi/pdf/10.1145/3386324 (Evolution of Emacs Lisp, p 37), that resemblance was, at least initially, accidental. As some others here have expressed, I find the use of "constructor syntax" for both construction (in a value position) and destructuring (in a binding position) aesthetically appealing. On the other hand, since pcase is in some ways an inverse operator to quasiquotation, I feel like the pattern clauses should be implicitly backquoted. Or, one might say, backquote introduces a value context for constructor syntax, but is not itself part of that constructor syntax, while unquote (comma) and unquote-splice (comma-at) operators are constructor syntax. Then pcase can be seen as introducing a binding context (i.e. similar to the"cond-let" form being discussed elsewhere). Read syntax could also be introduced to formalize the duality of the operators, say "`?". The documentation of the "bare" patterns (un-backquoted) is probably the most confusing part of the doc, especially with the "Caveats for symbol in pattern" section, but that's how pcase is introduced(!). That's where the confusing DSL is to me, since operators like "and" and "or" are redefined but act on patterns rather than values, but there's no visual prompt that this redefinition is in effect. A similar complaint might be levelled at ",(and ...)". If backquote and pcase were understood to introduce evaluation and binding contexts respectively for constructor syntax, then maybe the change in meaning would be more apparent? There are also macro expanders written explicitly for syntax pattern matching in Scheme. Those might be adapted if the core developers would prefer separate facilities for pattern matching used for compiling than "low-level" facilities made available everywhere. In a system like "syntax-case" the bindings made by the matcher are only available in the "syntax" constructor form, rather than bound as ordinary lexically-scoped variables. Lynn [-- Attachment #2: Type: text/html, Size: 4688 bytes --] ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-11-27 3:14 ` Richard Stallman 2023-11-28 2:46 ` Richard Stallman @ 2023-12-10 15:14 ` Richard Stallman 2023-12-10 16:27 ` Lynn Winebarger 1 sibling, 1 reply; 342+ messages in thread From: Richard Stallman @ 2023-12-10 15:14 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. ]]] I am trying to rewrite `byte-optimize-letX' with cond*, but I cannot understand its current definition. Specifically, I can't understand this pcase clause: ;; Body is last variable. (`(,head ,(and bindings (let last-var (caar (last bindings)))) ,(and last-var ; non-linear pattern (pred symbolp) (pred (not keywordp)) (pred (not booleanp)))) (if (eq head 'let) `(progn ,@(mapcar #'cadr bindings)) `(,head ,(butlast bindings) ,(cadar (last bindings))))) What case is it meant to handle? What does that case look like? The comments cited in that code make no sense to me; I don't know of any use of `let' or `let*' in which the body would be one of the variables, and their doc strings don't describe any new usage which would make that meaningful. -- Dr Richard Stallman (https://stallman.org) Chief GNUisance of the GNU Project (https://gnu.org) Founder, Free Software Foundation (https://fsf.org) Internet Hall-of-Famer (https://internethalloffame.org) ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-12-10 15:14 ` Richard Stallman @ 2023-12-10 16:27 ` Lynn Winebarger 2023-12-10 20:28 ` Michael Heerdegen via Emacs development discussions. 2023-12-11 3:31 ` Richard Stallman 0 siblings, 2 replies; 342+ messages in thread From: Lynn Winebarger @ 2023-12-10 16:27 UTC (permalink / raw) To: Richard Stallman; +Cc: Michael Heerdegen, emacs-devel [-- Attachment #1: Type: text/plain, Size: 1415 bytes --] On Sun, Dec 10, 2023, 10:14 AM Richard Stallman <rms@gnu.org> 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. ]]] > > I am trying to rewrite `byte-optimize-letX' with cond*, > but I cannot understand its current definition. > > Specifically, I can't understand this pcase clause: > > ;; Body is last variable. > (`(,head ,(and bindings > (let last-var (caar (last bindings)))) > ,(and last-var ; non-linear pattern > (pred symbolp) (pred (not keywordp)) (pred (not > booleanp)))) > (if (eq head 'let) > `(progn ,@(mapcar #'cadr bindings)) > `(,head ,(butlast bindings) ,(cadar (last bindings))))) > > What case is it meant to handle? What does that case look like? > The pattern would match a let or let* form that has bindings but no body. If it's a let form, the bindings are unused since only code in the body would see the bound variables. So the optimization is to transform the value expressions of the bindings into a progn. If it's a let* form, then the last bound variables would only be visible in the body, but there is none. Therefore, the last variable binding is eliminated and its value expression is made into the body. Lynn [-- Attachment #2: Type: text/html, Size: 2032 bytes --] ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-12-10 16:27 ` Lynn Winebarger @ 2023-12-10 20:28 ` Michael Heerdegen via Emacs development discussions. 2023-12-10 21:13 ` Lynn Winebarger 2023-12-12 3:43 ` Richard Stallman 2023-12-11 3:31 ` Richard Stallman 1 sibling, 2 replies; 342+ messages in thread From: Michael Heerdegen via Emacs development discussions. @ 2023-12-10 20:28 UTC (permalink / raw) To: emacs-devel Lynn Winebarger <owinebar@gmail.com> writes: > The pattern would match a let or let* form that has bindings but no > body. No - it matches where the body is the last variable. Not an empty body - right? With other words this case: #+begin_src emacs-lisp (byte-optimize-letX '(let ((a (+ 1 x)) (b (+ 2 x)) (c (+ 3 x))) c)) ; ==> (progn (+ 1 x) (+ 2 x) (+ 3 x)) (byte-optimize-letX '(let* ((a (+ 1 x)) (b (+ 2 a)) (c (+ 3 b))) c)) ;; ==> (let* ((a (+ 1 x)) (b (+ 2 a))) ;; (+ 3 b)) #+end_src Michael. ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-12-10 20:28 ` Michael Heerdegen via Emacs development discussions. @ 2023-12-10 21:13 ` Lynn Winebarger 2023-12-12 3:43 ` Richard Stallman 1 sibling, 0 replies; 342+ messages in thread From: Lynn Winebarger @ 2023-12-10 21:13 UTC (permalink / raw) To: Michael Heerdegen; +Cc: emacs-devel [-- Attachment #1: Type: text/plain, Size: 820 bytes --] On Sun, Dec 10, 2023, 3:28 PM Michael Heerdegen via Emacs development discussions. <emacs-devel@gnu.org> wrote: > Lynn Winebarger <owinebar@gmail.com> writes: > > > The pattern would match a let or let* form that has bindings but no > > body. > > No - it matches where the body is the last variable. Not an empty body > - right? > I stand corrected - looks like I miscounted parentheses and/or misunderstood the scoping rules of non-linear pattern variables. The reasoning for the validity of the transformation is essentially the same, except instead of no variable references in the body, there is exactly one variable reference. It seems like this could be generalized somewhat, particularly for let forms, but I'm guessing this particular case is frequently generated by macros or in the compiler itself. Lynn [-- Attachment #2: Type: text/html, Size: 1386 bytes --] ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-12-10 20:28 ` Michael Heerdegen via Emacs development discussions. 2023-12-10 21:13 ` Lynn Winebarger @ 2023-12-12 3:43 ` Richard Stallman 2023-12-12 6:46 ` Tomas Hlavaty ` (4 more replies) 1 sibling, 5 replies; 342+ messages in thread From: Richard Stallman @ 2023-12-12 3:43 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. ]]] I think whoever wrote that code in byte-optimize-letX was fascinated by the challenge of writing as much as possible in pcase language and minimizing use of Lisp. Here's my version, which I think is a lot clearer. It illustrates some of the flexibility of cond*: * Use of ordinary Lisp fir conditions, * Matching against different objects. * Clauses that bind and then drop through. (defun byte-optimize-letX (form) (cond* ;; Bindings list is empty. (:match (`(,_ () . ,body) form) `(progn . ,body)) ;; Decompose the form (:match (`(,head ,bindings . ,body) form)) ;; Body is empty or just contains a constant. (:match ((or `() `(,(macroexp-const-p const))) body) ;; If the match succeeds, it always binds CONST. (if (eq head 'let) `(progn ,@(mapcar #'cadr bindings) ,const) `(,head ,(butlast bindings) ,(cadar (last bindings)) ,const))) ;; Body does nothing but return the last variable in bindings. ((let ((last-var (car-safe (car (last bindings))))) ;; Next line could be written using `match', ;; but the clarity of this is worth one cons. (and (symbolp last-var) (equal body (list last-var)))) (if (eq head 'let) `(progn ,@(mapcar #'cadr bindings)) `(,head ,(butlast bindings) ,(cadar (last bindings))))) (t form))) -- Dr Richard Stallman (https://stallman.org) Chief GNUisance of the GNU Project (https://gnu.org) Founder, Free Software Foundation (https://fsf.org) Internet Hall-of-Famer (https://internethalloffame.org) ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-12-12 3:43 ` Richard Stallman @ 2023-12-12 6:46 ` Tomas Hlavaty 2023-12-12 15:18 ` [External] : " Drew Adams ` (3 subsequent siblings) 4 siblings, 0 replies; 342+ messages in thread From: Tomas Hlavaty @ 2023-12-12 6:46 UTC (permalink / raw) To: rms, Michael Heerdegen; +Cc: emacs-devel On Mon 11 Dec 2023 at 22:43, Richard Stallman <rms@gnu.org> wrote: > `(progn . ,body)) -> `(progn ,@body) those dots everywhere are ugly ^ permalink raw reply [flat|nested] 342+ messages in thread
* RE: [External] : Re: Instead of pcase 2023-12-12 3:43 ` Richard Stallman 2023-12-12 6:46 ` Tomas Hlavaty @ 2023-12-12 15:18 ` Drew Adams 2023-12-14 3:24 ` Richard Stallman 2023-12-12 19:24 ` Tomas Hlavaty ` (2 subsequent siblings) 4 siblings, 1 reply; 342+ messages in thread From: Drew Adams @ 2023-12-12 15:18 UTC (permalink / raw) To: rms@gnu.org, Michael Heerdegen; +Cc: emacs-devel@gnu.org > I think whoever wrote that code in byte-optimize-letX was fascinated > by the challenge of writing as much as possible in pcase language > and minimizing use of Lisp. > > Here's my version, which I think is a lot clearer. > > It illustrates some of the flexibility of cond*: > * Use of ordinary Lisp fir conditions, > * Matching against different objects. > * Clauses that bind and then drop through. > > (defun byte-optimize-letX (form) > (cond* > ;; Bindings list is empty. > (:match (`(,_ () . ,body) form) > `(progn . ,body)) > > ;; Decompose the form > (:match (`(,head ,bindings . ,body) form)) > > ;; Body is empty or just contains a constant. > (:match ((or `() `(,(macroexp-const-p const))) body) > ;; If the match succeeds, it always binds CONST. > (if (eq head 'let) > `(progn ,@(mapcar #'cadr bindings) ,const) > `(,head ,(butlast bindings) ,(cadar (last bindings)) ,const))) > > ;; Body does nothing but return the last variable in bindings. > ((let ((last-var (car-safe (car (last bindings))))) > ;; Next line could be written using `match', > ;; but the clarity of this is worth one cons. > (and (symbolp last-var) (equal body (list last-var)))) > (if (eq head 'let) > `(progn ,@(mapcar #'cadr bindings)) > `(,head ,(butlast bindings) ,(cadar (last bindings))))) > > (t form))) You might want to show the original, pcase, version at the same time, for comparison. ___ It might be clearer if clauses that can end the `cond*' are easily distinguished from those that always continue on to the next clause - their return value doesn't matter to the control flow (e.g., they just match/bind). Or is the former always the case if a clause contains two successive sexps? E.g., is the second clause above the only one that always "falls through" after performing its action (matching & binding)? If so, the absence or presence of a second sexp in a clause distinguishes the two cases enough, I guess. ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: [External] : Re: Instead of pcase 2023-12-12 15:18 ` [External] : " Drew Adams @ 2023-12-14 3:24 ` Richard Stallman 2023-12-14 16:52 ` Drew Adams 0 siblings, 1 reply; 342+ messages in thread From: Richard Stallman @ 2023-12-14 3:24 UTC (permalink / raw) To: Drew Adams; +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. ]]] > It might be clearer if clauses that can end > the `cond*' are easily distinguished from > those that always continue on to the next > clause - their return value doesn't matter to > the control flow (e.g., they just match/bind). That is rather abstract, and I am not sure what idea you are proposing. If you send a specific proposal I can think about it. > Or is the former always the case if a clause > contains two successive sexps? I am not sure what "the former" refers to. Could you please state your point in a way that takes less work to understand? p -- Dr Richard Stallman (https://stallman.org) Chief GNUisance of the GNU Project (https://gnu.org) Founder, Free Software Foundation (https://fsf.org) Internet Hall-of-Famer (https://internethalloffame.org) ^ permalink raw reply [flat|nested] 342+ messages in thread
* RE: [External] : Re: Instead of pcase 2023-12-14 3:24 ` Richard Stallman @ 2023-12-14 16:52 ` Drew Adams 2023-12-16 4:24 ` Richard Stallman 0 siblings, 1 reply; 342+ messages in thread From: Drew Adams @ 2023-12-14 16:52 UTC (permalink / raw) To: rms@gnu.org; +Cc: michael_heerdegen@web.de, emacs-devel@gnu.org > > It might be clearer if clauses that can end > > the `cond*' are easily distinguished from > > those that always continue on to the next > > clause - their return value doesn't matter to > > the control flow (e.g., they just match/bind). > > That is rather abstract, and I am not sure what idea you are > proposing. If you send a specific proposal I can think about it. I'm not proposing anything there. I'm saying that your introduction of fall-through clauses that can't end the cond* (and thus provide its value) introduces complexity and can cause confusion. In terms of a proposal: If you're going to allow clauses that just "fall through" (e.g. only match & bind), then (1) tell users how to easily recognize them and (2) maybe even add something syntactic that distinguishes them more easily. > > Or is the former always the case if a clause > > contains two successive sexps? > > I am not sure what "the former" refers to. Could you please state > your point in a way that takes less work to understand? "Former" here refers to clauses that can end the cond*. The "latter" kind of clauses cannot; they always "fall through" (whether or not they perform some action, such as matching/binding). What distinguishes a clause that can end the cond*? How can you tell immediately, independent of what some sexp is/does, whether the clause it's in can possibly end the cond* and provide its return value? That's my question. I guessed that this possibility is the case whenever a clause contains only _one sexp_. If so, that's OK, but then say that. And even so, it might be good to have some clearer indication, to distinguish such clauses. Others have already spoken to the oddity of clauses that can "fall through", that can't, themselves, end the cond*. Make it clearer when this is the case - especially for a construct whose name is so similar to cond's. In a traditional `cond' each clause can potentially end the cond and provide its return value. ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: [External] : Re: Instead of pcase 2023-12-14 16:52 ` Drew Adams @ 2023-12-16 4:24 ` Richard Stallman 2023-12-16 5:04 ` Drew Adams 0 siblings, 1 reply; 342+ messages in thread From: Richard Stallman @ 2023-12-16 4:24 UTC (permalink / raw) To: Drew Adams; +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. ]]] > In terms of a proposal: If you're going to allow > clauses that just "fall through" (e.g. only match & > bind), then (1) tell users how to easily recognize > them The file says this. In this version, each clause exits if it contains more than one element (after the possible keyword), and falls through otherwise. I think that is clear and simple. I don't know if I have posted that part. and (2) maybe even add something syntactic that > distinguishes them more easily. There are many ways to do that. Which would you propose? -- Dr Richard Stallman (https://stallman.org) Chief GNUisance of the GNU Project (https://gnu.org) Founder, Free Software Foundation (https://fsf.org) Internet Hall-of-Famer (https://internethalloffame.org) ^ permalink raw reply [flat|nested] 342+ messages in thread
* RE: [External] : Re: Instead of pcase 2023-12-16 4:24 ` Richard Stallman @ 2023-12-16 5:04 ` Drew Adams 2023-12-16 18:30 ` Bob Rogers 0 siblings, 1 reply; 342+ messages in thread From: Drew Adams @ 2023-12-16 5:04 UTC (permalink / raw) To: rms@gnu.org; +Cc: michael_heerdegen@web.de, emacs-devel@gnu.org > > In terms of a proposal: If you're going to allow > > clauses that just "fall through" (e.g. only match & > > bind), then (1) tell users how to easily recognize > > them > > The file says this. > > In this version, each clause exits if it contains more than one > element (after the possible keyword), and falls through otherwise. > > I think that is clear and simple. I don't know if I have posted that > part. That's what I guessed. Stating it explicitly gives users something quick to look for, to more easily parse things. > > and (2) maybe even add something syntactic that > > distinguishes them more easily. > > There are many ways to do that. Which would you propose? I don't have a concrete suggestion, but I do think _some_ syntactic indication would help, as opposed to discerning whether there's only one sexp. (Not that that's hard to do, but it that difference doesn't "saute aux yeux".) ^ permalink raw reply [flat|nested] 342+ messages in thread
* RE: [External] : Re: Instead of pcase 2023-12-16 5:04 ` Drew Adams @ 2023-12-16 18:30 ` Bob Rogers 2023-12-18 4:13 ` Richard Stallman 0 siblings, 1 reply; 342+ messages in thread From: Bob Rogers @ 2023-12-16 18:30 UTC (permalink / raw) To: Drew Adams; +Cc: rms@gnu.org, michael_heerdegen@web.de, emacs-devel@gnu.org From: Drew Adams <drew.adams@oracle.com> Date: Sat, 16 Dec 2023 05:04:43 +0000 [re cond* fall-through behavior:] > > and (2) maybe even add something syntactic that > > distinguishes them more easily. > > There are many ways to do that. Which would you propose? I don't have a concrete suggestion, but I do think _some_ syntactic indication would help, as opposed to discerning whether there's only one sexp. (Not that that's hard to do, but it that difference doesn't "saute aux yeux".) Suppose clauses only fall through if the last form is the literal symbol :fall-through ? That is wordier and perhaps less elegant, but it would make cond* more consistent with cond, and make the fall-through behavior less apt to surprise. (And apologies if this turns out to be infeasible due to some other constraint; I've only been half following this thread.) -- Bob Rogers http://www.rgrjr.com/ ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: [External] : Re: Instead of pcase 2023-12-16 18:30 ` Bob Rogers @ 2023-12-18 4:13 ` Richard Stallman 0 siblings, 0 replies; 342+ messages in thread From: Richard Stallman @ 2023-12-18 4:13 UTC (permalink / raw) To: Bob Rogers; +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. ]]] > Suppose clauses only fall through if the last form is the literal symbol > :fall-through ? I'm not absolutely against it, but I think people will get used to fall-throgh clauses based on having one element. I'd like people to try to do that, so we can see whether people do become used to it. -- Dr Richard Stallman (https://stallman.org) Chief GNUisance of the GNU Project (https://gnu.org) Founder, Free Software Foundation (https://fsf.org) Internet Hall-of-Famer (https://internethalloffame.org) ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-12-12 3:43 ` Richard Stallman 2023-12-12 6:46 ` Tomas Hlavaty 2023-12-12 15:18 ` [External] : " Drew Adams @ 2023-12-12 19:24 ` Tomas Hlavaty 2023-12-12 21:36 ` [External] : " Drew Adams 2023-12-13 1:32 ` Adam Porter 2023-12-13 4:58 ` Richard Stallman 4 siblings, 1 reply; 342+ messages in thread From: Tomas Hlavaty @ 2023-12-12 19:24 UTC (permalink / raw) To: rms, Michael Heerdegen; +Cc: emacs-devel in plain lisp with much clearer control-flow (not tested): (defun byte-optimize-letX (form) (if (consp form) (let ((head (car form)) (bindings (cadr form)) (body (cddr form))) (if bindings (let ((const (car body)) (rest (cdr body))) (if (or (not body) (and (macroexp-const-p const) (not rest))) ;; Body is empty or a constant. (if (eq head 'let) `(progn ,@(mapcar #'cadr bindings) ,const) `(,head ,(butlast bindings) ,(cadar (last bindings)) ,const)) (if (let ((last-var (car-safe (car (last bindings))))) (and (symbolp last-var) (equal body (list last-var)))) ;; Body does nothing but return the last variable in bindings. (if (eq head 'let) `(progn ,@(mapcar #'cadr bindings)) `(,head ,(butlast bindings) ,(cadar (last bindings)))) form)) ;; Bindings list is empty. `(progn ,@body))) form))) ^ permalink raw reply [flat|nested] 342+ messages in thread
* RE: [External] : Re: Instead of pcase 2023-12-12 19:24 ` Tomas Hlavaty @ 2023-12-12 21:36 ` Drew Adams 2023-12-12 22:25 ` Michael Heerdegen via Emacs development discussions. 0 siblings, 1 reply; 342+ messages in thread From: Drew Adams @ 2023-12-12 21:36 UTC (permalink / raw) To: Tomas Hlavaty, rms@gnu.org, Michael Heerdegen; +Cc: emacs-devel@gnu.org > in plain lisp with much clearer control-flow (not tested): > > (defun byte-optimize-letX (form) > (if (consp form) > (let ((head (car form)) > (bindings (cadr form)) > (body (cddr form))) > (if bindings > (let ((const (car body)) > (rest (cdr body))) > (if (or (not body) > (and (macroexp-const-p const) > (not rest))) > ;; Body is empty or a constant. > (if (eq head 'let) > `(progn > ,@(mapcar #'cadr bindings) > ,const) > `(,head > ,(butlast bindings) > ,(cadar (last bindings)) ,const)) > (if (let ((last-var (car-safe (car (last bindings))))) > (and (symbolp last-var) > (equal body (list last-var)))) > ;; Body does nothing but return the last variable in > bindings. > (if (eq head 'let) > `(progn > ,@(mapcar #'cadr bindings)) > `(,head > ,(butlast bindings) > ,(cadar (last bindings)))) > form)) > ;; Bindings list is empty. > `(progn ,@body))) > form))) <nit> Maybe a little clearer than (if (consp xxx) (huge tree sexp) xxx) is (if (atom xxx) xxx (huge tree sexp)) I think more than a few folks forget about `atom', for some reason. (Sometimes I see (not (consp xxx)) or even (!) (null (consp xxx)).) </nit> ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: [External] : Re: Instead of pcase 2023-12-12 21:36 ` [External] : " Drew Adams @ 2023-12-12 22:25 ` Michael Heerdegen via Emacs development discussions. 0 siblings, 0 replies; 342+ messages in thread From: Michael Heerdegen via Emacs development discussions. @ 2023-12-12 22:25 UTC (permalink / raw) To: emacs-devel Drew Adams <drew.adams@oracle.com> writes: > I think more than a few folks forget about `atom', for > some reason. (Sometimes I see (not (consp xxx)) or > even (!) (null (consp xxx)).) That should be (listp (consp xxx)) of course. Michael. ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-12-12 3:43 ` Richard Stallman ` (2 preceding siblings ...) 2023-12-12 19:24 ` Tomas Hlavaty @ 2023-12-13 1:32 ` Adam Porter 2023-12-14 3:23 ` Richard Stallman ` (3 more replies) 2023-12-13 4:58 ` Richard Stallman 4 siblings, 4 replies; 342+ messages in thread From: Adam Porter @ 2023-12-13 1:32 UTC (permalink / raw) To: rms; +Cc: emacs-devel Hi Richard, > I think whoever wrote that code in byte-optimize-letX was fascinated > by the challenge of writing as much as possible in pcase language > and minimizing use of Lisp. > > Here's my version, which I think is a lot clearer. > > It illustrates some of the flexibility of cond*: > * Use of ordinary Lisp fir conditions, > * Matching against different objects. > * Clauses that bind and then drop through. Respectfully, I disagree that this example is clearer than the original pcase form.[0] I'll explain why: > (defun byte-optimize-letX (form) > (cond* > ;; Bindings list is empty. > (:match (`(,_ () . ,body) form) > `(progn . ,body)) This is nearly identical to the equivalent pcase syntax, only adding `:match'. Since pcase's (and I suppose cond*'s) purpose is pattern matching, this seems redundant and unnecessarily verbose. > ;; Decompose the form > (:match (`(,head ,bindings . ,body) form)) I suppose it is largely a matter of taste, but I strongly dislike fall-through clauses. While it seems convenient here, as it allows the removal of either a redundancy (reiterating bindings in multiple clauses) or a level of nesting, its bindings are also implicit rather than explicit, as the scope of the binding form is not enclosed by visible boundaries (i.e. parens). One also wonders what it would look like if such a cond* form had multiple, overlapping fall-through bindings of the same variables--that would seem to be necessary in some cases, and would likely be confusing. Finally, forms which allow fall-through clauses are known to be more prone to human error than forms which don't allow them--and they don't seem syntactically "lispy." So I think this is more confusing than pcase, not less. > ;; Body is empty or just contains a constant. > (:match ((or `() `(,(macroexp-const-p const))) body) This seems even more confusing to me. The equivalent pcase form is: `(,head ,bindings . ,(or '() `(,(and const (pred macroexp-const-p))))) While the `and' keyword's being used to bind `const' may be surprising to those unfamiliar with pcase,[1] at least it explicitly binds the form to the variable before using it, and the scope of the binding is visible (being within that clause). In contrast, the cond* example appears to implicitly bind `const' by the symbol's being present in the predicate form as an argument. This seems much less clear to me. It also seems error-prone, as in a case where `const' were already bound. As well, what if the user needed to pass an already-bound argument in addition to the one being bound there? With pcase, the binding would be explicit, and the accompanying `guard' expression would have a clear place in lexical scope, so there would be no doubt about where the arguments were bound. With cond*, would the binding apply to the first argument symbol or a later one? If the goal is to avoid implicit rather than explicit behavior, that seems contrary to the goal. For these reasons, this seems more confusing to me than pcase, not less. Sincerely, Adam 0: https://git.savannah.gnu.org/cgit/emacs.git/tree/lisp/emacs-lisp/byte-opt.el?id=75fd7550ed6cede6c9e8224f1f2d62637c43fdd4#n1459 1: Perhaps we could recommend a minor change to pcase that might improve understanding: a `bind' keyword could be used to explicitly bind variables, rather than only having the implied binding from the `and' keyword (since `let' already has a different purpose in pcase). So the example from earlier could look like: `(,head ,bindings . ,(or '() `(,(and (bind const) (guard (macroexp-const-p const)))))) ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-12-13 1:32 ` Adam Porter @ 2023-12-14 3:23 ` Richard Stallman 2023-12-16 4:23 ` Richard Stallman ` (2 subsequent siblings) 3 siblings, 0 replies; 342+ messages in thread From: Richard Stallman @ 2023-12-14 3:23 UTC (permalink / raw) To: Adam Porter; +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. ]]] > One also wonders what it would look like if such a cond* form had > multiple, overlapping fall-through bindings of the same variables--that > would seem to be necessary in some cases, and would likely be confusing. Why would someone write duplicate drop-through clauses in a single cond* form? It looks like you think there is some reason, but I can't guess it. -- Dr Richard Stallman (https://stallman.org) Chief GNUisance of the GNU Project (https://gnu.org) Founder, Free Software Foundation (https://fsf.org) Internet Hall-of-Famer (https://internethalloffame.org) ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-12-13 1:32 ` Adam Porter 2023-12-14 3:23 ` Richard Stallman @ 2023-12-16 4:23 ` Richard Stallman 2023-12-18 4:09 ` cond* Richard Stallman 2023-12-18 4:09 ` cond* Richard Stallman 2023-12-16 4:23 ` Instead of pcase Richard Stallman 2023-12-16 4:23 ` Richard Stallman 3 siblings, 2 replies; 342+ messages in thread From: Richard Stallman @ 2023-12-16 4:23 UTC (permalink / raw) To: Adam Porter; +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. ]]] > > (defun byte-optimize-letX (form) > > (cond* > > ;; Bindings list is empty. > > (:match (`(,_ () . ,body) form) > > `(progn . ,body)) > This is nearly identical to the equivalent pcase syntax, only adding > `:match'. Since pcase's (and I suppose cond*'s) purpose is pattern > matching, this seems redundant and unnecessarily verbose. That's right. pcase has only one kind of clause, and all clauses match against one single value. cond* is more powerful and therefore it requires keywords to specify non-cond clauses. > > ;; Decompose the form > > (:match (`(,head ,bindings . ,body) form)) > I suppose it is largely a matter of taste, but I strongly dislike > fall-through clauses. While it seems convenient here, as it allows the > removal of either a redundancy (reiterating bindings in multiple > clauses) or a level of nesting, its bindings are also implicit rather > than explicit, as the scope of the binding form is not enclosed by > visible boundaries (i.e. parens). These bindings run from the place they are made to the closeparen at the end of the containing cond*. I think those bounds are easy to see. The use of a fall-through :match clause avoids the need to bind the variables separately for each clause, and the chance that they may differ (not incorrectly, but perhaps confusingly) in different clauses. However, it shares with pcase the design idea that variables to be bound by pattern matching are buried inside of a pattern, not centralized in one list that makes them easy to find. If people generally find that confusing, perhaps it would be good to change the fall-through :match clause so that the variables to be bound _must_ be listed "redundantly" in a previous :bind clause. This would make the code a little longer but make it easier to read. > > ;; Body is empty or just contains a constant. > > (:match ((or `() `(,(macroexp-const-p const))) body) > This seems even more confusing to me. The equivalent pcase form is: > `(,head ,bindings . ,(or '() `(,(and const (pred macroexp-const-p))))) I think the cond* method is simpler. (macroexp-const-p const) is both simpler and more natural than (and const (pred macroexp-const-p)). -- Dr Richard Stallman (https://stallman.org) Chief GNUisance of the GNU Project (https://gnu.org) Founder, Free Software Foundation (https://fsf.org) Internet Hall-of-Famer (https://internethalloffame.org) ^ permalink raw reply [flat|nested] 342+ messages in thread
* cond* 2023-12-16 4:23 ` Richard Stallman @ 2023-12-18 4:09 ` Richard Stallman 2023-12-18 10:08 ` cond* João Távora 2023-12-19 3:49 ` cond* Richard Stallman 2023-12-18 4:09 ` cond* Richard Stallman 1 sibling, 2 replies; 342+ messages in thread From: Richard Stallman @ 2023-12-18 4:09 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. ]]] I've made cond*'s syntax more Lispy by changing (:match (PATTERN DATA) to ((match* PATTERN DATA) and likewise (:bind VARLIST to ((bind* VARLIST...) This means that cond* no longer uses keywords itself. This simplifies the criterion for a fall-through clause: it has one exactly element. The proposed macros `match' and `match-bind' are not necessary because you can use (cond* ((match* PATTERN DATA) t)) and (cond* ((match* PATTERN DATA) BODY...)) which are hardly more complex to use. So I have eliminated those macros from the proposal. I've tentatively added a new kind of clause, ((match-set* PATTERN DATA) which sets pattern variables without binding them. That can be used instead of the previously proposed macro, `match-set'. But I am not sure whether this feature is really worth its added complexity. Maybe in the end it should be omitted. Each clause exits if it contains more than one element, and falls through otherwise. (cond* ;; Same as a clause in `cond', (CONDITION DO-THIS-IF-TRUE-THEN-EXIT...) ;; Execute FORM and ignore its value. (FORM) ;; Variables to bind, as in let*, around the rest ;; of the cond*. ((bind* (x foobar) y z (foo 5) a)) ;; Bindings continue in effect for the whole cond* construct. ;; Bind variables for the clause, as in let*. ((bind* (foo 5) (condition (hack-it foo))) ;; condition is that the last variable bound be non-nil. BODY...) ;; Bindings no longer in effect. ;; Extracts substructure and binds variables for the clause. ((match* `(expt ,foo ,bar) x) DO-THIS-IF-IT-MATCHED-THEN-EXIT...) ;; Bindings no longer in effect. ;; Extracts substructure and binds variables ;; for the rest of the cond*. ;; Like above but always falls thru to next clause. ;; All the variables mentioned in the pattern ;; are bound whether match succeeds or not. ;; If a value can be determined from an incomplete match, ;; the variable gets that value. ((match* `(expt ,foo ,bar) x)) ;; Bindings continue in effect. ;; Another example of fall-through match* clause. ;; All the variables mentioned in the pattern ;; are bound in all cases. ((match* (or `() `(,macroexp-const-p const)) body) ;; The `match-set*' is a tentative proposal. It may not be worth including. ;; Extracts substructure and sets variables if match succeeds ((match-set* `(expt ,foo ,bar) x) DO-THIS-IF-IT-MATCHED-THEN-EXIT...) ;; Extracts substructure and sets variables without binding them. ;; Always falls thru to next clause. ((match-set* `(expt ,foo ,bar) x)) ) To execute several expressions and not exit, use this: ((progn DO-THIS-UNCONDITIONALLY-AND-DONT-STOP...) To test a condition and return its value if non-nil, use this: ((bind* (value CONDITION)) value) That has a small fixed amount of extra complexity compared with a one-element cond clause, but given that those are not very common, this is a small price to pay. \f **Possible types of patterns for match*. CONSTANT: nil, t, a keyword, a quoted constant other than a cons cell, fixed parts of a backquote. This matches any value equal to CONSTANT. _ _ means to match any value and not store it anywhere. VARIABLE: a symbol A symbol means to match any value and set VARIABLE to it. A quoted cons cell The car and the cdr are subpattenrs. The cons cell pattern matches any cons cell whose car and cdr match those two subpatterns. How nil as a cdr matches is controlled by the match-nil flag. When the nil-match-all flag is false, nil as a cdr matches only nil itself. When the nil-match-all flag is true, nil as a cdr matches any object and ignores that object. The nil-match-all flag is false by default. The `cdr' pattern maks it false within its its subpattern, and the `cdr-safe' pattern makes it true forwithin its its subpattern. (cdr-safe QUOTED-CONS-CELL) This pattern is equivalent to QUOTED-CONS-CELL by itself except that it makes the nil-match-all flag true within it. (cdr-safe `(a b)) matches (a b), (a b c), (a b . d), etc. (cdr QUOTED-CONS-CELL) This pattern is equivalent to QUOTED-CONS-CELL by itself except that it makes the nil-match-all flag false within it. (cdr `(a b)) matches only (a b). Constrained variable: (TESTFN VARIABLE OTHER-ARGS...) This matches any value VALUE provided (TESTFN VALUE OTHER-ARGS...) evaluates to true. If so, it sets VARIABLE to VALUE. (symbolp sym) Match any symbol, store it in `sym'. (> num-foos 1) Match any thing greater than 1, store it in `num-foos'. When matching to bind variables, this pattern unconditionally binds VARIABLE whether it matches or not. `quote', `constrain' and `or' cannot be used as TESTFN. Constrained variable constructs can be nested. For example, (< (numberp num-foos) 1) Match any number > 1, store it in mum-foos. General constrained variable: (constrain VAR EXPRESSION) This general constrained variable pattern binds VAR to the value being matched against, only for evaluating EXPRESSION. If the result is non-nil, the match succeeds and sets VAR to the value. For instance, (constrain x (and (> x 0) (< x 100))) Alternatives: (or SUBPATTERNS...) This tries to match each of the SUBPATTERNS in order until one matches. If the pattern is being used to bind variables, it binds all the variables specified in any of SUBPATTERNS -- Dr Richard Stallman (https://stallman.org) Chief GNUisance of the GNU Project (https://gnu.org) Founder, Free Software Foundation (https://fsf.org) Internet Hall-of-Famer (https://internethalloffame.org) ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: cond* 2023-12-18 4:09 ` cond* Richard Stallman @ 2023-12-18 10:08 ` João Távora 2023-12-21 4:20 ` cond* Richard Stallman 2023-12-19 3:49 ` cond* Richard Stallman 1 sibling, 1 reply; 342+ messages in thread From: João Távora @ 2023-12-18 10:08 UTC (permalink / raw) To: rms; +Cc: emacs-devel I think you definitely need to work on this part: ;; Extracts substructure and binds variables for the clause. ((match* `(expt ,foo ,bar) x) DO-THIS-IF-IT-MATCHED-THEN-EXIT...) ;; Bindings no longer in effect. ;; Extracts substructure and binds variables ;; for the rest of the cond*. ;; Like above but always falls thru to next clause. ;; All the variables mentioned in the pattern ;; are bound whether match succeeds or not. ;; If a value can be determined from an incomplete match, ;; the variable gets that value. ((match* `(expt ,foo ,bar) x)) (t (something-that-depends-on FOO BAR) ; is this how to use it? ) am I going to use BAR and FOO in a form that is not contained in any form that declares BAR and FOO as they are matched and bound? This would seem to be an unhygienic macro, it's asking for trouble and confuses the user's reading of byte compiler output, which is currently very competent at catching unused and potentially unbound variables (which become especially evident when flymake-mode is used) João ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: cond* 2023-12-18 10:08 ` cond* João Távora @ 2023-12-21 4:20 ` Richard Stallman 2023-12-21 9:50 ` cond* João Távora 2023-12-21 14:10 ` cond* Ihor Radchenko 0 siblings, 2 replies; 342+ messages in thread From: Richard Stallman @ 2023-12-21 4:20 UTC (permalink / raw) To: João Távora; +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. ]]] > am I going to use BAR and FOO Are you talking about this? (cond* ((match* `(expt ,foo ,bar) x)) (t (something-that-depends-on FOO BAR) ; is this how to use it? ) in a form that is not contained > in any form that declares BAR and FOO as they are matched > and bound? "Declares BAR and FOO as they are matched and bound" is somewhat stramge usage of those words. It is not entirely clear what that means. And I am not sure what code you are talking about. What you quoted is not an example of code. It presents various sorts of clauses that a cond* can contain, but not meant as one cond* expression. Those clauses do not try to work together validly. So you're judging them by a criterion they do not try to fit. This tries to be a real example: (defun byte-optimize-letX (form) (cond* ;; Bindings list is empty. ((match* `(,_ () . ,body) form) `(progn . ,body)) ;; Decompose the form ((match* `(,head ,bindings . ,body) form)) ;; Body is empty or just contains a constant. ((match* (or `() `(,(macroexp-const-p const))) body) ;; If the match succeeds, it always binds CONST. (if (eq head 'let) `(progn ,@(mapcar #'cadr bindings) ,const) `(,head ,(butlast bindings) ,(cadar (last bindings)) ,const))) ;; Body does nothing but return the last variable in bindings. ((let ((last-var (car-safe (car (last bindings))))) ;; Next line could be written using `match', ;; but the clarity of this is worth one cons. (and (symbolp last-var) (equal body (list last-var)))) (if (eq head 'let) `(progn ,@(mapcar #'cadr bindings)) `(,head ,(butlast bindings) ,(cadar (last bindings))))) (t form))) head, bindings and body are bound in the cond* form, as specified by the fall-through second clause, and they can be used in the rest of the cond* clause. -- Dr Richard Stallman (https://stallman.org) Chief GNUisance of the GNU Project (https://gnu.org) Founder, Free Software Foundation (https://fsf.org) Internet Hall-of-Famer (https://internethalloffame.org) ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: cond* 2023-12-21 4:20 ` cond* Richard Stallman @ 2023-12-21 9:50 ` João Távora 2023-12-21 16:01 ` [External] : cond* Drew Adams 2023-12-24 3:57 ` cond* Richard Stallman 2023-12-21 14:10 ` cond* Ihor Radchenko 1 sibling, 2 replies; 342+ messages in thread From: João Távora @ 2023-12-21 9:50 UTC (permalink / raw) To: rms; +Cc: emacs-devel On Thu, Dec 21, 2023 at 4:20 AM Richard Stallman <rms@gnu.org> wrote: > Are you talking about this? > > (cond* > ((match* `(expt ,foo ,bar) x)) > (t > (something-that-depends-on FOO BAR) ; is this how to use it? > ) Yes. It is very simple. In Elisp or any Lisp I know, forms that introduce bindings are also the containers of any forms that use such bindings, most notable case being (let VARLIST BODY...) This principle is not a cosmetic convention. It's essential as it makes things like following the 'foo' in: (dolist (foo '(1)) (funcall (lambda (foo) (let ((foo 2)) (message "%" foo))) 3)) easy, even to the beginner, because one just travels up the form tree to a notable binding-introducing form. A given match* form in a given use of your cond* doesn't have this property. It introduces bindings that can be used by other forms _outside_ it and this leads to ambiguity. Adam noted this too. > So you're judging them by a criterion they do not try to fit. Well, I can't guess your intent, but I can tell you skipping this criterion is a bad idea, IMO. João ^ permalink raw reply [flat|nested] 342+ messages in thread
* RE: [External] : Re: cond* 2023-12-21 9:50 ` cond* João Távora @ 2023-12-21 16:01 ` Drew Adams 2023-12-21 16:20 ` João Távora 2023-12-24 3:56 ` Richard Stallman 2023-12-24 3:57 ` cond* Richard Stallman 1 sibling, 2 replies; 342+ messages in thread From: Drew Adams @ 2023-12-21 16:01 UTC (permalink / raw) To: João Távora, rms@gnu.org; +Cc: emacs-devel@gnu.org > A given match* form in a given use of your cond* doesn't have this > property. It introduces bindings that can be used by other forms > _outside_ it and this leads to ambiguity. Adam noted this too. Maybe you meant Drew (Adams), not Adam (Porter). In any case, yes, that's something I pointed out. It's the reason I suggested putting all sexps that only match/bind, i.e., sexps that can never end the `cond*' and provide its value, inside a clause that _can_ do that (i.e., a clause that's not match/bind-only). And to Richard's objection to that: Yes, it must be made clear (e.g. in the doc) that a sexp that only matches/binds applies to _everything_ that follows it in the `cond*', not just to the one clause in which it occurs. And I asked the question (no response yet) of whether there is ever any need/intention to provide for match/bind-only sexps that are _local_ to a given clause, i.e., their bindings don't exist (are undone) outside that clause. If there is such a need/intention, then how to indicate that? The obvious way would be the syntax I suggested above (for non-local use): just put that match/bind-only sexp inside the clause to which it's local. In that case, some other syntax would be needed for the "global" case (i.e., for a binding that applies to subsequent clauses as well). If not (no need for locals), then saying that a binding applies to both the current clause and subsequent clauses still makes sense. ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: [External] : Re: cond* 2023-12-21 16:01 ` [External] : cond* Drew Adams @ 2023-12-21 16:20 ` João Távora 2023-12-24 3:56 ` Richard Stallman 1 sibling, 0 replies; 342+ messages in thread From: João Távora @ 2023-12-21 16:20 UTC (permalink / raw) To: Drew Adams; +Cc: rms@gnu.org, emacs-devel@gnu.org On Thu, Dec 21, 2023 at 4:01 PM Drew Adams <drew.adams@oracle.com> wrote: > > > A given match* form in a given use of your cond* doesn't have this > > property. It introduces bindings that can be used by other forms > > _outside_ it and this leads to ambiguity. Adam noted this too. > > Maybe you meant Drew (Adams), not Adam (Porter). > In any case, yes, that's something I pointed out. I really meant Adam, as I _think_ he (also) pointed it out. But if you also did, that's good! João ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: [External] : Re: cond* 2023-12-21 16:01 ` [External] : cond* Drew Adams 2023-12-21 16:20 ` João Távora @ 2023-12-24 3:56 ` Richard Stallman 1 sibling, 0 replies; 342+ messages in thread From: Richard Stallman @ 2023-12-24 3:56 UTC (permalink / raw) To: Drew Adams; +Cc: joaotavora, 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. ]]] > And I asked the question (no response yet) of > whether there is ever any need/intention to > provide for match/bind-only sexps that are > _local_ to a given clause, i.e., their bindings > don't exist (are undone) outside that clause. I saw that message, but I didn't notice that question then. I saw only a proposal for a syntax that would insert a non-exit clause inside the following ordinary clause. My reply was that that syntax seemed unnatural for what the feature does. Now I see you meant to propose a different feature, one which would make bindings that apply only to the following clause. Such a feature could occasionally be useful, but not useful enough to justify adding an additional feature. It would not be an adequate replacement for the non-exit clause feature. I've chosen the term "non-exit clause" because that name states the feature's overall effect, and its purpose. "Falling through" is just a part of the effect. -- Dr Richard Stallman (https://stallman.org) Chief GNUisance of the GNU Project (https://gnu.org) Founder, Free Software Foundation (https://fsf.org) Internet Hall-of-Famer (https://internethalloffame.org) ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: cond* 2023-12-21 9:50 ` cond* João Távora 2023-12-21 16:01 ` [External] : cond* Drew Adams @ 2023-12-24 3:57 ` Richard Stallman 1 sibling, 0 replies; 342+ messages in thread From: Richard Stallman @ 2023-12-24 3:57 UTC (permalink / raw) To: João Távora; +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. ]]] > > Are you talking about this? > > > > (cond* > > ((match* `(expt ,foo ,bar) x)) > > (t > > (something-that-depends-on FOO BAR) ; is this how to use it? > > ) > Yes. It is very simple. In Elisp or any Lisp I know, forms that > introduce bindings are also the containers of any forms that use > such bindings, most notable case being (let VARLIST BODY...) The that introduces these bindings is let, and it also contains them. Likewise for cond*. match* and bind* are not independent constructs -- they are defined as part of cond*. They are used within a cond* to specify the bindings for it. It is a little more complex than the way let* makes bindings but not very different. This is a generalization of a feature of pcase. A pcase clause's pattern may specify bindings that are not contained within that pattern. They are contained within the pcase form. The same is true for cond*, but since it has different kinds of clauses, match* and bind* identify clauses whose first element can make bindings. These bindings are specified by part of the cond* form and contained within the cond* form. (Formerly I proposed the keywords :match and :bind to mark this, but it's equivalent except for syntax.) -- Dr Richard Stallman (https://stallman.org) Chief GNUisance of the GNU Project (https://gnu.org) Founder, Free Software Foundation (https://fsf.org) Internet Hall-of-Famer (https://internethalloffame.org) ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: cond* 2023-12-21 4:20 ` cond* Richard Stallman 2023-12-21 9:50 ` cond* João Távora @ 2023-12-21 14:10 ` Ihor Radchenko 2023-12-24 3:57 ` cond* Richard Stallman 1 sibling, 1 reply; 342+ messages in thread From: Ihor Radchenko @ 2023-12-21 14:10 UTC (permalink / raw) To: rms; +Cc: João Távora, emacs-devel Richard Stallman <rms@gnu.org> writes: > ... > This tries to be a real example: > > (defun byte-optimize-letX (form) > (cond* > ... > ;; Decompose the form > ((match* `(,head ,bindings . ,body) form)) > > ;; Body is empty or just contains a constant. > ((match* (or `() `(,(macroexp-const-p const))) body) This may be confusing. Consider (let ((somenumber 2) (form '(10))) (cond* ((match* `(,(> (+ somenumber form-car-value) 3))) form) )) It is not clear how to mark actual variables and variables to-be-bound inside ,(...) match* constructs. -- Ihor Radchenko // yantar92, Org mode contributor, Learn more about Org mode at <https://orgmode.org/>. Support Org development at <https://liberapay.com/org-mode>, or support my work at <https://liberapay.com/yantar92> ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: cond* 2023-12-21 14:10 ` cond* Ihor Radchenko @ 2023-12-24 3:57 ` Richard Stallman 2023-12-25 14:14 ` cond* Ihor Radchenko 0 siblings, 1 reply; 342+ messages in thread From: Richard Stallman @ 2023-12-24 3:57 UTC (permalink / raw) To: Ihor Radchenko; +Cc: joaotavora, 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. ]]] > This may be confusing. Consider > (let ((somenumber 2) (form '(10))) > (cond* > ((match* `(,(> (+ somenumber form-car-value) 3))) form) > )) This tries to use (> (+ somenumber form-car-value) 3) as a constrained variable, but it is not valid as one. In a constrained variable, the first argument of the predicate function is supposed to be a pattern to match. It can't be an expression such as (+ somenumber form-car-value). Yesterday I rewrote the documentation of constrained variables and sent that to the list. Does that version make this clear? -- Dr Richard Stallman (https://stallman.org) Chief GNUisance of the GNU Project (https://gnu.org) Founder, Free Software Foundation (https://fsf.org) Internet Hall-of-Famer (https://internethalloffame.org) ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: cond* 2023-12-24 3:57 ` cond* Richard Stallman @ 2023-12-25 14:14 ` Ihor Radchenko 0 siblings, 0 replies; 342+ messages in thread From: Ihor Radchenko @ 2023-12-25 14:14 UTC (permalink / raw) To: rms; +Cc: joaotavora, emacs-devel Richard Stallman <rms@gnu.org> writes: > Yesterday I rewrote the documentation of constrained variables and > sent that to the list. Does that version make this clear? Having a documentation certainly helps :) I still find the construct problematic though - will reply to the email describing the PRED construct. -- Ihor Radchenko // yantar92, Org mode contributor, Learn more about Org mode at <https://orgmode.org/>. Support Org development at <https://liberapay.com/org-mode>, or support my work at <https://liberapay.com/yantar92> ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: cond* 2023-12-18 4:09 ` cond* Richard Stallman 2023-12-18 10:08 ` cond* João Távora @ 2023-12-19 3:49 ` Richard Stallman 2023-12-19 12:13 ` cond* João Távora 2023-12-19 15:53 ` [External] : cond* Drew Adams 1 sibling, 2 replies; 342+ messages in thread From: Richard Stallman @ 2023-12-19 3:49 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. ]]] It would be possible to indicate fall-through clauses by making them start with t. For instance, ((match* PATTERN DATA)) would become (t (match* PATTERN DATA)) With this change, whether a clause falls through would have nothing to do with how many elements it has, only with whether its first element is t. Note that this change in rules would make no change in the interpretation of a final clause that starts with t. Please send me feedback about this proposed change. If you like it, if you dislike it, or if you think it makes little difference, I would like to hear that from you. -- Dr Richard Stallman (https://stallman.org) Chief GNUisance of the GNU Project (https://gnu.org) Founder, Free Software Foundation (https://fsf.org) Internet Hall-of-Famer (https://internethalloffame.org) ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: cond* 2023-12-19 3:49 ` cond* Richard Stallman @ 2023-12-19 12:13 ` João Távora 2023-12-22 3:14 ` cond* Richard Stallman 2023-12-19 15:53 ` [External] : cond* Drew Adams 1 sibling, 1 reply; 342+ messages in thread From: João Távora @ 2023-12-19 12:13 UTC (permalink / raw) To: rms; +Cc: emacs-devel On Tue, Dec 19, 2023 at 3:49 AM Richard Stallman <rms@gnu.org> wrote: > Please send me feedback about this proposed change. If you like it, > if you dislike it, or if you think it makes little difference, I would > like to hear that from you. If subsequent clauses can still access bindings in PATTERN, then my previous doubts and criticism remain, and this change makes little difference. ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: cond* 2023-12-19 12:13 ` cond* João Távora @ 2023-12-22 3:14 ` Richard Stallman 2023-12-22 7:27 ` cond* Philip Kaludercic 0 siblings, 1 reply; 342+ messages in thread From: Richard Stallman @ 2023-12-22 3:14 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. ]]] Fall-through clauses are an important feature of cond* and a big advance in flexibility. Precisely how to indicate one is a detail, and I've proposed three ways to design that: * A clause with one element. * A clause that starts with t. * A clause that starts with nil. * A keyword. If you have preferences about that detail, please let me know. I am also interested in other suggestions, but I will only accept it if it is as natural and simple as those above. -- Dr Richard Stallman (https://stallman.org) Chief GNUisance of the GNU Project (https://gnu.org) Founder, Free Software Foundation (https://fsf.org) Internet Hall-of-Famer (https://internethalloffame.org) ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: cond* 2023-12-22 3:14 ` cond* Richard Stallman @ 2023-12-22 7:27 ` Philip Kaludercic 2023-12-25 3:41 ` cond* Richard Stallman 0 siblings, 1 reply; 342+ messages in thread From: Philip Kaludercic @ 2023-12-22 7:27 UTC (permalink / raw) To: Richard Stallman; +Cc: 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. ]]] > > Fall-through clauses are an important feature of cond* and a big > advance in flexibility. Precisely how to indicate one is a detail, > and I've proposed three ways to design that: > > * A clause with one element. > * A clause that starts with t. > * A clause that starts with nil. > * A keyword. > > If you have preferences about that detail, please let me know. > I am also interested in other suggestions, but I will only accept > it if it is as natural and simple as those above. Have I missed something, or where is the source code for cond*. Skimming through the messages, I don't quite understand how it is supposed to work. ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: cond* 2023-12-22 7:27 ` cond* Philip Kaludercic @ 2023-12-25 3:41 ` Richard Stallman 2023-12-25 12:32 ` cond* Philip Kaludercic 0 siblings, 1 reply; 342+ messages in thread From: Richard Stallman @ 2023-12-25 3:41 UTC (permalink / raw) To: Philip Kaludercic; +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. ]]] I'm going to finish designing the specs of cond* before trying to implement it. To implement each of the different spec versions would have been a lot more work than is really necessary. -- Dr Richard Stallman (https://stallman.org) Chief GNUisance of the GNU Project (https://gnu.org) Founder, Free Software Foundation (https://fsf.org) Internet Hall-of-Famer (https://internethalloffame.org) ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: cond* 2023-12-25 3:41 ` cond* Richard Stallman @ 2023-12-25 12:32 ` Philip Kaludercic 2023-12-27 4:54 ` cond* Richard Stallman 0 siblings, 1 reply; 342+ messages in thread From: Philip Kaludercic @ 2023-12-25 12:32 UTC (permalink / raw) To: Richard Stallman; +Cc: 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. ]]] > > I'm going to finish designing the specs of cond* before trying to > implement it. To implement each of the different spec versions > would have been a lot more work than is really necessary. Having a rough prototype of an implementation would still be useful to have, to get a better felling of what the macro should look and feel like. An advantage of `pcase' (as with Emacs) is that it is extensible and can be adapted to new needs. My fear is that if `cond*' is conjured up in our minds, it is easy to misunderstand the needs in practice, or if it really will be easier to use. E.g. from reading your messages, I am still not sure how `cond*' and `match' are supposed to interact with one another. ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: cond* 2023-12-25 12:32 ` cond* Philip Kaludercic @ 2023-12-27 4:54 ` Richard Stallman 2023-12-27 14:34 ` cond* Philip Kaludercic 0 siblings, 1 reply; 342+ messages in thread From: Richard Stallman @ 2023-12-27 4:54 UTC (permalink / raw) To: Philip Kaludercic; +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. ]]] > Having a rough prototype of an implementation would still be useful to > have, to get a better felling of what the macro should look and feel > like. Yes, it might do that. Would you like to help write it? I think some parts of the pcase code could be adapted. > E.g. from reading your messages, I am > still not sure how `cond*' and `match' are supposed to interact with one > another. `match*' is not an independent construct defined on its own. It is meaningful only within a cond* construct. In effect, it marks a certain part of the cond*. If someone can figure out a way that `match*' could be meaningful on its own, whi;e also working together with `cond*' so that the two function together as desired, that would be a neat hack. But I'm not aiming for that. -- Dr Richard Stallman (https://stallman.org) Chief GNUisance of the GNU Project (https://gnu.org) Founder, Free Software Foundation (https://fsf.org) Internet Hall-of-Famer (https://internethalloffame.org) ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: cond* 2023-12-27 4:54 ` cond* Richard Stallman @ 2023-12-27 14:34 ` Philip Kaludercic 2023-12-29 3:52 ` cond* Richard Stallman 0 siblings, 1 reply; 342+ messages in thread From: Philip Kaludercic @ 2023-12-27 14:34 UTC (permalink / raw) To: Richard Stallman; +Cc: 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. ]]] > > > Having a rough prototype of an implementation would still be useful to > > have, to get a better felling of what the macro should look and feel > > like. > > Yes, it might do that. Would you like to help write it? > I think some parts of the pcase code could be adapted. I have some time and could try it out. Can you link me to the most current specification? > > E.g. from reading your messages, I am > > still not sure how `cond*' and `match' are supposed to interact with one > > another. > > `match*' is not an independent construct defined on its own. > It is meaningful only within a cond* construct. In effect, > it marks a certain part of the cond*. > > If someone can figure out a way that `match*' could be meaningful on > its own, whi;e also working together with `cond*' so that the two > function together as desired, that would be a neat hack. But I'm not > aiming for that. I agree, that would be interesting to have. ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: cond* 2023-12-27 14:34 ` cond* Philip Kaludercic @ 2023-12-29 3:52 ` Richard Stallman 2024-01-01 14:49 ` cond* Ihor Radchenko 0 siblings, 1 reply; 342+ messages in thread From: Richard Stallman @ 2023-12-29 3:52 UTC (permalink / raw) To: Philip Kaludercic; +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. ]]] I include below the latest version. Compare the total complexity of specification of cond* with the total complexity of specification of pcase. Then likewise compare the generality and flexibility of cond* with pcase. Each clause in cond* that has just one element -- no "clause body" -- is a "non-exit" clause. After that clause completes, control always proceeds to the following clause. All other clauses are like cond clauses, in that when the condition is true, the executes its clause body and then exits the cond*. (cond* ;; Same as a clause in `cond', (CONDITION DO-THIS-IF-TRUE-THEN-EXIT...) ;; Execute FORM and ignore its value. (FORM) ;; Variables to bind, as in let*, around the rest ;; of the cond*. ((bind* (x foobar) y z (foo 5) a)) ;; Bindings continue in effect for the whole cond* construct. ;; Bind variables for the clause, as in let*. ((bind* (foo 5) (condition (hack-it foo))) ;; condition is that the last variable bound be non-nil. BODY...) ;; Bindings no longer in effect. ;; Extracts substructure and binds variables for the clause. ((match* `(expt ,foo ,bar) x) DO-THIS-IF-IT-MATCHED-THEN-EXIT...) ;; Bindings no longer in effect. ;; Extracts substructure and binds variables ;; for the rest of the cond*. ;; Like above but always falls thru to next clause. ;; All the variables mentioned in the pattern ;; are bound whether match succeeds or not. ;; If a value can be determined from an incomplete match, ;; the variable gets that value. ((match* `(expt ,foo ,bar) x)) ;; Bindings continue in effect. ;; Another example of fall-through match* clause. ;; All the variables mentioned in the pattern ;; are bound in all cases. ((match* (or `() `(,macroexp-const-p const)) body) ;; The `match-set*' is a tentative proposal. It may not be worth including. ;; Extracts substructure and sets variables if match succeeds ((match-set* `(expt ,foo ,bar) x) DO-THIS-IF-IT-MATCHED-THEN-EXIT...) ;; Extracts substructure and sets variables without binding them. ;; Always falls thru to next clause. ((match-set* `(expt ,foo ,bar) x)) ) To execute several expressions and not exit, use this: ((progn DO-THIS-UNCONDITIONALLY-AND-DONT-STOP...) To test CONDITION and return its value if non-nil, use this: (CONDITION CONDITION) That is the best way when CONDITION is simple. When it is complex, this may be clearer and shorter than repeating CONDITION: ((bind* (value CONDITION)) value) \f **Possible types of patterns for match*. CONSTANT: nil, t, a keyword, a quoted constant other than a cons cell, fixed parts of a backquote. This matches any value equal to CONSTANT. _ _ means to match any value and not store it anywhere. VARIABLE: a symbol A symbol means to match any value and set VARIABLE to it. A backquoted cons cell The car and the cdr are subpattenrs. The cons cell pattern matches any cons cell whose car and cdr match those two subpatterns. How nil as a cdr matches is controlled by the match-nil flag. When the nil-match-all flag is false, nil as a cdr matches only nil itself. When the nil-match-all flag is true, nil as a cdr matches any object and ignores that object. The nil-match-all flag is false by default. The `cdr' pattern maks it false within its its subpattern, and the `cdr-safe' pattern makes it true forwithin its its subpattern. (cdr-safe QUOTED-CONS-CELL) This pattern is equivalent to QUOTED-CONS-CELL by itself except that it makes the nil-match-all flag true within it. (cdr-safe `(a b)) matches (a b), (a b c), (a b . d), etc. (cdr QUOTED-CONS-CELL) This pattern is equivalent to QUOTED-CONS-CELL by itself except that it makes the nil-match-all flag false within it. (cdr `(a b)) matches only (a b). A backquoted vector Each element is a subpattern. This matches a vector of data if each element of that vector is matched by the corresponding subpattern. A backquoted structure constructor Each field is a subpattern. This matches a structure as data if each field element of that structure is matched by the corresponding subpattern. Constrained variable: (PRED VARIABLE) or, more generally, (PRED VARIABLE OTHER-ARGS...) This matches any value VALUE that satisfies the specified constraint. PRED is a function to test the constraint. It receives VALUE as its first argument. If PRED returns true, that means VALUE satisfies the constraint, so this pattern binds (or sets) VARIABLE to that value. For instance, (symbolp sym) ; Match any symbol, bind `sym' to it. xxxxxxxxxxxxxx not decided yet This would give some added power, but does that power really enable the user to do more with cond*? I am not sure. PATTERN can also be a list, which is a pattern to destructure, For instance, (plistp `(,a ,b . ,rest)) checks that VA<UE is a valid plist, then binds a and b to the first and second element and binds rest to its cddr. xxxxxxxxxxxxxx not decided yet If you wish, you can specify additional arguments to pass to PRED. The OTHER-ARGS are not patterns to match, they are Lisp expressions whose values specify the additional arguments to pass to PRED, following the first argument which is VALUE. In effect, the call to PRED looks like this: (apply PRED VALUE (mapcar 'eval OTHER-ARGS)) Here are two examples of passing an additional argument. (> num-foos 1) ; Match any number greater than 1, bind `num-foos' to it. (> num-foos min-foos) ; Match any number greater than MIN-FOOS, ; bind `num-foos' to it. When matching to bind variables, the presence of a constrained variable pattern, as a subpattern of the overall pattern to be matched, unconditionally binds VARIABLE whether the subpattern matches or not. Errors in constrained variable constructs: If an error occurs in testing the constraint, or calculating the other arguments to pass to the predicate, that pattern fails to match but does not terminate the cond* form. Constrained variable constructs can be nested: For example, (integerp (> num-foos 1)) ; Match any integer > 1, ; bind `num-foos' to it. nests the constrained pattern (integerp num-foos) inside the constrained pattern (< ... 1). This nested constrained pattern first tests that the value is greater than 1, then tests it is an integer. If both of those constraints are true, it setse `num-foos'. (> (integerp num-foos) 1) ; Match any integer > 1, ; bind `num-foos' to it. does the two tests in the opposite order; it is equivalent, because an error in the call to `>' only makes this pattern fail to match. Advanced hack for experts: the OTHER-ARGS can refer to variables bound earlier in this pattern-matching operation. For example, `(,(integerp smaller) ,(> (integerp bigger) smaller)) ; Matches a list of two integers in which the second integer ; is larger than the first. (or `(,(integerp smaller) ,(> (integerp bigger) smaller)) `(,(integerp bigger) ,(< (integerp smaller) bigger))) ; matches a ist of two integers and binds `bigger' to the bigger one ; and `smaller' to the smaller one. However, it might be cleaner to match the two integers regardless of their numberical ordering, then in Lisp code see which one is larger. General constrained variable: (constrain VAR EXPRESSION) This general constrained variable pattern binds VAR to the value being matched against, tentatively, then evaluates EXPRESSION. If the result is true, the match succeeds and leaves VAR bound to that value. For instance, (constrain x (and (> x 0) (< x 100))) succeeds if the value being matched aainst is in the open interval (0, 100), and in that case it binds x to that value. Alternatives: (or SUBPATTERNS...) This tries to match each of the SUBPATTERNS in order until one matches. If the pattern is being used to bind variables, it binds all the variables specified in any of SUBPATTERNS \f These three ways of using `cond*' are worth noting. (cond* ((match* PATTERN VALUE) TEST)) PATTERN is a pattern as described above. For instance (match `(+ (expt ,_ ,_)) (get-complex-list)) would decompose the result of (get-complex-list) and check for `+' and `expt' in it. PATTERN will not be evaluated, just used as guidance when the `match' form is macroexpanded. If PATTERN includes substitutions, it will virtually perform those substitutions and compare parts of VALUE against them. (match `(foo ,foo) x) compares (car x) with `foo'. TEST is a Lisp expression to be evaluated if VALUE seems to fit PATTERN. If TEST evaluates non-nil, the match succeeds. `match' returns t if it succeeds in matching, otherwise nil. `match' can also handle vectors and maybe some other kinds of structures. (cond* ((match-set* PATTERN VALUE))) PATTERN is a pattern as described above. For instance (match-set `(+ ,y ,z) (get-complex-list)) would decompose the result of (get-complex-list), verify the car, and set y and z. It is equivalent to this: (if (eq (car value) '+) (progn (setq y (car (cadr value)) z (cadr (cadr value))) TEST)) PATTERN will not be evaluated, just used as guidance when the `match-set' form is macroexpanded, producing code like this: TEST is a Lisp expression to be evaluated if VALUE seems to fit PATTERN. If TEST evaluates non-nil, the match succeeds. `match-set' returns t if it succeeds in matching, otherwise nil. `match-set' can also handle vectors and maybe some other kinds of structures. (cond* ((match* PATTERN VALUE) BODY...)) Like the previous, except that instead of setting the variables found in PATTERN, it let-binds them and runs BODY with those bindings. -- Dr Richard Stallman (https://stallman.org) Chief GNUisance of the GNU Project (https://gnu.org) Founder, Free Software Foundation (https://fsf.org) Internet Hall-of-Famer (https://internethalloffame.org) ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: cond* 2023-12-29 3:52 ` cond* Richard Stallman @ 2024-01-01 14:49 ` Ihor Radchenko 2024-01-03 4:13 ` cond* Richard Stallman ` (2 more replies) 0 siblings, 3 replies; 342+ messages in thread From: Ihor Radchenko @ 2024-01-01 14:49 UTC (permalink / raw) To: rms; +Cc: Philip Kaludercic, emacs-devel Richard Stallman <rms@gnu.org> writes: > Each clause in cond* that has just one element -- no "clause body" -- > is a "non-exit" clause. After that clause completes, control always > proceeds to the following clause. > ... > To test CONDITION and return its value if non-nil, use this: > > (CONDITION CONDITION) Note that it is different from `cond', which is somewhat confusing - (CONDITION) in `cond' exits, returning CONDITION value. > A backquoted cons cell > > ... > (cdr-safe QUOTED-CONS-CELL) > > This pattern is equivalent to QUOTED-CONS-CELL by itself > except that it makes the nil-match-all flag true within it. > > (cdr-safe `(a b)) matches (a b), (a b c), (a b . d), etc. > > (cdr QUOTED-CONS-CELL) > > This pattern is equivalent to QUOTED-CONS-CELL by itself > except that it makes the nil-match-all flag false within it. > > (cdr `(a b)) matches only (a b). This is more confusing than `pcase'. In `pcase', what you call "cdr-safe" is realized simply by `(a b . _) and what you cal ""cdr" is `(a b). I find `pcase' version both more intuitive and more compact. > Constrained variable: (PRED VARIABLE) or, more generally, > (PRED VARIABLE OTHER-ARGS...) > > This matches any value VALUE that satisfies the specified > constraint. PRED is a function to test the constraint. It receives > VALUE as its first argument. If PRED returns true, that means VALUE > satisfies the constraint, so this pattern binds (or sets) VARIABLE > to that value. For instance, > > (symbolp sym) ; Match any symbol, bind `sym' to it. This is an equivalent of pcase's pred pattern, except that pcase also allow VARIABLE to be non-first argument of PRED. What about allowing a construct like ,((plist-get plist) property) that will test for PROPERTY being in PLIST? Or, better, allow VARIABLE to be in an arbitrary argument of PRED: ,(PRED ARG1 ARG2 !VARIABLE ARG3 ...) Example: ,(plist-get plist !variable #'equal) > xxxxxxxxxxxxxx not decided yet > This would give some added power, but does that power really enable > the user to do more with cond*? I am not sure. > > PATTERN can also be a list, which is a pattern to destructure, > For instance, > > (plistp `(,a ,b . ,rest)) > > checks that VA<UE is a valid plist, then binds a and b to the first > and second element and binds rest to its cddr. > xxxxxxxxxxxxxx not decided yet I feel that layering conditions will lead to unnecessary complexity. What about allowing (and ...) pattern, similar to (or ...): (match* (and (plistp _) `(,a ,b . ,rest)) plist) P.S. What is missing in the above compared to pcase is matching regular expressions: ‘(rx RX-EXPR...)’ Matches strings against the regexp RX-EXPR..., using the ‘rx’ regexp notation (*note Rx Notation::), as if by ‘string-match’. In addition to the usual ‘rx’ syntax, RX-EXPR... can contain the following constructs: ‘(let REF RX-EXPR...)’ Bind the symbol REF to a submatch that matches RX-EXPR.... REF is bound in BODY-FORMS to the string of the submatch or ‘nil’, but can also be used in ‘backref’. ‘(backref REF)’ Like the standard ‘backref’ construct, but REF can here also be a name introduced by a previous ‘(let REF ...)’ construct. -- Ihor Radchenko // yantar92, Org mode contributor, Learn more about Org mode at <https://orgmode.org/>. Support Org development at <https://liberapay.com/org-mode>, or support my work at <https://liberapay.com/yantar92> ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: cond* 2024-01-01 14:49 ` cond* Ihor Radchenko @ 2024-01-03 4:13 ` Richard Stallman 2024-01-03 15:57 ` cond* Ihor Radchenko 2024-01-03 4:13 ` cond* Richard Stallman 2024-01-03 4:13 ` cond* Richard Stallman 2 siblings, 1 reply; 342+ messages in thread From: Richard Stallman @ 2024-01-03 4:13 UTC (permalink / raw) To: Ihor Radchenko; +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. ]]] > What about allowing a construct like ,((plist-get plist) property) that > will test for PROPERTY being in PLIST? I do not understand what you mean by ,((plist-get plist) property). I am simply lost here. I don't know which parts of that are supposed to be fixed structure and which parts refer to things in the cond* call. > Or, better, allow VARIABLE to be in an arbitrary argument of PRED: I understand that in the abstract. I just don't see any syntax that makes sense to use for it. > ,(PRED ARG1 ARG2 !VARIABLE ARG3 ...) I don't understand this syntax. `!' as no special meaning. It cam't magically have a special meaning in a cpnd* pattern. It would be part of the variable name. This feature makes sense, and I've defined a syntax for it already: (constrain VARIABLE (PRED ARG1 ARG2 VARIABLE ARG3...)) -- Dr Richard Stallman (https://stallman.org) Chief GNUisance of the GNU Project (https://gnu.org) Founder, Free Software Foundation (https://fsf.org) Internet Hall-of-Famer (https://internethalloffame.org) ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: cond* 2024-01-03 4:13 ` cond* Richard Stallman @ 2024-01-03 15:57 ` Ihor Radchenko 2024-01-05 4:23 ` cond* Richard Stallman 0 siblings, 1 reply; 342+ messages in thread From: Ihor Radchenko @ 2024-01-03 15:57 UTC (permalink / raw) To: rms; +Cc: emacs-devel Richard Stallman <rms@gnu.org> writes: > > Or, better, allow VARIABLE to be in an arbitrary argument of PRED: > > I understand that in the abstract. I just don't see any syntax that > makes sense to use for it. > > > ,(PRED ARG1 ARG2 !VARIABLE ARG3 ...) > > I don't understand this syntax. `!' as no special meaning. > It cam't magically have a special meaning in a cpnd* pattern. > It would be part of the variable name. > This feature makes sense, and I've defined a syntax for it already: > > (constrain VARIABLE (PRED ARG1 ARG2 VARIABLE ARG3...)) It is technically possible to assign special meaning to !name in macros. However, I do agree that "constrain" should be good enough to the use case that I proposed. > > What about allowing a construct like ,((plist-get plist) property) that > > will test for PROPERTY being in PLIST? > > I do not understand what you mean by ,((plist-get plist) property). > I am simply lost here. I don't know which parts of that are supposed > to be fixed structure and which parts refer to things in the cond* call. [ I withdraw this proposal as "constrain" is good enough, but still replying to provide context for my previous idea ] I was referring to what "pred" in `pcase' does: ‘(pred FUNCTION)’ Matches if the predicate FUNCTION returns non-‘nil’ when called on EXPVAL. The test can be negated with the syntax ‘(pred (not FUNCTION))’. The predicate FUNCTION can have one of the following forms: function name (a symbol) Call the named function with one argument, EXPVAL. Example: ‘integerp’ <...> function call with N args Call the function (the first element of the function call) with N arguments (the other elements) and an additional N+1-th argument that is EXPVAL. Example: ‘(= 42)’ ^^^^^^^^^^^^^^^^^ <- this In this example, the function is ‘=’, N is one, and the actual function call becomes: ‘(= 42 EXPVAL)’. -- Ihor Radchenko // yantar92, Org mode contributor, Learn more about Org mode at <https://orgmode.org/>. Support Org development at <https://liberapay.com/org-mode>, or support my work at <https://liberapay.com/yantar92> ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: cond* 2024-01-03 15:57 ` cond* Ihor Radchenko @ 2024-01-05 4:23 ` Richard Stallman 2024-01-06 14:33 ` cond* Ihor Radchenko 0 siblings, 1 reply; 342+ messages in thread From: Richard Stallman @ 2024-01-05 4:23 UTC (permalink / raw) To: Ihor Radchenko; +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. ]]] > I was referring to what "pred" in `pcase' does: > ‘(pred FUNCTION)’ > Matches if the predicate FUNCTION returns non-‘nil’ when called on > EXPVAL. The test can be negated with the syntax ‘(pred (not > FUNCTION))’. The predicate FUNCTION can have one of the following > forms: Ok. Given that for comparison, what conclusion or suggestion to you offer about cond*? -- Dr Richard Stallman (https://stallman.org) Chief GNUisance of the GNU Project (https://gnu.org) Founder, Free Software Foundation (https://fsf.org) Internet Hall-of-Famer (https://internethalloffame.org) ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: cond* 2024-01-05 4:23 ` cond* Richard Stallman @ 2024-01-06 14:33 ` Ihor Radchenko 2024-01-06 22:25 ` [External] : cond* Drew Adams ` (2 more replies) 0 siblings, 3 replies; 342+ messages in thread From: Ihor Radchenko @ 2024-01-06 14:33 UTC (permalink / raw) To: rms; +Cc: emacs-devel Richard Stallman <rms@gnu.org> writes: > > I was referring to what "pred" in `pcase' does: > > > ‘(pred FUNCTION)’ > > Matches if the predicate FUNCTION returns non-‘nil’ when called on > > EXPVAL. The test can be negated with the syntax ‘(pred (not > > FUNCTION))’. The predicate FUNCTION can have one of the following > > forms: > > Ok. Given that for comparison, what conclusion or suggestion to you > offer about cond*? From my reading of your latest spec of the cond*, I feel that it is getting closer and closer to the features provided by `pcase'. The description is also getting closer to pcase manual page length. Since cond* is aiming to produce "simpler" syntax compared to pcase, I feel that the concise style of pcase may either be avoided or considered carefully. In particular, I believe that (PRED ...) in conf* is no less confusing than (pred ...) that pcase provides. IMHO, the recursive (PRED1 (PRED2 ...) ...) is more confusing compared to what pcase offers. -- Ihor Radchenko // yantar92, Org mode contributor, Learn more about Org mode at <https://orgmode.org/>. Support Org development at <https://liberapay.com/org-mode>, or support my work at <https://liberapay.com/yantar92> ^ permalink raw reply [flat|nested] 342+ messages in thread
* RE: [External] : Re: cond* 2024-01-06 14:33 ` cond* Ihor Radchenko @ 2024-01-06 22:25 ` Drew Adams 2024-01-08 3:45 ` Richard Stallman 2024-01-08 3:47 ` cond* Richard Stallman 2024-01-08 3:47 ` cond* Richard Stallman 2 siblings, 1 reply; 342+ messages in thread From: Drew Adams @ 2024-01-06 22:25 UTC (permalink / raw) To: Ihor Radchenko, rms@gnu.org; +Cc: emacs-devel@gnu.org Perhaps off-topic, but I think the difficulty of human-parsing pcase sexps can be reduced considerably if each variable bound by the sexp is clearly shown to be just that. Even just following a trivial convention, such as prefixing each variable name with, `?', would help. (I'd even suggest that this could be part of the required syntax - except that pcase is no longer new and there are lots of pcase occurrences already out there in the wild.) Here's an example from bug #68029 (closed as "done" but really was "wont-fix" -- nothing was done). The vars introduced here are ?msg and ?code: (pcase (get-return-code x) ((and (pred stringp) ?msg) (message "%s" ?msg)) ('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))) [ I changed `msg' and `code' in the Elisp manual example to `?msg' and `?code', to point out that it introduces two variables, whereas it was claimed that it introduced _NO_ vars and that _therefore_ the pcase version was clearer than using `let'. I even used uppercase, `?MSG' and ?CODE, to make the presence of the vars clearer. The doc _still incorrectly claims_ that the pcase version is superior because it doesn't need to introduce any vars such as `code'. The author and an Emacs maintainer, at least, apparently missed that pcase binds these variables. IOW, the fact of the var bindings isn't as clear as it could be. ] https://debbugs.gnu.org/cgi/bugreport.cgi?bug=68029#13 ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: [External] : Re: cond* 2024-01-06 22:25 ` [External] : cond* Drew Adams @ 2024-01-08 3:45 ` Richard Stallman 2024-01-08 15:20 ` Drew Adams 2024-01-09 2:53 ` map seq and radix-tree-leaf, in pcase Richard Stallman 0 siblings, 2 replies; 342+ messages in thread From: Richard Stallman @ 2024-01-08 3:45 UTC (permalink / raw) To: Drew Adams; +Cc: yantar92, 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. ]]] > Perhaps off-topic, but I think the difficulty > of human-parsing pcase sexps can be reduced > considerably if each variable bound by the > sexp is clearly shown to be just that. After reading the example, I see the point you're making. I suppose the same issue could apply to cond*. Do you think it applies equally to both? The only pertinent difference is that cond* would use match* or bind* around constructs that can make bindings. > Even just following a trivial convention, > such as prefixing each variable name with, > `?', would help. Supposing that cond* could benefit from this idea, how can we make this idea fit the framework of Emacs Lisp? `?' has a different meaning. Of course, it does not _have_ to take the form of `?', but what could it be? -- Dr Richard Stallman (https://stallman.org) Chief GNUisance of the GNU Project (https://gnu.org) Founder, Free Software Foundation (https://fsf.org) Internet Hall-of-Famer (https://internethalloffame.org) ^ permalink raw reply [flat|nested] 342+ messages in thread
* RE: [External] : Re: cond* 2024-01-08 3:45 ` Richard Stallman @ 2024-01-08 15:20 ` Drew Adams 2024-01-09 2:53 ` map seq and radix-tree-leaf, in pcase Richard Stallman 1 sibling, 0 replies; 342+ messages in thread From: Drew Adams @ 2024-01-08 15:20 UTC (permalink / raw) To: rms@gnu.org; +Cc: yantar92@posteo.net, emacs-devel@gnu.org > > Perhaps off-topic, but I think the difficulty > > of human-parsing pcase sexps can be reduced > > considerably if each variable bound by the > > sexp is clearly shown to be just that. > > After reading the example, I see the point you're making. > I suppose the same issue could apply to cond*. > Do you think it applies equally to both? > The only pertinent difference is that cond* > would use match* or bind* around constructs that can make bindings. My point about pcase was made originally in the context of (IMHO) poor examples in the Elisp manual. I've only cursorily followed this cond* thread. My point about pcase not signalling well that something is a variable binding may not apply to cond*, if variabless in cond* are always introduced with a label that signals a binding. That's akin to the use of an explicit "let" to signal bindings - not a problem. > > Even just following a trivial convention, > > such as prefixing each variable name with, > > `?', would help. > > Supposing that cond* could benefit from this idea, how can we make > this idea fit the framework of Emacs Lisp? `?' has a different > meaning. Of course, it does not _have_ to take the form of `?', but > what could it be? I don't know. Some Lisp pattern-matching contexts have used a cons such as `(? VAR)' (instead of just `?VAR') to indicate a variable `VAR'. And in some such contexts, the cons can even be updated destructively to unify (logic programming) or instantiate. My guess is that if you use a label such as `match*' or `bind*', and if in that context it's clear enough which things are the vars, then you don't also need a syntax convention (or enforcement) such as a `?' prefix. So my comment about this may be off-topic in a strict sense for this thread. In a more general way it might still be relevant or helpful. I really do guess that much of the bother people have with pcase and learning its syntax comes from _vars not being obvious_. For lispers used to backquote syntax I think variables not signaling themselves is likely to be more of an obstacle than the use of backquote. A third obstacle, IMO, is the mixing of variable-binding constructs with control (conditional) constructs. That's also the case for `loop' and even things like `if-let'. But `if-let' & compagnie are simple, compared to `loop' and `pcase'. Among (1) unobvious var bindings, (2) backquote syntax, and (3) mixing of control structure with pattern-matching / var-binding, the degree to which each presents an obstacle to understanding/ reading/learning is debatable. ^ permalink raw reply [flat|nested] 342+ messages in thread
* map seq and radix-tree-leaf, in pcase 2024-01-08 3:45 ` Richard Stallman 2024-01-08 15:20 ` Drew Adams @ 2024-01-09 2:53 ` Richard Stallman 1 sibling, 0 replies; 342+ messages in thread From: Richard Stallman @ 2024-01-09 2:53 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 the help text for pcase, I saw information about these three constructs, but I am not sure what they mean. -- (map &rest ARGS) -- (seq &rest PATTERNS) -- (radix-tree-leaf VPAT) Perhaps I should add similar constructs, or substitutes for them, to cond*. Could someone please explain what they mean, and give an explained example? -- Dr Richard Stallman (https://stallman.org) Chief GNUisance of the GNU Project (https://gnu.org) Founder, Free Software Foundation (https://fsf.org) Internet Hall-of-Famer (https://internethalloffame.org) ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: cond* 2024-01-06 14:33 ` cond* Ihor Radchenko 2024-01-06 22:25 ` [External] : cond* Drew Adams @ 2024-01-08 3:47 ` Richard Stallman 2024-01-10 13:03 ` cond* Ihor Radchenko 2024-01-08 3:47 ` cond* Richard Stallman 2 siblings, 1 reply; 342+ messages in thread From: Richard Stallman @ 2024-01-08 3:47 UTC (permalink / raw) To: Ihor Radchenko; +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. ]]] > In particular, I believe that (PRED ...) in conf* is no > less confusing than (pred ...) that pcase provides. A few people misunderstood it from the initial version of the documentation, but that is no reason to think the feature itself is confusing. The corresponding pcase `pred' feature is certainly not better -- it is inside out -- and I don't see any other alternative to try. If you would like to suggest one, I'd look at it with interest. IMHO, the recursive > (PRED1 (PRED2 ...) ...) is more confusing compared to what pcase offers. You may be right about that. I decided to remove it, for now. I introduced a `and' construction which is like the one in pcase. It can be used for the same purposes and may be more natural. Thanks for working with me. -- Dr Richard Stallman (https://stallman.org) Chief GNUisance of the GNU Project (https://gnu.org) Founder, Free Software Foundation (https://fsf.org) Internet Hall-of-Famer (https://internethalloffame.org) ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: cond* 2024-01-08 3:47 ` cond* Richard Stallman @ 2024-01-10 13:03 ` Ihor Radchenko 2024-01-13 3:50 ` cond* Richard Stallman 0 siblings, 1 reply; 342+ messages in thread From: Ihor Radchenko @ 2024-01-10 13:03 UTC (permalink / raw) To: rms; +Cc: emacs-devel Richard Stallman <rms@gnu.org> writes: > > In particular, I believe that (PRED ...) in conf* is no > > less confusing than (pred ...) that pcase provides. > > A few people misunderstood it from the initial version of the > documentation, but that is no reason to think the feature itself > is confusing. > > The corresponding pcase `pred' feature is certainly not better -- it > is inside out -- and I don't see any other alternative to try. If you > would like to suggest one, I'd look at it with interest. My suggestion is simple - drop PRED and just leave "constrain". This will be more verbose, but also more clear. -- Ihor Radchenko // yantar92, Org mode contributor, Learn more about Org mode at <https://orgmode.org/>. Support Org development at <https://liberapay.com/org-mode>, or support my work at <https://liberapay.com/yantar92> ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: cond* 2024-01-10 13:03 ` cond* Ihor Radchenko @ 2024-01-13 3:50 ` Richard Stallman 2024-01-13 6:32 ` cond* Adam Porter 2024-01-13 19:47 ` cond* Ihor Radchenko 0 siblings, 2 replies; 342+ messages in thread From: Richard Stallman @ 2024-01-13 3:50 UTC (permalink / raw) To: Ihor Radchenko; +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. ]]] (symbolp x) is simpler and more natural than the pcase equivalent, which I believe would be (and (pred symbolp) x). People seem to have accepted the latter, without criticizing it as unnatural. I think they will accept (symbolp x) also. I think that people will get used to this once they start actually using cond*. To require use of the more complex `constrain' form even for the common simple cases would make cond* less convenient for real. I don't think it would be wise to create a real drawback to eliminate a mere perception of a drawback. -- Dr Richard Stallman (https://stallman.org) Chief GNUisance of the GNU Project (https://gnu.org) Founder, Free Software Foundation (https://fsf.org) Internet Hall-of-Famer (https://internethalloffame.org) ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: cond* 2024-01-13 3:50 ` cond* Richard Stallman @ 2024-01-13 6:32 ` Adam Porter 2024-01-16 3:31 ` cond* Richard Stallman 2024-01-13 19:47 ` cond* Ihor Radchenko 1 sibling, 1 reply; 342+ messages in thread From: Adam Porter @ 2024-01-13 6:32 UTC (permalink / raw) To: rms; +Cc: emacs-devel, yantar92 > (symbolp x) is simpler and more natural than the pcase equivalent, > which I believe would be (and (pred symbolp) x). People seem to have > accepted the latter, without criticizing it as unnatural. I think that is an apples-to-oranges comparison. This pcase form: (and (pred symbolp) x) is specifically a pcase form. It does two things, and--crucially--it does them separately and explicitly: 1. It tests the EXP with the predicate `symbolp'. 2. If the test is non-nil, it binds the EXP to `x'. The list `(pred symbolp)' is obviously not a normal expression, because `symbolp' is a predicate function and is unquoted in this list (i.e. there is no `symbolp' variable bound). In contrast, this cond* form: (symbolp x) looks like a normal expression calling the function `symbolp'; and, in a sense, it is, because that will happen. But that same form also binds the variable `x' after testing its to-be-bound value with the predicate `symbolp'--yet the binding is not explicit and separate, but implicit and combined. Contrast that also with a pcase `guard' form, like in: (and x (guard (symbolp x))) That also does the same thing, but again, the binding and testing are separate and explicit. And it provides the additional benefit of the `guard' form being a normal expression, so it could include other parts, like: (and x (guard (and (symbolp x) (string-prefix-p "foo" (symbol-name x))))) ISTM that the most potentially confusing aspect of that pcase form is that `and' is effectively used to denote binding; and I think that could be mitigated by offering an alternative, optional keyword to surround bindings, to make them appear more explicit. > I think they will accept (symbolp x) also. I think that people will > get used to this once they start actually using cond*. By the same token, people could get used to pcase's design once they start using it. But pcase's binding and testing forms are more explicit and look less like normal expressions, which makes it potentially less confusing to users. We often bemoan the addition of various libraries to Emacs and ELPA that seem to do what existing ones already do, but in slightly different ways. Why not improve pcase to solve these minor shortcomings, instead of adding another library that does some similar things, in slightly different, incompatible ways, while not even offering as much functionality as pcase? (e.g. as I've mentioned, pcase can destructure maps, structs, and EIEIO objects, and is extensible by other libraries--it's an incredible tool that I sorely miss when working in environments outside of Emacs Lisp.) --Adam ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: cond* 2024-01-13 6:32 ` cond* Adam Porter @ 2024-01-16 3:31 ` Richard Stallman 0 siblings, 0 replies; 342+ messages in thread From: Richard Stallman @ 2024-01-16 3:31 UTC (permalink / raw) To: Adam Porter; +Cc: emacs-devel, yantar92 [[[ 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 contrast, this cond* form: > (symbolp x) > looks like a normal expression calling the function `symbolp'; This is in the match* construct, whose operands are never Lisp expressions. Just as inaide pcase, people will understand these are different. People will be accustomed to seeing cond* patterns there, just as people who use ocase are accustomed to seeing pcase patterns there. and, in a > sense, it is, because that will happen. No, that's not quite correct. What it does is test the value there in the data to see if it is symbolp, and if so, the match will bind x to that symbol. It is similar to what happens if the pattern is just x You're working hard to convince people that they they will dislike cond*. But that is not a usefu thing to do. Soon people will have a chance to play with cond* and see what they think. -- Dr Richard Stallman (https://stallman.org) Chief GNUisance of the GNU Project (https://gnu.org) Founder, Free Software Foundation (https://fsf.org) Internet Hall-of-Famer (https://internethalloffame.org) ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: cond* 2024-01-13 3:50 ` cond* Richard Stallman 2024-01-13 6:32 ` cond* Adam Porter @ 2024-01-13 19:47 ` Ihor Radchenko 2024-01-15 3:13 ` cond* Richard Stallman 1 sibling, 1 reply; 342+ messages in thread From: Ihor Radchenko @ 2024-01-13 19:47 UTC (permalink / raw) To: rms; +Cc: emacs-devel Richard Stallman <rms@gnu.org> writes: > ... I think > they will accept (symbolp x) also. I think that people will get used > to this once they start actually using cond*. People may as well get used to `pcase'. But `cond*' is supposed to be _better_ than `pcase', isn't it? Otherwise, we will end up not with one, but two confusing pattern matching macros and people will have to learn both. > To require use of the more complex `constrain' form even for the > common simple cases would make cond* less convenient for real. I > don't think it would be wise to create a real drawback to eliminate a > mere perception of a drawback. I was confused when reading the examples you provided. Same for Adam. So, at least two people are confused - it is not a "mere perception". I tried to come up with some better notation that is not as verbose as "constrain", but I cannot think of anything less confusing, unfortunately. -- Ihor Radchenko // yantar92, Org mode contributor, Learn more about Org mode at <https://orgmode.org/>. Support Org development at <https://liberapay.com/org-mode>, or support my work at <https://liberapay.com/yantar92> ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: cond* 2024-01-13 19:47 ` cond* Ihor Radchenko @ 2024-01-15 3:13 ` Richard Stallman 0 siblings, 0 replies; 342+ messages in thread From: Richard Stallman @ 2024-01-15 3:13 UTC (permalink / raw) To: Ihor Radchenko; +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. ]]] > I was confused when reading the examples you provided. Same for Adam. > So, at least two people are confused - it is not a "mere perception". I think that with better documentation, containing good examples explained, and seeing it in use, people will get used to it and like it. When the pcase form (and (pred symbolp) x) and the cond* form (symbolp x) are competing pm an equal footing, I think people will prefer the brevity of the cond* form. But we will see. -- -- Dr Richard Stallman (https://stallman.org) Chief GNUisance of the GNU Project (https://gnu.org) Founder, Free Software Foundation (https://fsf.org) Internet Hall-of-Famer (https://internethalloffame.org) ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: cond* 2024-01-06 14:33 ` cond* Ihor Radchenko 2024-01-06 22:25 ` [External] : cond* Drew Adams 2024-01-08 3:47 ` cond* Richard Stallman @ 2024-01-08 3:47 ` Richard Stallman 2024-01-08 15:13 ` cond* Ihor Radchenko 2 siblings, 1 reply; 342+ messages in thread From: Richard Stallman @ 2024-01-08 3:47 UTC (permalink / raw) To: Ihor Radchenko; +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. ]]] > >From my reading of your latest spec of the cond*, I feel that it is > getting closer and closer to the features provided by `pcase'. The > description is also getting closer to pcase manual page length. After eliminating the nested constrained variables, it is only 213 lines. Are there any pcase features that cond* does not provide an equivalent for? -- Dr Richard Stallman (https://stallman.org) Chief GNUisance of the GNU Project (https://gnu.org) Founder, Free Software Foundation (https://fsf.org) Internet Hall-of-Famer (https://internethalloffame.org) ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: cond* 2024-01-08 3:47 ` cond* Richard Stallman @ 2024-01-08 15:13 ` Ihor Radchenko 2024-01-27 3:37 ` cond* Richard Stallman 0 siblings, 1 reply; 342+ messages in thread From: Ihor Radchenko @ 2024-01-08 15:13 UTC (permalink / raw) To: rms; +Cc: emacs-devel Richard Stallman <rms@gnu.org> writes: > > >From my reading of your latest spec of the cond*, I feel that it is > > getting closer and closer to the features provided by `pcase'. The > > description is also getting closer to pcase manual page length. > > After eliminating the nested constrained variables, it is only 213 lines. > > Are there any pcase features that cond* does not provide an equivalent > for? Other than rx, one missing feature is an ability to match against multiple values in a single condition: (defun yant/list-sum (list) (apply #'+ list)) (pcase '(1 2 3) ((and `(,x ,y ,z) (app yant/list-sum (and sum (guard (< 2 sum))))) (format "%d + %d + %d = %d; 2 is < %d" x y z sum sum))) ; => "1 + 2 + 3 = 6; 2 is < 6" In the above, we first match `(,x ,y ,z) against '(1 2 3) and then match (and sum (guard (< 2 sum))) against the result of (yant/list-sum '(1 2 3)) Also, `pcase' performs some compiler-like optimizations on the provided patterns. -- Ihor Radchenko // yantar92, Org mode contributor, Learn more about Org mode at <https://orgmode.org/>. Support Org development at <https://liberapay.com/org-mode>, or support my work at <https://liberapay.com/yantar92> ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: cond* 2024-01-08 15:13 ` cond* Ihor Radchenko @ 2024-01-27 3:37 ` Richard Stallman 2024-02-01 16:26 ` cond* Ihor Radchenko 0 siblings, 1 reply; 342+ messages in thread From: Richard Stallman @ 2024-01-27 3:37 UTC (permalink / raw) To: Ihor Radchenko; +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. ]]] > Other than rx, one missing feature is an ability to match against > multiple values in a single condition: > (defun yant/list-sum (list) > (apply #'+ list)) > (pcase '(1 2 3) > ((and `(,x ,y ,z) (app yant/list-sum (and sum (guard (< 2 sum))))) > (format "%d + %d + %d = %d; 2 is < %d" x y z sum sum))) > ; => "1 + 2 + 3 = 6; 2 is < 6" Understanding this was a struggle, but I think it can be done with (cond* ((match* `(,x ,y ,z) list-of-three)) ((< 2 (+ x y z)) success))) It is not the one condition which is the goal you specified, but given the flexibility of cond* it doesn't need to be one condition. And it is much clearer than the pcase code to do the same job. -- Dr Richard Stallman (https://stallman.org) Chief GNUisance of the GNU Project (https://gnu.org) Founder, Free Software Foundation (https://fsf.org) Internet Hall-of-Famer (https://internethalloffame.org) ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: cond* 2024-01-27 3:37 ` cond* Richard Stallman @ 2024-02-01 16:26 ` Ihor Radchenko 2024-02-03 3:36 ` cond* Richard Stallman 0 siblings, 1 reply; 342+ messages in thread From: Ihor Radchenko @ 2024-02-01 16:26 UTC (permalink / raw) To: rms; +Cc: emacs-devel Richard Stallman <rms@gnu.org> writes: > > Other than rx, one missing feature is an ability to match against > > multiple values in a single condition: > > (defun yant/list-sum (list) > > (apply #'+ list)) > > (pcase '(1 2 3) > > ((and `(,x ,y ,z) (app yant/list-sum (and sum (guard (< 2 sum))))) > > (format "%d + %d + %d = %d; 2 is < %d" x y z sum sum))) > > ; => "1 + 2 + 3 = 6; 2 is < 6" > > Understanding this was a struggle, but I think it can be done with > > (cond* ((match* `(,x ,y ,z) list-of-three)) > ((< 2 (+ x y z)) > success))) Nope. Consider (let ((list-of-three '(1 2))) (cond* ((match* `(,x ,y ,z) list-of-three)) ((< 2 (+ x y z)) 'success))) ; => (wrong-type-argument number-or-marker-p nil) Debugger entered--Lisp error: (wrong-type-argument number-or-marker-p nil) (+ 1 2 nil) (< 2 (+ x y z)) (if (< 2 (+ x y z)) (progn 'success)) (let* ((z (nth 2 d2495))... I used the latest version of cond* you submitted in https://yhetil.org/emacs-devel/86cytg1vcu.fsf@gnu.org/T/#t Also, I was surprised by (let ((list-of-three '(1 2 3 4))) (cond* ((match* `(,x ,y ,z) list-of-three)) ((< 2 (+ x y z)) 'success))) ; => success I did not expect list of four to match `(,x ,y ,z). -- Ihor Radchenko // yantar92, Org mode contributor, Learn more about Org mode at <https://orgmode.org/>. Support Org development at <https://liberapay.com/org-mode>, or support my work at <https://liberapay.com/yantar92> ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: cond* 2024-02-01 16:26 ` cond* Ihor Radchenko @ 2024-02-03 3:36 ` Richard Stallman 2024-02-03 16:52 ` cond* Ihor Radchenko 0 siblings, 1 reply; 342+ messages in thread From: Richard Stallman @ 2024-02-03 3:36 UTC (permalink / raw) To: Ihor Radchenko; +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. ]]] > (let ((list-of-three '(1 2))) > (cond* ((match* `(,x ,y ,z) list-of-three)) > ((< 2 (+ x y z)) > 'success))) ; => (wrong-type-argument number-or-marker-p nil) That is not exactly a bug, but it is an unclarity in the design. The match* condition fails, but since it is a non-exit clause, that failure doesn't affect anything -- it goes ahead an executes the next clause. Arguably it is doing exactly what your code said. But it raises the question of what a non-exit match* clause should do when it does not match. What do you think it should do? The idea that occurs to me is this: bind all those variables, initializing by matching those that can match, and initializing the rest to nil. -- Dr Richard Stallman (https://stallman.org) Chief GNUisance of the GNU Project (https://gnu.org) Founder, Free Software Foundation (https://fsf.org) Internet Hall-of-Famer (https://internethalloffame.org) ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: cond* 2024-02-03 3:36 ` cond* Richard Stallman @ 2024-02-03 16:52 ` Ihor Radchenko 0 siblings, 0 replies; 342+ messages in thread From: Ihor Radchenko @ 2024-02-03 16:52 UTC (permalink / raw) To: rms; +Cc: emacs-devel Richard Stallman <rms@gnu.org> writes: > > (let ((list-of-three '(1 2))) > > (cond* ((match* `(,x ,y ,z) list-of-three)) > > ((< 2 (+ x y z)) > > 'success))) ; => (wrong-type-argument number-or-marker-p nil) > > That is not exactly a bug, but it is an unclarity in the design. > ... I think that we are drifting away from the original topic I raised in this discussion branch. I originally pointed to a missing feature of cond* - inability to match against multiple values as in (defun yant/list-sum (list) (apply #'+ list)) (pcase '(1 2 3) ((and `(,x ,y ,z) (app yant/list-sum (and sum (guard (< 2 sum))))) (format "%d + %d + %d = %d; 2 is < %d" x y z sum sum))) ; => "1 + 2 + 3 = 6; 2 is < 6" You suggested how the same can be done with cond*. However, your example does not work, throwing wrong-type-argument, when the first match fails. So, I still view the above scenario as a missing feature in cond*. What I imagine as an addition to cond* is something like: (let ((list-of-three '(1 2))) (cond* ((and (match* `(,x ,y ,z) list-of-three) (match* (constrain x (< 2 x)) (yant/list-sum list-of-three))) 'success))) This way, multiple values can be matched against. > But it raises the question of what a non-exit match* clause should do > when it does not match. What do you think it should do? > > The idea that occurs to me is this: bind all those variables, > initializing by matching those that can match, and initializing the > rest to nil. I'd rather make cond* throw an error in such scenario. Otherwise, it will be impossible to distinguish between "no match" and something like (let ((list-of-three '(nil nil nil))) (cond* ((match* `(,x ,y ,z) list-of-three) ((and (null x) (null y) (null z)) "We matched '(nil nil nil), or did we?")))) (let ((list-of-three 'not-a-list)) (cond* ((match* `(,x ,y ,z) list-of-three) ((and (null x) (null y) (null z)) "We matched '(nil nil nil), or did we?")))) -- Ihor Radchenko // yantar92, Org mode contributor, Learn more about Org mode at <https://orgmode.org/>. Support Org development at <https://liberapay.com/org-mode>, or support my work at <https://liberapay.com/yantar92> ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: cond* 2024-01-01 14:49 ` cond* Ihor Radchenko 2024-01-03 4:13 ` cond* Richard Stallman @ 2024-01-03 4:13 ` Richard Stallman 2024-01-03 15:48 ` cond* Ihor Radchenko 2024-01-03 4:13 ` cond* Richard Stallman 2 siblings, 1 reply; 342+ messages in thread From: Richard Stallman @ 2024-01-03 4:13 UTC (permalink / raw) To: Ihor Radchenko; +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. ]]] > ‘(rx RX-EXPR...)’ > Matches strings against the regexp RX-EXPR..., using the ‘rx’ > regexp notation (*note Rx Notation::), as if by ‘string-match’. That seems natural enough, though I don't recall the details of `rx'. (I have never used it myself.) But I need to underdstand this too: > In addition to the usual ‘rx’ syntax, RX-EXPR... can contain the > following constructs: > ‘(let REF RX-EXPR...)’ > Bind the symbol REF to a submatch that matches RX-EXPR.... > REF is bound in BODY-FORMS to the string of the submatch or > ‘nil’, but can also be used in ‘backref’. I don't understand that description. I don't see what this construct would look like inside of an (rx ...) pattern, let alone what it would mean. Can you show me a complete pattern example using (rx...) and this, and explain it? -- Dr Richard Stallman (https://stallman.org) Chief GNUisance of the GNU Project (https://gnu.org) Founder, Free Software Foundation (https://fsf.org) Internet Hall-of-Famer (https://internethalloffame.org) ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: cond* 2024-01-03 4:13 ` cond* Richard Stallman @ 2024-01-03 15:48 ` Ihor Radchenko 2024-01-06 4:31 ` cond* Richard Stallman 0 siblings, 1 reply; 342+ messages in thread From: Ihor Radchenko @ 2024-01-03 15:48 UTC (permalink / raw) To: rms; +Cc: emacs-devel Richard Stallman <rms@gnu.org> writes: > > In addition to the usual ‘rx’ syntax, RX-EXPR... can contain the > > following constructs: > > > ‘(let REF RX-EXPR...)’ > > Bind the symbol REF to a submatch that matches RX-EXPR.... > > REF is bound in BODY-FORMS to the string of the submatch or > > ‘nil’, but can also be used in ‘backref’. > > I don't understand that description. I don't see what this construct > would look like inside of an (rx ...) pattern, let alone what it would > mean. > > Can you show me a complete pattern example using (rx...) and this, and > explain it? Sure. Consider the following `rx' form that matches lines like "#+begin: something": (rx line-start (0+ (any " \t")) "#+BEGIN:" (0+ (any " \t")) ;; matches "something" (1+ word)) This is equivalent to "^[ ]*#\\+BEGIN:[ ]*[[:word:]]+" Now, consider that we need to extract "something" from the match if the match succeeds: (pcase " #+begin: something" ((rx line-start (0+ (any " \t")) "#+BEGIN:" (0+ (any " \t")) ;; matches "something" ;; (let VAR <sub-expression>) binds VAR to sub-expression match. (let matched-value (1+ word))) (format "We just matched \"%s\"" matched-value))) ; => "We just matched \"something\"" -- Ihor Radchenko // yantar92, Org mode contributor, Learn more about Org mode at <https://orgmode.org/>. Support Org development at <https://liberapay.com/org-mode>, or support my work at <https://liberapay.com/yantar92> ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: cond* 2024-01-03 15:48 ` cond* Ihor Radchenko @ 2024-01-06 4:31 ` Richard Stallman 2024-01-06 13:09 ` cond* Ihor Radchenko 0 siblings, 1 reply; 342+ messages in thread From: Richard Stallman @ 2024-01-06 4:31 UTC (permalink / raw) To: Ihor Radchenko; +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. ]]] Now I understand what (let REF RX-EXPR...) does, Thanks. It seems like a gratuitous complexity for this aspect of `rx' to be different between use in pcase and use as a Lisp function. What Emacs really implements in search is numbered groups. So that was the easiest thing to implement in `rx'. But if it is possible to implement the named variables for thisin pcase, surely they can be implemented in `rx' too. How about if we add them to `rx'? WDYT? -- Dr Richard Stallman (https://stallman.org) Chief GNUisance of the GNU Project (https://gnu.org) Founder, Free Software Foundation (https://fsf.org) Internet Hall-of-Famer (https://internethalloffame.org) ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: cond* 2024-01-06 4:31 ` cond* Richard Stallman @ 2024-01-06 13:09 ` Ihor Radchenko 2024-01-08 3:47 ` cond* Richard Stallman 0 siblings, 1 reply; 342+ messages in thread From: Ihor Radchenko @ 2024-01-06 13:09 UTC (permalink / raw) To: rms; +Cc: emacs-devel Richard Stallman <rms@gnu.org> writes: > ... > What Emacs really implements in search is numbered groups. > So that was the easiest thing to implement in `rx'. > > But if it is possible to implement the named variables for thisin > pcase, surely they can be implemented in `rx' too. > > How about if we add them to `rx'? WDYT? May you please elaborate how you see named variables in `rx'? `rx' is a macro that transforms a sexp into string regexp. It does not introduce let-bindings. So, I do not see any context to put named variables within `rx' itself. -- Ihor Radchenko // yantar92, Org mode contributor, Learn more about Org mode at <https://orgmode.org/>. Support Org development at <https://liberapay.com/org-mode>, or support my work at <https://liberapay.com/yantar92> ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: cond* 2024-01-06 13:09 ` cond* Ihor Radchenko @ 2024-01-08 3:47 ` Richard Stallman 2024-01-08 15:26 ` cond* Ihor Radchenko 0 siblings, 1 reply; 342+ messages in thread From: Richard Stallman @ 2024-01-08 3:47 UTC (permalink / raw) To: Ihor Radchenko; +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. ]]] > May you please elaborate how you see named variables in `rx'? Exactly the same as in `rx' in pcase. I suppose pcase transforms the (rx ...) construct into a regular expression -- right? If this can be implemented for the (rx ...) pattern in pcase, it can be implemented for `rx' the function with the same code -- right? I expect it would work by allocating a subpattern number for each (let ...) variable. Please don't tell me that someone reimplemented `rx' from scratch for pcase, rather than using the existing `rx' code! -- Dr Richard Stallman (https://stallman.org) Chief GNUisance of the GNU Project (https://gnu.org) Founder, Free Software Foundation (https://fsf.org) Internet Hall-of-Famer (https://internethalloffame.org) ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: cond* 2024-01-08 3:47 ` cond* Richard Stallman @ 2024-01-08 15:26 ` Ihor Radchenko 2024-01-27 3:37 ` cond* Richard Stallman 0 siblings, 1 reply; 342+ messages in thread From: Ihor Radchenko @ 2024-01-08 15:26 UTC (permalink / raw) To: rms; +Cc: emacs-devel Richard Stallman <rms@gnu.org> writes: > > May you please elaborate how you see named variables in `rx'? > > Exactly the same as in `rx' in pcase. > > I suppose pcase transforms the (rx ...) construct into a regular > expression -- right? If this can be implemented for the (rx ...) > pattern in pcase, it can be implemented for `rx' the function with the > same code -- right? > > I expect it would work by allocating a subpattern number for each > (let ...) variable. > > Please don't tell me that someone reimplemented `rx' from scratch > for pcase, rather than using the existing `rx' code! The way (let ...) expressions are handled inside pcase is defined in `rx--pcase-expand'. It has nothing to do with rx operation itself. Instead, it parser the rx pattern, and transforms it into a different pcase match: This (pcase " #+begin: something" ((rx line-start (0+ (any " \t")) "#+BEGIN:" (0+ (any " \t")) ;; matches "something" ;; (let VAR <sub-expression>) binds VAR to sub-expression match. (let matched-value (1+ word))) (format "We just matched \"%s\"" matched-value))) becomes something along the lines of (pcase " #+begin: something" ((app (lambda (s) (and (string-match regexp-generated-by-rx s) (list (match-string 0 s) (match-string 1 s)))) `(_ ,matched-value)) In other words, `rx' pattern matching is implemented by rewriting the pattern using other `pcase' constructs during macro expansion. The original `rx' is not changed and does not assign any variables. -- Ihor Radchenko // yantar92, Org mode contributor, Learn more about Org mode at <https://orgmode.org/>. Support Org development at <https://liberapay.com/org-mode>, or support my work at <https://liberapay.com/yantar92> ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: cond* 2024-01-08 15:26 ` cond* Ihor Radchenko @ 2024-01-27 3:37 ` Richard Stallman 0 siblings, 0 replies; 342+ messages in thread From: Richard Stallman @ 2024-01-27 3:37 UTC (permalink / raw) To: Ihor Radchenko; +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. ]]] > The way (let ...) expressions are handled inside pcase is defined in > `rx--pcase-expand'. It has nothing to do with rx operation itself. How surprising. I judt called one of the entry points of rx, and it seems to work. -- Dr Richard Stallman (https://stallman.org) Chief GNUisance of the GNU Project (https://gnu.org) Founder, Free Software Foundation (https://fsf.org) Internet Hall-of-Famer (https://internethalloffame.org) ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: cond* 2024-01-01 14:49 ` cond* Ihor Radchenko 2024-01-03 4:13 ` cond* Richard Stallman 2024-01-03 4:13 ` cond* Richard Stallman @ 2024-01-03 4:13 ` Richard Stallman 2024-01-03 15:50 ` cond* Ihor Radchenko 2 siblings, 1 reply; 342+ messages in thread From: Richard Stallman @ 2024-01-03 4:13 UTC (permalink / raw) To: Ihor Radchenko; +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. ]]] What should a string used as a pattern mean in cond*? (What does it mean in pcase?) Should it mean a usual Emacs regular expression to match against a string? -- Dr Richard Stallman (https://stallman.org) Chief GNUisance of the GNU Project (https://gnu.org) Founder, Free Software Foundation (https://fsf.org) Internet Hall-of-Famer (https://internethalloffame.org) ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: cond* 2024-01-03 4:13 ` cond* Richard Stallman @ 2024-01-03 15:50 ` Ihor Radchenko 2024-01-06 4:31 ` cond* Richard Stallman 0 siblings, 1 reply; 342+ messages in thread From: Ihor Radchenko @ 2024-01-03 15:50 UTC (permalink / raw) To: rms; +Cc: emacs-devel Richard Stallman <rms@gnu.org> writes: > What should a string used as a pattern mean in cond*? > (What does it mean in pcase?) > > Should it mean a usual Emacs regular expression to match against a string? In `pcase', string pattern matches against a string: (pcase "string" ("string" 'matched-string-by-equality) (_ 'not-matched)) ; => 'matched-string-by-equality -- Ihor Radchenko // yantar92, Org mode contributor, Learn more about Org mode at <https://orgmode.org/>. Support Org development at <https://liberapay.com/org-mode>, or support my work at <https://liberapay.com/yantar92> ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: cond* 2024-01-03 15:50 ` cond* Ihor Radchenko @ 2024-01-06 4:31 ` Richard Stallman 2024-01-06 13:13 ` cond* Ihor Radchenko 0 siblings, 1 reply; 342+ messages in thread From: Richard Stallman @ 2024-01-06 4:31 UTC (permalink / raw) To: Ihor Radchenko; +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. ]]] > > Should it mean a usual Emacs regular expression to match against a string? > In `pcase', string pattern matches against a string: Since the idea is pattern-matching, I think that a regexp is natural as well as more general. Why not do this? -- Dr Richard Stallman (https://stallman.org) Chief GNUisance of the GNU Project (https://gnu.org) Founder, Free Software Foundation (https://fsf.org) Internet Hall-of-Famer (https://internethalloffame.org) ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: cond* 2024-01-06 4:31 ` cond* Richard Stallman @ 2024-01-06 13:13 ` Ihor Radchenko 2024-01-08 3:47 ` cond* Richard Stallman 0 siblings, 1 reply; 342+ messages in thread From: Ihor Radchenko @ 2024-01-06 13:13 UTC (permalink / raw) To: rms; +Cc: emacs-devel Richard Stallman <rms@gnu.org> writes: > > > Should it mean a usual Emacs regular expression to match against a string? > > > In `pcase', string pattern matches against a string: > > Since the idea is pattern-matching, I think that a regexp is natural > as well as more general. Why not do this? It is not very clear then how to match plain strings for equality. -- Ihor Radchenko // yantar92, Org mode contributor, Learn more about Org mode at <https://orgmode.org/>. Support Org development at <https://liberapay.com/org-mode>, or support my work at <https://liberapay.com/yantar92> ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: cond* 2024-01-06 13:13 ` cond* Ihor Radchenko @ 2024-01-08 3:47 ` Richard Stallman 2024-01-08 15:35 ` cond* Ihor Radchenko 0 siblings, 1 reply; 342+ messages in thread From: Richard Stallman @ 2024-01-08 3:47 UTC (permalink / raw) To: Ihor Radchenko; +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. ]]] > > Since the idea is pattern-matching, I think that a regexp is natural > > as well as more general. Why not do this? > It is not very clear then how to match plain strings for equality. 1. Instead of writing the string as a literal, write a regexp to match only that string. This is not hard. 2. Use this constrained variable patern: (equal foo "xyz") It will bind the variable `foo', but you are not required to use it. -- Dr Richard Stallman (https://stallman.org) Chief GNUisance of the GNU Project (https://gnu.org) Founder, Free Software Foundation (https://fsf.org) Internet Hall-of-Famer (https://internethalloffame.org) ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: cond* 2024-01-08 3:47 ` cond* Richard Stallman @ 2024-01-08 15:35 ` Ihor Radchenko 0 siblings, 0 replies; 342+ messages in thread From: Ihor Radchenko @ 2024-01-08 15:35 UTC (permalink / raw) To: rms; +Cc: emacs-devel Richard Stallman <rms@gnu.org> writes: > > > Since the idea is pattern-matching, I think that a regexp is natural > > > as well as more general. Why not do this? > > > It is not very clear then how to match plain strings for equality. > > 1. Instead of writing the string as a literal, write a regexp to match > only that string. This is not hard. This is a bad idea when writing _generic purpose_ code - regexp matching is _a lot_ slower compared to string comparison. Orders of magnitude. > 2. Use this constrained variable patern: > > (equal foo "xyz") > > It will bind the variable `foo', but you are not required to use it. I am not a big fan of introducing yet another convention: Compare (cond* ((match* `("foo?" "bar") '("fo" "bar")) t)) ; => t (pcase '("fo" "bar") (`("foo?" "bar") t)) ; => nil People familiar with `pcase' will have to keep the above distinction in mind all the time - a source of potential confusion. -- Ihor Radchenko // yantar92, Org mode contributor, Learn more about Org mode at <https://orgmode.org/>. Support Org development at <https://liberapay.com/org-mode>, or support my work at <https://liberapay.com/yantar92> ^ permalink raw reply [flat|nested] 342+ messages in thread
* RE: [External] : Re: cond* 2023-12-19 3:49 ` cond* Richard Stallman 2023-12-19 12:13 ` cond* João Távora @ 2023-12-19 15:53 ` Drew Adams 2023-12-21 4:22 ` Richard Stallman 2023-12-21 4:22 ` Richard Stallman 1 sibling, 2 replies; 342+ messages in thread From: Drew Adams @ 2023-12-19 15:53 UTC (permalink / raw) To: rms@gnu.org, emacs-devel@gnu.org Apologies for not taking much time to check what you've suggested in more detail. If this reply doesn't help, please just ignore it. > It would be possible to indicate fall-through clauses > by making them start with t. For instance, > > ((match* PATTERN DATA)) > > would become > > (t (match* PATTERN DATA)) > > With this change, whether a clause falls through would have nothing to > do with how many elements it has, only with whether its first element > is t. Noticing whether a clause has more than one sexp isn't the best approach, I think, as I mentioned. But adding `t' that way doesn't help either, IMO. In fact, it can make things worse. > Note that this change in rules would make no change > in the interpretation of a final clause that starts with t. Yes, and that's a source of confusion. It looks too much like a clause whose condition is always true and whose _action_ (and the `cond*' return value) is the effect (and the value) of that `match*' sexp. > Please send me feedback about this proposed change. If you like it, > if you dislike it, or if you think it makes little difference, I would > like to hear that from you. Thanks for trying to address the problem I raised (to more easily distinguish no-action/return clauses from action/return clauses). Initially you had a no-action clause in this form: (match* PATTERN DATA). I actually (mis)thought the initial form was what you _next_ proposed: ((match* PATTERN DATA)). I also (mis)thought that action clauses, that is, clauses whose return value can be the return value of the `cond*', had a set of surrounding parens, just as in `cond'. And I was then thinking about suggesting that you change a no-action clause to just what you in fact had proposed initially (which I missed). Then, action clauses would continue to have surrounding parens (just like a `cond' clause) and no-action clauses would not - easier to see the difference. A no-action clause affects all subsequent clauses. So another suggestion was to be (and still could be) to move a no-action sexp inside the parens of the next action clause, instead of letting it be a clause on its own. That way, _all_ clauses would be action clauses (i.e., could provide the `cond*'s return value). They just might have one or more no-action sexps at their beginning. E.g., instead of this: (:match ...) ; no-action sexp as a clause (CONDITION . ACTIONS) ; action clause You'd have this: ((:match ...) CONDITION . ACTIONS) (Consecutive no-action sexps would be included in the first action clause that follows them.) I'd still suggest that, except that I have this question: Is there perhaps such a case as having a no-action sexp whose bindings are to be _local_ to the following action clause, i.e., they would be undone for following clauses? If that's the case, then a natural way to express that would be to put the no-action sexp inside the action clause that it affects. IOW, the form I suggested above for _all_ no-action sexps. In that case, there'd be no way to distinguish a no-action (e.g. binding) sexp that affects _all_ subsequent action clauses from one that's local to just the next action clause. So far, I don't think I've noticed any locality of binding sexps - e.g., bindings that would be undone for clauses following the immediately next one. If there won't be any clause-local no-action sexps then the suggestion above might work. To repeat the suggestion: Require each clause to have a tail of (CONDITION . ACTIONS): ([NO-ACTION-SEXP]* CONDITION . ACTIONS) This means that a NO-ACTION-SEXP cannot appear on its own, as a clause. It's part of some clause that has an action/return value. Each clause can end the `cond*' and provide its return value. And, as previously, a NO-ACTION-SEXP affects the clause it belongs to, _and_ subsequent ones. (I.e., no possibility of a no-action sexp whose effect is only local to a given clause.) Again, apologies if I've missed something. The main point here is to not have no-action sexps as clauses: the return value of any clause can be the `cond*'s return value. And again, by "no-action sexp" I just mean a sexp that only matches/binds and whose result can't possibly be the `cond*'s return value. With this suggestion there's no "fall through". Each no-action sexp belongs to some clause, and each clause can provide the `cond*' return value. Does this make sense? ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: [External] : Re: cond* 2023-12-19 15:53 ` [External] : cond* Drew Adams @ 2023-12-21 4:22 ` Richard Stallman 2023-12-21 4:22 ` Richard Stallman 1 sibling, 0 replies; 342+ messages in thread From: Richard Stallman @ 2023-12-21 4:22 UTC (permalink / raw) To: Drew Adams; +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. ]]] > > Note that this change in rules would make no change > > in the interpretation of a final clause that starts with t. > Yes, and that's a source of confusion. That makes no sense. There is no possible confusion there. Non-final clauses in cond never start with t, so no one will expect tham to do anything other than what this definition says. So I think you are concerned about a non-problem. Compared with all the complexity people have to get used to in pcase, this is almost nothing. > You'd have this: > ((:match ...) CONDITION . ACTIONS) This syntax is not coherent and won't be an improvement. It does not make sense to attach a fall-through clause to the following clause. The fall-through clause's bindings affect all the rest of the cond*, NOT just the following clause. Getting used to a special meaning for t as the first element of a cond* clause will be EASIER than getting used to a special meaning for (:match ...) there. So I will not accept that suggestion. It creates a problem where currentlly there is none. I've decided no to use keywords in cond* any more. You've put the keywod :match that cond* previous used together with the syntax I've adopted for the newer replacement, which is match*. That combination is not coherent. -- Dr Richard Stallman (https://stallman.org) Chief GNUisance of the GNU Project (https://gnu.org) Founder, Free Software Foundation (https://fsf.org) Internet Hall-of-Famer (https://internethalloffame.org) ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: [External] : Re: cond* 2023-12-19 15:53 ` [External] : cond* Drew Adams 2023-12-21 4:22 ` Richard Stallman @ 2023-12-21 4:22 ` Richard Stallman 1 sibling, 0 replies; 342+ messages in thread From: Richard Stallman @ 2023-12-21 4:22 UTC (permalink / raw) To: Drew Adams; +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. ]]] It would be easy to indicate a fall-through clause with nil instead of t. One advantage of nil is that it is never used as the first element of a cond clause. Or a keyword, such as :fall-thru, could do this job. I prefer t or nil to a keyword, because they are more elegant. -- Dr Richard Stallman (https://stallman.org) Chief GNUisance of the GNU Project (https://gnu.org) Founder, Free Software Foundation (https://fsf.org) Internet Hall-of-Famer (https://internethalloffame.org) ^ permalink raw reply [flat|nested] 342+ messages in thread
* cond* 2023-12-16 4:23 ` Richard Stallman 2023-12-18 4:09 ` cond* Richard Stallman @ 2023-12-18 4:09 ` Richard Stallman 2023-12-18 5:41 ` cond* Adam Porter 1 sibling, 1 reply; 342+ messages in thread From: Richard Stallman @ 2023-12-18 4:09 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. ]]] To finish the design of cond*, we need to find what features needed to be added so that it is rare to encounter a pcase that can't be replaced cleanly. Would people please tell me about possible examples? -- Dr Richard Stallman (https://stallman.org) Chief GNUisance of the GNU Project (https://gnu.org) Founder, Free Software Foundation (https://fsf.org) Internet Hall-of-Famer (https://internethalloffame.org) ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: cond* 2023-12-18 4:09 ` cond* Richard Stallman @ 2023-12-18 5:41 ` Adam Porter 2023-12-21 4:20 ` cond* Richard Stallman 0 siblings, 1 reply; 342+ messages in thread From: Adam Porter @ 2023-12-18 5:41 UTC (permalink / raw) To: rms; +Cc: emacs-devel > To finish the design of cond*, we need to find what features > needed to be added so that it is rare to encounter a pcase > that can't be replaced cleanly. Would people please tell me > about possible examples? Well, one of the most common things I do with pcase is to destructure alists, plists, and structs, often nested at multiple levels. For example: (defun ement-ignore-user (user-id session &optional unignore-p) "Ignore USER-ID on SESSION. If UNIGNORE-P (interactively, with prefix), un-ignore USER." (interactive (list (ement-complete-user-id) (ement-complete-session) current-prefix-arg)) ;; NOTE: Destructures account-data slot of ement-session struct. (pcase-let* (((cl-struct ement-session account-data) session) ;; NOTE: Destructures alist nested in another alist and ;; binds to a variable of a different name than the key. ((map ('content (map ('ignored_users ignored-users)))) (cl-find "m.ignored_user_list" account-data :key (lambda (event) (alist-get 'type event)) :test #'equal))) ...)) (defun ement--room-in-space-p (room space) "Return non-nil if ROOM is in SPACE on SESSION." ;; NOTE: Destructures slots in two structs to alternative variable ;; names, and destructures an alist key in each struct's `local' ;; slot to a variable of the same name. (pcase-let* (((cl-struct ement-room (id parent-id) (local (map children))) space) ((cl-struct ement-room (id child-id) (local (map parents))) room)) ...)) No alternative to pcase that omitted these features could take its place for me. In a large package like Ement.el, where function after function destructures similar objects in similar ways, the benefit of the consistency, conciseness, and flexibility offered by pcase can't be understated. As well, pcase is easily extended with its built-in flexibility, e.g. how easily support was added for the cl-type based pattern. It's a very well-designed system. Then there are pcase-lambda, pcase-dolist, and pcase-setq, all of which use the same underlying facilities and patterns. It's a coherent system: learning pcase opens up this world of useful forms. I would not want to give up these powerful tools which make my programs better and my programming more enjoyable. ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: cond* 2023-12-18 5:41 ` cond* Adam Porter @ 2023-12-21 4:20 ` Richard Stallman 0 siblings, 0 replies; 342+ messages in thread From: Richard Stallman @ 2023-12-21 4:20 UTC (permalink / raw) To: Adam Porter; +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. ]]] > Well, one of the most common things I do with pcase is to destructure > alists, plists, and structs, often nested at multiple levels. For example: These examples don't use pcase. They use pcase-let*, which I am not familiar with. Although I now understand simple pcase usage, I can't relate what I see in these examples to that. I can't understand them at all. If you explain to me what these examples do, and how they do it, I might understand them enough to think about them. As for pcase-let* in itself, its doc string is clear enough. It uses a series of bindings of the form (PATTERN VALUE). We can do that naturally in cond* like this: (cond* (t (match* PATTERN VALUE)) (t (match* PATTERN2 VALUE2)) ... (t BODY...))) so I think cond* avoids the need for a separate ...let* construct. -- Dr Richard Stallman (https://stallman.org) Chief GNUisance of the GNU Project (https://gnu.org) Founder, Free Software Foundation (https://fsf.org) Internet Hall-of-Famer (https://internethalloffame.org) ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-12-13 1:32 ` Adam Porter 2023-12-14 3:23 ` Richard Stallman 2023-12-16 4:23 ` Richard Stallman @ 2023-12-16 4:23 ` Richard Stallman 2023-12-16 4:23 ` Richard Stallman 3 siblings, 0 replies; 342+ messages in thread From: Richard Stallman @ 2023-12-16 4:23 UTC (permalink / raw) To: Adam Porter; +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. ]]] My aim in cond* is to include the convenient aspects of pcase without its rigidity of framework, which requires the programmer to squeeze things into it that don't easily fit. That rigidity is the fact that if you want to put one clause into a pcase which can't be written in pcase language, you have to redesign that whole pcase. I suspect that that rigidity creates pressure to extend pcase language to be universal -- so that there can't ever be one clause that you "can't express in pcase language." cond* avoids that problem completely. It lets you use pcase-like patterns where they are convenient, interspersed with Lisp code where that is convenient. The cond* pattern specification is a little more complex than it was in the first version, but it is still far simpler than the pcase language. As far as I know, it needs no further extension. I looked at the pcase examples that were suggested, and they don't need any further extension. The `cdr' and `cdr-safe' feature is not strictly necessary, but the lack of this feature in pcase leads to filling up many patterns with lots of `_' subpatterns. I think this feature is an improvement, but omitting it would only reintroduce the added complexity of those `_' subpatterns. Can anyone show me more pcase examples I should study, which you think show cases that call for adding any more pattern features to cond*? -- Dr Richard Stallman (https://stallman.org) Chief GNUisance of the GNU Project (https://gnu.org) Founder, Free Software Foundation (https://fsf.org) Internet Hall-of-Famer (https://internethalloffame.org) ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-12-13 1:32 ` Adam Porter ` (2 preceding siblings ...) 2023-12-16 4:23 ` Instead of pcase Richard Stallman @ 2023-12-16 4:23 ` Richard Stallman 2023-12-16 6:57 ` Adam Porter 3 siblings, 1 reply; 342+ messages in thread From: Richard Stallman @ 2023-12-16 4:23 UTC (permalink / raw) To: Adam Porter; +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. ]]] > As well, what if the user needed to pass an already-bound argument in > addition to the one being bound there? With pcase, the binding would be > explicit, and the accompanying `guard' expression would have a clear > place in lexical scope, so there would be no doubt about where the > arguments were bound. I am having trouble grasping the abstract description. Would you like to show an example of the putative problem that you are concerned about? I might understand it then. -- Dr Richard Stallman (https://stallman.org) Chief GNUisance of the GNU Project (https://gnu.org) Founder, Free Software Foundation (https://fsf.org) Internet Hall-of-Famer (https://internethalloffame.org) ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-12-16 4:23 ` Richard Stallman @ 2023-12-16 6:57 ` Adam Porter 2023-12-20 3:28 ` Richard Stallman 0 siblings, 1 reply; 342+ messages in thread From: Adam Porter @ 2023-12-16 6:57 UTC (permalink / raw) To: rms; +Cc: emacs-devel Hello Richard, On 12/15/23 22:23, Richard Stallman wrote: > > As well, what if the user needed to pass an already-bound argument in > > addition to the one being bound there? With pcase, the binding would be > > explicit, and the accompanying `guard' expression would have a clear > > place in lexical scope, so there would be no doubt about where the > > arguments were bound. > > I am having trouble grasping the abstract description. Would you like > to show an example of the putative problem that you are concerned > about? I might understand it then. Here are some examples I put together that demonstrate, IMHO, that pcase's binding forms are more explicit and less confusing. ;; In the match, will "bar" be called with "CONST" or "FOO" as the ;; first argument? (cl-labels ((bar (one two) t)) (let ((foo 'FOO) (const 'CONST) (body '(CONST FOO))) (cond* (:match ((or `() `(,(bar foo const))) body))))) ;; In the match, will "bar" be called with "CONST" or "FOO" as the ;; first argument? (cl-labels ((bar (one two) t)) (let ((foo 'FOO) (const 'CONST) (body '(FOO CONST))) (cond* (:match ((or `() `(,(bar const foo))) body))))) ;; In the match, will "bar" be called with "FOO" or "B" as the second ;; argument? (cl-labels ((bar (one two) t)) (let ((foo 'FOO) (body '(A B))) (cond* (:match ((or `() `(,(bar const foo))) body))))) ;; pcase's bindings are more explicit and less confusing: (cl-labels ((bar (one two) t)) (let ((foo 'FOO) (const 'CONST) (body '(A B))) (pcase body ((or `() (and `(,const ,foo) ; Explicitly binds within scope of clause. (guard (bar const foo)))) ; Binding of "foo" clearly shadows that of the LET form. (format "CONST:%S FOO:%S" const foo)) (_ "No match")))) ;; "CONST:A FOO:B" ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-12-16 6:57 ` Adam Porter @ 2023-12-20 3:28 ` Richard Stallman 2023-12-20 10:52 ` Adam Porter 0 siblings, 1 reply; 342+ messages in thread From: Richard Stallman @ 2023-12-20 3:28 UTC (permalink / raw) To: Adam Porter; +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. ]]] I find these examples hard to understand because of the complexity caused by the functions called `bar'. I could not fully make sense of the first one: I don't understand what you intend it to do, or what you think it might do, or why it might do that. It is indeed painfully complex, but I don't think that is the fault of cond*. Is it possible that the explanation of a constrained variable patterm is not clear? Constrained variable: (TESTFN VARIABLE OTHER-ARGS...) This matches any value VALUE provided (TESTFN VALUE OTHER-ARGS...) evaluates to true. If so, it sets VARIABLE to VALUE. (symbolp sym) Match any symbol, store it in `sym'. (> num-foos 1) Match any thing greater than 1, store it in `num-foos'. Only the first argument to a TESTFN is a kind of subpattern. The OTHER-ARGS are handled are not patterns to match; they are expressions to evaluate. Their values are passed to TESTFN as in an ordinary function call. If TESTFN is your function `bar', it will then receive its arguments in the usual way and do what it is defined to do. It is used as a predicate, so all that matters is whether its return value is non-nil. The first parameter of `bar' will be data that this subpattern may match or not. The remaining parameters of `bar' will be the results of evaluating OTHER-ARGS... -- Dr Richard Stallman (https://stallman.org) Chief GNUisance of the GNU Project (https://gnu.org) Founder, Free Software Foundation (https://fsf.org) Internet Hall-of-Famer (https://internethalloffame.org) ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-12-20 3:28 ` Richard Stallman @ 2023-12-20 10:52 ` Adam Porter 2023-12-23 2:53 ` Richard Stallman 2023-12-23 2:53 ` Richard Stallman 0 siblings, 2 replies; 342+ messages in thread From: Adam Porter @ 2023-12-20 10:52 UTC (permalink / raw) To: rms; +Cc: emacs-devel On 12/19/23 21:28, Richard Stallman wrote: > I find these examples hard to understand because of the complexity > caused by the functions called `bar'. I did not add those functions to the example myself; I merely elaborated on them to illustrate the problems I was pointing out. > I could not fully make sense of the first one: I don't understand > what you intend it to do, or what you think it might do, or why it > might do that. Yes, that is part of the point I am making: that the way COND* binds variables and passes them to predicate forms is confusing. > Is it possible that the explanation of a constrained variable patterm > is not clear? > > Constrained variable: (TESTFN VARIABLE OTHER-ARGS...) > > This matches any value VALUE provided (TESTFN VALUE OTHER-ARGS...) > evaluates to true. If so, it sets VARIABLE to VALUE. > > (symbolp sym) Match any symbol, store it in `sym'. (> num-foos 1) > Match any thing greater than 1, store it in `num-foos'. > > Only the first argument to a TESTFN is a kind of subpattern. The > OTHER-ARGS are handled are not patterns to match; they are > expressions to evaluate. Their values are passed to TESTFN as in an > ordinary function call. > The first parameter of `bar' will be data that this subpattern may > match or not. The remaining parameters of `bar' will be the results > of evaluating OTHER-ARGS... Yes, this is one of the problems I was trying to illustrate. What if the TESTFN needs VALUE as its second or later argument rather than as the first? Or what if TESTFN needs to receive multiple arguments bound from a matched pattern? What if TESTFN needs 3 arguments, and the middle one is not from the matched pattern? Or what if the middle one /is/ from the matched pattern? And what if there are naming conflicts among VARIABLE and OTHER-ARGS? What if some of those symbols are already bound outside the COND* or in another clause of it that falls through? PCASE handles these situations in a better way by matching and binding separately and explicitly, providing the GUARD form to evaluate arbitrary expressions, which may or may not include variables bound in the pattern. ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-12-20 10:52 ` Adam Porter @ 2023-12-23 2:53 ` Richard Stallman 2023-12-23 2:53 ` Richard Stallman 1 sibling, 0 replies; 342+ messages in thread From: Richard Stallman @ 2023-12-23 2:53 UTC (permalink / raw) To: Adam Porter; +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. ]]] > > I could not fully make sense of the first one: I don't understand > > what you intend it to do, or what you think it might do, or why it > > might do that. > Yes, that is part of the point I am making: that the way COND* binds > variables and passes them to predicate forms is confusing. For me, what is confusing is the rest of those examples, such as the use of subroutines called `bar' which do various things that you didn't explain. If you tell me what you are trying to do in each case, I could show you examples of how to do it in a simple way with cond*. -- Dr Richard Stallman (https://stallman.org) Chief GNUisance of the GNU Project (https://gnu.org) Founder, Free Software Foundation (https://fsf.org) Internet Hall-of-Famer (https://internethalloffame.org) ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-12-20 10:52 ` Adam Porter 2023-12-23 2:53 ` Richard Stallman @ 2023-12-23 2:53 ` Richard Stallman 2023-12-25 14:26 ` Ihor Radchenko 1 sibling, 1 reply; 342+ messages in thread From: Richard Stallman @ 2023-12-23 2:53 UTC (permalink / raw) To: Adam Porter; +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. ]]] > Or what if TESTFN needs to receive multiple arguments bound from a > matched pattern? What if TESTFN needs 3 arguments, and the middle one > is not from the matched pattern? Or what if the middle one /is/ from > the matched pattern? Thank you. I did not realize that my description was unclear in this way. I've done a lot of rewriting; I hope this version is clearer. Constrained variable: (PRED VARIABLE) or, more generally, (PRED VARIABLE OTHER-ARGS...) This matches any value VALUE that satisfies a specified constraint. PRED is a function to test the constraint. It receives VALUE as an argument. If PRED returns true, that means VALUE matches the constraint, so this pattern binds (or sets) VARIABLE to that value. For instance, (symbolp sym) ; Match any symbol, bind `sym' to it. If you wish, you can specify additional arguments to pass to PRED. The OTHER-ARGS are not patterns to match, they are Lisp expressions to whose values specify the additional arguments to pass to PRED, following the first argument which is VALUE. In effect, the call to PRED looks like this: (apply PRED VALUE (mapcar 'eval OTHER-ARGS)) For example, (> num-foos 1) ; Match any number greater than 1, bind `num-foos' to it. (> num-foos min-foos) ; Match any number greater than MIN-FOOS, ; bind `num-foos' to it. When matching to bind variables, the presence of this kind of subpattern in the overall pattern to be matched unconditionally binds VARIABLE whether the subpattern matches or not. Constrained variable constructs can be nested For example, (< (integerp num-foos) 1) ; Match any integer number > 1, ; bind `num-foos' to it. Advanced hack for experts: the OTHER-ARGS can refer to variables bound earlier in this pattern-matching operation. For example, `(,(integerp smaller) ,(> (integerp bigger) smaller)) ; Matches a list of two integers in which the second integer ; is larger than the first. (or `(,(integerp smaller) ,(> (integerp bigger) smaller)) `(,(integerp bigger) ,(< (integerp smaller) bigger))) ; matches a ist of two integers and binds `bigger' to the bigger one ; and `smaller' to the smaller one. However, it might be cleaner to match the two integers regardless of their numberical ordering, then in Lisp code see which one is larger. General constrained variable: (constrain VAR EXPRESSION) This general constrained variable pattern binds VAR to the value being matched against, tentatively, then evaluates EXPRESSION. If the result is true, the match succeeds and leaves VAR bound to that value. For instance, (constrain x (and (> x 0) (< x 100))) succeeds if the value being matched aainst is in the open interval (0, 100), and in that case it binds x to that value. -- Dr Richard Stallman (https://stallman.org) Chief GNUisance of the GNU Project (https://gnu.org) Founder, Free Software Foundation (https://fsf.org) Internet Hall-of-Famer (https://internethalloffame.org) ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-12-23 2:53 ` Richard Stallman @ 2023-12-25 14:26 ` Ihor Radchenko 2023-12-27 4:54 ` Richard Stallman 0 siblings, 1 reply; 342+ messages in thread From: Ihor Radchenko @ 2023-12-25 14:26 UTC (permalink / raw) To: rms; +Cc: Adam Porter, emacs-devel Richard Stallman <rms@gnu.org> writes: > Constrained variable: (PRED VARIABLE) or, more generally, > (PRED VARIABLE OTHER-ARGS...) > ... > (symbolp sym) ; Match any symbol, bind `sym' to it. This one is clear, especially as ,(symbolp sym) - comma indicates that the form is special. > (> num-foos min-foos) ; Match any number greater than MIN-FOOS, > ; bind `num-foos' to it. But this is confusing - which symbol to bind and which one to eval is based purely on position in the ,(PRED ...) pattern. In such scenario, it is very easy to confuse that num-foos will be let-bound. It does not help that the whole thing looks like an ordinary function call. I'd suggest to provide a more clear indication about which symbol will be bound, so that it stands out compared to ordinary variables like min-foos. > Constrained variable constructs can be nested > > For example, > > (< (integerp num-foos) 1) ; Match any integer number > 1, > ; bind `num-foos' to it. This is also confusing. Looking at the above expression, I expect that we compare the return value of `integerp' with 1, but it is not the case - integerp returns nil or t. Again, it looks deceivingly similar to normal function call. > General constrained variable: (constrain VAR EXPRESSION) > > This general constrained variable pattern binds VAR to the > value being matched against, tentatively, then evaluates EXPRESSION. > If the result is true, the match succeeds and leaves VAR > bound to that value. > > For instance, > > (constrain x (and (> x 0) (< x 100))) > > succeeds if the value being matched aainst is in the open interval (0, 100), > and in that case it binds x to that value. This looks much better, as `constrain' is a special keyword that can be easily recognized and not confused with a function call. -- Ihor Radchenko // yantar92, Org mode contributor, Learn more about Org mode at <https://orgmode.org/>. Support Org development at <https://liberapay.com/org-mode>, or support my work at <https://liberapay.com/yantar92> ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-12-25 14:26 ` Ihor Radchenko @ 2023-12-27 4:54 ` Richard Stallman 2023-12-28 13:05 ` Ihor Radchenko 0 siblings, 1 reply; 342+ messages in thread From: Richard Stallman @ 2023-12-27 4:54 UTC (permalink / raw) To: Ihor Radchenko; +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. ]]] > > (> num-foos min-foos) ; Match any number greater than MIN-FOOS, > > ; bind `num-foos' to it. > But this is confusing - which symbol to bind and which one to eval is > based purely on position in the ,(PRED ...) pattern. As this states > Constrained variable: (PRED VARIABLE) or, more generally, > (PRED VARIABLE OTHER-ARGS...) the pattern variable to bind is always the second element of that list -- what would be the first "argument" of PRED, if this ere a normal function call. Thus, in (> num-foos min-foos) the variable to bind is `num-foos', and `min-foos' is simply an expression to evaluate. The comments after it restate that: ; Match any number greater than MIN-FOOS, ; bind `num-foos' to it. Is it clear now what that pattern means? Can you suggest what aspects of that (or other) text to improve? -- Dr Richard Stallman (https://stallman.org) Chief GNUisance of the GNU Project (https://gnu.org) Founder, Free Software Foundation (https://fsf.org) Internet Hall-of-Famer (https://internethalloffame.org) ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-12-27 4:54 ` Richard Stallman @ 2023-12-28 13:05 ` Ihor Radchenko 2023-12-30 3:20 ` Richard Stallman 0 siblings, 1 reply; 342+ messages in thread From: Ihor Radchenko @ 2023-12-28 13:05 UTC (permalink / raw) To: rms; +Cc: emacs-devel Richard Stallman <rms@gnu.org> writes: > > > (> num-foos min-foos) ; Match any number greater than MIN-FOOS, > > > ; bind `num-foos' to it. > > > But this is confusing - which symbol to bind and which one to eval is > > based purely on position in the ,(PRED ...) pattern. > > As this states > > > Constrained variable: (PRED VARIABLE) or, more generally, > > (PRED VARIABLE OTHER-ARGS...) > > the pattern variable to bind is always the second element of that list > ... > Is it clear now what that pattern means? > Can you suggest what aspects of that (or other) text to improve? I did not mean that I do not understand the description of PRED form. I just find the syntax you proposed confusing - it is too similar to the ordinary Elisp forms. Especially when we start nesting "constrained variable" constructs. For example, consider matching a list of two integers where the second element is both larger than the first and also divisible by 5 when subtracted variable DEC: `(,(integerp smaller) ,(> (= (mod (- (integerp bigger) dec) 5) 0) smaller)) -- Ihor Radchenko // yantar92, Org mode contributor, Learn more about Org mode at <https://orgmode.org/>. Support Org development at <https://liberapay.com/org-mode>, or support my work at <https://liberapay.com/yantar92> ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-12-28 13:05 ` Ihor Radchenko @ 2023-12-30 3:20 ` Richard Stallman 2024-01-01 14:33 ` Ihor Radchenko 0 siblings, 1 reply; 342+ messages in thread From: Richard Stallman @ 2023-12-30 3:20 UTC (permalink / raw) To: Ihor Radchenko; +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. ]]] > `(,(integerp smaller) ,(> (= (mod (- (integerp bigger) dec) 5) 0) smaller)) That is not a valid constrained variable pattern, because (mod (- (integerp bigger) dec) 5) is nt a valid constrained variable pattern. In a constrained variable pattern, the cadr has to be a _variable pattern_. It can be a plain symbol, or it can be another constrained variable pattern. For tests which don't fit that form, you can use `constrain'. Here's a valid example: `(,(integerp smaller) ,(constrain bigger (> (= (mod (- (integerp bigger) dec) 5) 0) smaller))) Does the text I sent fail to make this clear? Would you please take a look, and if it is not clear, tell me why? -- Dr Richard Stallman (https://stallman.org) Chief GNUisance of the GNU Project (https://gnu.org) Founder, Free Software Foundation (https://fsf.org) Internet Hall-of-Famer (https://internethalloffame.org) ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-12-30 3:20 ` Richard Stallman @ 2024-01-01 14:33 ` Ihor Radchenko 2024-01-03 4:13 ` Richard Stallman 2024-01-03 4:13 ` Richard Stallman 0 siblings, 2 replies; 342+ messages in thread From: Ihor Radchenko @ 2024-01-01 14:33 UTC (permalink / raw) To: rms; +Cc: emacs-devel Richard Stallman <rms@gnu.org> writes: > For tests which don't fit that form, you can use `constrain'. > Here's a valid example: > > `(,(integerp smaller) > ,(constrain bigger (> (= (mod (- (integerp bigger) dec) 5) 0) smaller))) > > Does the text I sent fail to make this clear? Would you please take > a look, and if it is not clear, tell me why? Your description is clear. However, it is somewhat similar to the existing `pcase' description in a way that it is also clear, but goes in odds with the usual Elisp structures - I see nested "constrained variable" construct yet as another DSL. I see myself coming to back the documentation of `cond*' again and again, just as I do with `pcase' now. Let me try to illustrate the problem with another example: ;; ALIST-VAL = '((:key1 . 1) (:key4 . 2)) ;; Match alist key where the key is one of a know set of keys. (match* (memq (alist-get key alist-val) '(:key1 :key2 :key3)) :key1) From the description of "constrained variable" construct, the above will (1) test if ALIST-VAL contains a record with KEY=:key1 key; (2) test if KEY=:key1 is one of :key1 :key2 :key3. However, the above is also deceivingly similar to Elisp expression that tests the return value of `alist-get': (memq 1 '(:key1 :key2 :key3)) -- Ihor Radchenko // yantar92, Org mode contributor, Learn more about Org mode at <https://orgmode.org/>. Support Org development at <https://liberapay.com/org-mode>, or support my work at <https://liberapay.com/yantar92> ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2024-01-01 14:33 ` Ihor Radchenko @ 2024-01-03 4:13 ` Richard Stallman 2024-01-03 4:13 ` Richard Stallman 1 sibling, 0 replies; 342+ messages in thread From: Richard Stallman @ 2024-01-03 4:13 UTC (permalink / raw) To: Ihor Radchenko; +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. ]]] > existing `pcase' description in a way that it is also clear, but goes in > odds with the usual Elisp structures - I see nested "constrained > variable" construct yet as another DSL. It took me a while to figure oiut what "DSL" stood for. In another message I saw "E2E" and had to look it up. It refers to a concept I am familiar with, but I never saw that acronym before. People, so that I can understand you, I ask you plesae to spell out such expressions in full rather than using acronyms, unless we use those acronyms here every day. Each time you use an acronym that maybe not all of us know, that may exclude someone from understanding. Thank you. -- Dr Richard Stallman (https://stallman.org) Chief GNUisance of the GNU Project (https://gnu.org) Founder, Free Software Foundation (https://fsf.org) Internet Hall-of-Famer (https://internethalloffame.org) ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2024-01-01 14:33 ` Ihor Radchenko 2024-01-03 4:13 ` Richard Stallman @ 2024-01-03 4:13 ` Richard Stallman 2024-01-03 16:08 ` Ihor Radchenko 1 sibling, 1 reply; 342+ messages in thread From: Richard Stallman @ 2024-01-03 4:13 UTC (permalink / raw) To: Ihor Radchenko; +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. ]]] > Let me try to illustrate the problem with another example: > ;; ALIST-VAL = '((:key1 . 1) (:key4 . 2)) > ;; Match alist key where the key is one of a know set of keys. > (match* (memq (alist-get key alist-val) '(:key1 :key2 :key3)) :key1) > >From the description of "constrained variable" construct, the above will > (1) test if ALIST-VAL contains a record with KEY=:key1 key; (2) test if > KEY=:key1 is one of :key1 :key2 :key3. What a strange example. This is connterintuitive and I could not see at first what it would mean. But I worked it out by following the rules. (match* PATTERN :key1) matches PATTERN against the data object :key1. (memq (alist-get key alist-val) '(:key1 :key2 :key3)) as a pattern means to match (alist-get key alist-val) aainst it, and if that matches, then call memq to determine whether this matches, It would be matched against :key1. Matching (alist-get key alist-val) against :key1 would succeed, so `key' would be bound to `key1'. So the memq call would return t. And the pattern would match, binding `key' to :key1. It isn't "wrong", but I can't see the point using that strange pattern. What purpose did you have in mind in writing it? Is there a simpler way to do that? -- Dr Richard Stallman (https://stallman.org) Chief GNUisance of the GNU Project (https://gnu.org) Founder, Free Software Foundation (https://fsf.org) Internet Hall-of-Famer (https://internethalloffame.org) ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2024-01-03 4:13 ` Richard Stallman @ 2024-01-03 16:08 ` Ihor Radchenko 2024-01-05 4:23 ` Richard Stallman 0 siblings, 1 reply; 342+ messages in thread From: Ihor Radchenko @ 2024-01-03 16:08 UTC (permalink / raw) To: rms; +Cc: emacs-devel Richard Stallman <rms@gnu.org> writes: > > ;; ALIST-VAL = '((:key1 . 1) (:key4 . 2)) > > ;; Match alist key where the key is one of a know set of keys. > > (match* (memq (alist-get key alist-val) '(:key1 :key2 :key3)) :key1) > > > >From the description of "constrained variable" construct, the above will > > (1) test if ALIST-VAL contains a record with KEY=:key1 key; (2) test if > > KEY=:key1 is one of :key1 :key2 :key3. > > What a strange example. This is connterintuitive and I could not see > at first what it would mean. But I worked it out by following the > rules. > ... > So the memq call would return t. And the pattern would match, > binding `key' to :key1. > It isn't "wrong", but I can't see the point using that strange > pattern. What purpose did you have in mind in writing it? > Is there a simpler way to do that? Let me try again to illustrate the point I wanted to make - the (match* (PRED VAL ...)) construct can look too similar to ordinary Elisp yet yielding different results that one would have to work out consciously. This similarity may lead to confusion. Consider another example: (match* (xor (not var) t) t) Unlike (match* (> (integerp bigger) 5) 10), where it is clear that #'> cannot apply to the return value of #'integerp, my example with #'xor may be tricky - one may confuse that #'xor is applied to the return value of (not var) rather than to var itself. More generally, my concern is that (match* (PRED1 (PRED2 var) ARGS) val) may be confusing for people reading the code because (PRED1 (PRED2 var) ARGS) outside match* is also a valid Elisp code, which returns a _different value_ compared to what happens inside match*. -- Ihor Radchenko // yantar92, Org mode contributor, Learn more about Org mode at <https://orgmode.org/>. Support Org development at <https://liberapay.com/org-mode>, or support my work at <https://liberapay.com/yantar92> ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2024-01-03 16:08 ` Ihor Radchenko @ 2024-01-05 4:23 ` Richard Stallman 2024-01-06 13:04 ` Ihor Radchenko 0 siblings, 1 reply; 342+ messages in thread From: Richard Stallman @ 2024-01-05 4:23 UTC (permalink / raw) To: Ihor Radchenko; +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. ]]] > Consider another example: > (match* (xor (not var) t) t) My first repsonse was to say that xor is not valid in cond* patterns. Indeed, I did not know that this function `xor' existed. But now I see that your example does fit the definition of cond* patters, and its meaning is quite unintuitive. I wonder why people defined `xor'. It can't be used as a conditional, like `and' and `or', so what is the point of it? Anyway, I suppose the best response is to say that such counterintuitive constrained variables are best avoided. Or else specifically disallow `xor' as PRED in a constrained variable. -- Dr Richard Stallman (https://stallman.org) Chief GNUisance of the GNU Project (https://gnu.org) Founder, Free Software Foundation (https://fsf.org) Internet Hall-of-Famer (https://internethalloffame.org) ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2024-01-05 4:23 ` Richard Stallman @ 2024-01-06 13:04 ` Ihor Radchenko 2024-01-08 3:47 ` Richard Stallman 0 siblings, 1 reply; 342+ messages in thread From: Ihor Radchenko @ 2024-01-06 13:04 UTC (permalink / raw) To: rms; +Cc: emacs-devel Richard Stallman <rms@gnu.org> writes: > > Consider another example: > > > (match* (xor (not var) t) t) > > Anyway, I suppose the best response is to say that such counterintuitive > constrained variables are best avoided. Or else specifically disallow > `xor' as PRED in a constrained variable. My point is not about `xor' in particular. What I am trying to demonstrate is that (foo (bar var) arg) looks like a normal Elisp call - `foo' called with two arguments: (bar var) and arg. Yet, it has completely different meaning inside match*. So, it is very easy to confuse match* clause result with return value of the equivalent normal Elisp expression. In contrast, a more explicit (match* (constrain var (and (bar var) (foo var arg))) ...) (match* (constrain var (and (not var) (xor var t)) t) ...) is much more natural and avoids confusion. > ... > I wonder why people defined `xor'. It can't be used > as a conditional, like `and' and `or', so what is the point of it? `xor' can be used as conditional, and it also comes handy at time (we have 7 functions using `xor' in Org mode, for example). But that's off-topic to `pcase' discussion. -- Ihor Radchenko // yantar92, Org mode contributor, Learn more about Org mode at <https://orgmode.org/>. Support Org development at <https://liberapay.com/org-mode>, or support my work at <https://liberapay.com/yantar92> ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2024-01-06 13:04 ` Ihor Radchenko @ 2024-01-08 3:47 ` Richard Stallman 2024-01-08 15:42 ` Ihor Radchenko 0 siblings, 1 reply; 342+ messages in thread From: Richard Stallman @ 2024-01-08 3:47 UTC (permalink / raw) To: Ihor Radchenko; +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. ]]] > > I wonder why people defined `xor'. It can't be used > > as a conditional, like `and' and `or', so what is the point of it? > `xor' can be used as conditional Perhaps we are miscommunicating. `or' and `and' can act as conditionals. (and X Y) says to do Y if X is true. (or X Y) says to do Y if X is false. That is why those constructs are useful. `xor' can'e be used as a conditional, because all of the arguments of `xor' must always be evaluatedd. -- Dr Richard Stallman (https://stallman.org) Chief GNUisance of the GNU Project (https://gnu.org) Founder, Free Software Foundation (https://fsf.org) Internet Hall-of-Famer (https://internethalloffame.org) ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2024-01-08 3:47 ` Richard Stallman @ 2024-01-08 15:42 ` Ihor Radchenko 2024-01-27 3:37 ` Richard Stallman 0 siblings, 1 reply; 342+ messages in thread From: Ihor Radchenko @ 2024-01-08 15:42 UTC (permalink / raw) To: rms; +Cc: emacs-devel Richard Stallman <rms@gnu.org> writes: > > > I wonder why people defined `xor'. It can't be used > > > as a conditional, like `and' and `or', so what is the point of it? > > > `xor' can be used as conditional > > Perhaps we are miscommunicating. > > `or' and `and' can act as conditionals. (and X Y) says to > do Y if X is true. (or X Y) says to do Y if X is false. > That is why those constructs are useful. IMHO, it is a better practice to do code flow control via special forms like `if', `when', `prog1', `progn', etc. In my mind, `or' and `and' are to be used as function (they are, indeed, functions). Treating them as flow control constructs may lead to confusion, as it did for you. > `xor' can'e be used as a conditional, because all of the arguments of > `xor' must always be evaluatedd. `xor' is a function - in cond*, PRED may be any function. And the fact that not all the arguments are evaluated in (PRED x arg1 arg2 ...) is the source of my confusion and the reason why I objected the idea of PRED in its current form when "x" not visually distinct from the rest of the arguments. -- Ihor Radchenko // yantar92, Org mode contributor, Learn more about Org mode at <https://orgmode.org/>. Support Org development at <https://liberapay.com/org-mode>, or support my work at <https://liberapay.com/yantar92> ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2024-01-08 15:42 ` Ihor Radchenko @ 2024-01-27 3:37 ` Richard Stallman 0 siblings, 0 replies; 342+ messages in thread From: Richard Stallman @ 2024-01-27 3:37 UTC (permalink / raw) To: Ihor Radchenko; +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. ]]] > In my mind, `or' and `and' are to be used as function (they are, indeed, > functions). They are not Lisp functions -- they are implemented as special forms, so as not to always compute all their arguments. That's what makes them useful. What puzzled me about having a function called `xor' is that it is merely an ordinary function on truth values, thus NOT simplar in its use to `and' and `or'. -- Dr Richard Stallman (https://stallman.org) Chief GNUisance of the GNU Project (https://gnu.org) Founder, Free Software Foundation (https://fsf.org) Internet Hall-of-Famer (https://internethalloffame.org) ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-12-12 3:43 ` Richard Stallman ` (3 preceding siblings ...) 2023-12-13 1:32 ` Adam Porter @ 2023-12-13 4:58 ` Richard Stallman 4 siblings, 0 replies; 342+ messages in thread From: Richard Stallman @ 2023-12-13 4:58 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. ]]] I was compelled to copy pcase's `_' meaning "match anything" because I could not see a way to do this with anything less arbitrary. If anyone sees a cleaner way to do this, please tell me. Here is the current definition of patterns for use in cond*. **Possible types of patterns for :match and the match-... functions** CONSTANT: nil, t, a keyword, a quoted constant, fixed parts of a backquote This matches any value equal to CONSTANT. _ _ means to match any value and not store it anywhere. VARIABLE: a symbol A symbol means to match any value and set VARIABLE to it. A quoted cons cell The car and the cdr are subpattenrs. The cons cell pattern matches any cons cell whose car and cdr match those two subpatterns. How nil as a cdr matches is controlled by the match-nil flag. When the nil-match-all flag is false, nil as a cdr matches only nil itself. When the nil-match-all flag is true, nil as a cdr matches any object and ignores that object. The nil-match-all flag is false by default. The `cdr' pattern maks it false within its its subpattern, and the `cdr-safe' pattern makes it true forwithin its its subpattern. (cdr-safe QUOTED-CONS-CELL) This pattern is equivalent to QUOTED-CONS-CELL by itself except that it makes the nil-match-all flag true within it. (cdr-safe `(a b)) matches (a b), (a b c), (a b . d), etc. (cdr QUOTED-CONS-CELL) This pattern is equivalent to QUOTED-CONS-CELL by itself except that it makes the nil-match-all flag false within it. (cdr `(a b)) matches only (a b). Constrained variable: (TESTFN VARIABLE OTHER-ARGS...) This matches any value VALUE provided (TESTFN VALUE OTHER-ARGS...) evaluates to true. If so, it sets VARIABLE to VALUE. (symbolp sym) Match any symbol, store it in `sym'. (> num-foos 1) Match any thing greater than 1, store it in `num-foos'. When matching to bind variables, this pattern unconditionally binds VARIABLE whether it matches or not. `quote', `constrain' and `or' cannot be used as TESTFN. Constrained variable constructs can be nested. For example, (< (numberp num-foos) 1) Match any number > 1, store it in mum-foos. General constrained variable: (constrain VAR EXPRESSION) This general constrained variable pattern binds VAR to the value being matched against, only for evaluating EXPRESSION. If the result is non-nil, the match succeeds and sets VAR to the value. For instance, (constrain x (and (> x 0) (< x 100))) Alternatives: (or SUBPATTERNS...) This tries to match each of the SUBPATTERNS in order until one matches. If the pattern is being used to bind variables, it binds all the variables specified in any of SUBPATTERNS -- Dr Richard Stallman (https://stallman.org) Chief GNUisance of the GNU Project (https://gnu.org) Founder, Free Software Foundation (https://fsf.org) Internet Hall-of-Famer (https://internethalloffame.org) ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-12-10 16:27 ` Lynn Winebarger 2023-12-10 20:28 ` Michael Heerdegen via Emacs development discussions. @ 2023-12-11 3:31 ` Richard Stallman 1 sibling, 0 replies; 342+ messages in thread From: Richard Stallman @ 2023-12-11 3:31 UTC (permalink / raw) To: Lynn Winebarger; +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. ]]] > The pattern would match a let or let* form that has bindings but no body. Thanks. Now I can figure out what to do. -- Dr Richard Stallman (https://stallman.org) Chief GNUisance of the GNU Project (https://gnu.org) Founder, Free Software Foundation (https://fsf.org) Internet Hall-of-Famer (https://internethalloffame.org) ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-11-18 3:04 ` Richard Stallman 2023-11-19 12:23 ` Michael Heerdegen @ 2023-11-19 13:49 ` Dmitry Gutov 2023-11-21 2:42 ` Richard Stallman 1 sibling, 1 reply; 342+ messages in thread From: Dmitry Gutov @ 2023-11-19 13:49 UTC (permalink / raw) To: rms, Philip Kaludercic; +Cc: emacs-devel On 18/11/2023 05:04, Richard Stallman wrote: > > (`(,_ . ,(and (pred functionp) f)) (funcall f)) > > (`(,hookfun . (,start ,end ,collection . ,plist)) > > I read the Info documentation of pcase a few days ago and I can't > recall the rules for understanding those two pcase clauses. What I > recall is that they are not to be interpreted as Lisp expressions. > They contain code that looks like Lisp but does not have the same > semantic rules as Lisp. Yes: it's a domain-specific language. To interpret those backquotes and commas, one can imagine that the they do the inverse of the usual. If normally you have commas to insert the values from the environment (variables or expressions) into the backquoted form, then inside pcase they are used to do the opposite: to extract values from the expression at given positions, and bind them with given names in the corresponding clause's environment. I think that's pretty clever, but also quite readable once you "grok" the above idea. ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-11-19 13:49 ` Dmitry Gutov @ 2023-11-21 2:42 ` Richard Stallman 2023-11-21 5:14 ` Jim Porter ` (4 more replies) 0 siblings, 5 replies; 342+ messages in thread From: Richard Stallman @ 2023-11-21 2:42 UTC (permalink / raw) To: Dmitry Gutov; +Cc: philipk, 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. ]]] > > They contain code that looks like Lisp but does not have the same > > semantic rules as Lisp. > Yes: it's a domain-specific language. THat is why pcase adds to the total complexity of Emacs Lisp: because it incorporates a domain-specific language. (I called it a "little lajguage".) > To interpret those backquotes and commas, one can imagine that the they > do the inverse of the usual. I uderstand that when you say it, but when I saw the line > > (`(,hookfun . (,start ,end ,collection . ,plist)) I was not sure which part of the line that rule applies to. In particular, what is the reason for the period and inner parenthsses? Why doesn't the code say this? > > (`(,hookfun ,start ,end ,collection . ,plist) Would that be equiva;ent? I could not assume the inner parenthsses were unnecessary. Maybe there was a conventiob by which they change the meaning. I did not know. -- Dr Richard Stallman (https://stallman.org) Chief GNUisance of the GNU Project (https://gnu.org) Founder, Free Software Foundation (https://fsf.org) Internet Hall-of-Famer (https://internethalloffame.org) ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-11-21 2:42 ` Richard Stallman @ 2023-11-21 5:14 ` Jim Porter 2023-11-21 5:34 ` Yuri Khan ` (3 subsequent siblings) 4 siblings, 0 replies; 342+ messages in thread From: Jim Porter @ 2023-11-21 5:14 UTC (permalink / raw) To: rms, Dmitry Gutov; +Cc: philipk, emacs-devel On 11/20/2023 6:42 PM, Richard Stallman wrote: > I uderstand that when you say it, but when I saw the line > >> > (`(,hookfun . (,start ,end ,collection . ,plist)) > > I was not sure which part of the line that rule applies to. > > In particular, what is the reason for the period and inner > parenthsses? Why doesn't the code say this? > >> > (`(,hookfun ,start ,end ,collection . ,plist) > > Would that be equiva;ent? Yes, These are equivalent (unless I'm severely mistaken): ---------------------------------------- (pcase '(func 0 10 coll plist1 plist2) (`(,hookfun . (,start ,end ,collection . ,plist)) (message "hookfun = %s start = %s end = %s collection = %s plist = %s" hookfun start end collection plist))) => "hookfun = func start = 0 end = 10 collection = coll plist = (plist1 plist2)" (pcase '(func 0 10 coll plist1 plist2) (`(,hookfun ,start ,end ,collection . ,plist) (message "hookfun = %s start = %s end = %s collection = %s plist = %s" hookfun start end collection plist))) => "hookfun = func start = 0 end = 10 collection = coll plist = (plist1 plist2)" ---------------------------------------- > I could not assume the inner parenthsses were unnecessary. Maybe > there was a conventiob by which they change the meaning. > I did not know. I think this might be a case where the 'pcase' code was written in a more-cryptic-than-necessary manner, which adds extra confusion. This could be a good example to include in some documentation though: it can show how one's intuition about "ordinary" backquoted forms can apply directly to reading 'pcase'. ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-11-21 2:42 ` Richard Stallman 2023-11-21 5:14 ` Jim Porter @ 2023-11-21 5:34 ` Yuri Khan 2023-11-21 11:11 ` Dmitry Gutov ` (2 subsequent siblings) 4 siblings, 0 replies; 342+ messages in thread From: Yuri Khan @ 2023-11-21 5:34 UTC (permalink / raw) To: rms; +Cc: Dmitry Gutov, philipk, emacs-devel On Tue, 21 Nov 2023 at 09:42, Richard Stallman <rms@gnu.org> wrote: > > To interpret those backquotes and commas, one can imagine that the they > > do the inverse of the usual. > > I uderstand that when you say it, but when I saw the line > > > > (`(,hookfun . (,start ,end ,collection . ,plist)) > > I was not sure which part of the line that rule applies to. > > In particular, what is the reason for the period and inner > parenthsses? Why doesn't the code say this? > > > > (`(,hookfun ,start ,end ,collection . ,plist) > > Would that be equiva;ent? I am looking at this part of code for the first time so let’s see what I can make of it. The code in the revision I’m looking at looks like this: (defun completion-at-point () "…" (interactive) (let ((res (run-hook-wrapped 'completion-at-point-functions #'completion--capf-wrapper 'all))) (pcase res (`(,_ . ,(and (pred functionp) f)) (funcall f)) (`(,hookfun . (,start ,end ,collection . ,plist)) …) ;; Maybe completion already happened and the function returned t. (_ …)))) First, this runs a hook and binds its returned value to the local name ‘res’. Then it matches that value to one of three patterns, the last of which is a match-all. The first two look like they match ‘res’ to a cons cell. I go to look a the documentation of ‘completion-at-point-functions’: should return either nil, meaning it is not applicable at point, or a function of no arguments to perform completion (discouraged), or a list of the form (START END COLLECTION . PROPS), where: Aha! The two latter formats are the same as the inner matchers in the first two pcase alternatives. I look at ‘completion--capf-wrapper’ to see if it supplies the ‘car’ part. (defun completion--capf-wrapper (fun which) (if … (let ((res (funcall fun))) … (if res (cons fun res))))) It seems it does! So the pcase matchers in ‘completion-at-point’ are written that way because the wrapper returns a cons cell with the function in car and its result in cdr, and one of the possible formats of the result is a sub-list. I’m pretty sure collapsing that `(,hookfun . (,start …)) to `(,hookfun ,start …) would be an equivalent transformation, but I also feel it would mash together the expectations from the wrapper and the completion-at-point function thus increasing cognitive load for the reader. I further notice that, curiously, the inside of ‘completion--capf-wrapper’ analyses the result of (funcall fun) with a cond, consp, listp, functionp, and nthcdr 3 to check some conditions, then extracts its car, nth 2, and nthcdr 3 to pass them to a nested ‘try-completion’ call, and it’s not trivial for me to follow as I have to keep in mind the general structure of the list. If I were trying to grok that function, I would, for personal reference, try to rewrite it to pcase, binding the parts of the list to descriptive names. ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-11-21 2:42 ` Richard Stallman 2023-11-21 5:14 ` Jim Porter 2023-11-21 5:34 ` Yuri Khan @ 2023-11-21 11:11 ` Dmitry Gutov 2023-11-21 15:38 ` Michael Heerdegen 2023-11-24 3:34 ` Richard Stallman 2023-11-24 17:29 ` Lynn Winebarger 2023-11-25 4:15 ` Stefan Monnier 4 siblings, 2 replies; 342+ messages in thread From: Dmitry Gutov @ 2023-11-21 11:11 UTC (permalink / raw) To: rms; +Cc: philipk, emacs-devel On 21/11/2023 04:42, Richard Stallman wrote: > I uderstand that when you say it, but when I saw the line > >> > (`(,hookfun . (,start ,end ,collection . ,plist)) > I was not sure which part of the line that rule applies to. > > In particular, what is the reason for the period and inner > parenthsses? Why doesn't the code say this? > >> > (`(,hookfun ,start ,end ,collection . ,plist) > Would that be equiva;ent? These are indeed equivalent. The particular shape is chosen to follow how the data matched against was constructed in completion--capf-wrapper: (cons fun res). So it was for the ease of comprehension, actually. ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-11-21 11:11 ` Dmitry Gutov @ 2023-11-21 15:38 ` Michael Heerdegen 2023-11-23 3:00 ` Richard Stallman 2023-11-24 3:34 ` Richard Stallman 1 sibling, 1 reply; 342+ messages in thread From: Michael Heerdegen @ 2023-11-21 15:38 UTC (permalink / raw) To: emacs-devel Dmitry Gutov <dmitry@gutov.dev> writes: >> In particular, what is the reason for the period and inner >> parenthsses? Why doesn't the code say this? This was a really good question. > The particular shape is chosen to follow how the data matched against > was constructed in completion--capf-wrapper: (cons fun res). So it was > for the ease of comprehension, actually. Indeed. The backquote syntax allows to resemble the structure of the matched list. So it actually helps the readers understanding. Stefan did not choose this syntax by accident. On the contrary, it helps writing readable code for complex cases. Exactly what higher-level constructs are good for: support writing and reading complex code. Michael. ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-11-21 15:38 ` Michael Heerdegen @ 2023-11-23 3:00 ` Richard Stallman 0 siblings, 0 replies; 342+ messages in thread From: Richard Stallman @ 2023-11-23 3:00 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. ]]] > > The particular shape is chosen to follow how the data matched against > > was constructed in completion--capf-wrapper: (cons fun res). So it was > > for the ease of comprehension, actually. > Indeed. The backquote syntax allows to resemble the structure of the > matched list. So it actually helps the readers understanding. Maybe it helps someone understand some code in another context, but in did not help me understand that example. -- Dr Richard Stallman (https://stallman.org) Chief GNUisance of the GNU Project (https://gnu.org) Founder, Free Software Foundation (https://fsf.org) Internet Hall-of-Famer (https://internethalloffame.org) ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-11-21 11:11 ` Dmitry Gutov 2023-11-21 15:38 ` Michael Heerdegen @ 2023-11-24 3:34 ` Richard Stallman 2023-11-24 4:30 ` Jim Porter 2023-11-24 17:01 ` Dmitry Gutov 1 sibling, 2 replies; 342+ messages in thread From: Richard Stallman @ 2023-11-24 3:34 UTC (permalink / raw) To: Dmitry Gutov; +Cc: philipk, 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. ]]] > >> > (`(,hookfun . (,start ,end ,collection . ,plist)) > > I was not sure which part of the line that rule applies to. > > > >> > (`(,hookfun ,start ,end ,collection . ,plist) > > Would that be equiva;ent? I as a reader, trying to understand what that pcase construct did, did not know they would be equivalent. So this specific piece of cleverness specifically interfered with my understanding that example and therefore with my trying to understand pcase. > The particular shape is chosen to follow how the data matched against > was constructed in completion--capf-wrapper: (cons fun res). So it was > for the ease of comprehension, actually. I believe the assertion that this was intended to achieve that result. Whether it did achieve that, for some users, I don't know. But I can testify that, for this reader, it had the opposite effect. -- Dr Richard Stallman (https://stallman.org) Chief GNUisance of the GNU Project (https://gnu.org) Founder, Free Software Foundation (https://fsf.org) Internet Hall-of-Famer (https://internethalloffame.org) ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-11-24 3:34 ` Richard Stallman @ 2023-11-24 4:30 ` Jim Porter 2023-11-24 7:45 ` Eli Zaretskii 2023-11-25 3:08 ` Emanuel Berg 2023-11-24 17:01 ` Dmitry Gutov 1 sibling, 2 replies; 342+ messages in thread From: Jim Porter @ 2023-11-24 4:30 UTC (permalink / raw) To: rms, Dmitry Gutov; +Cc: philipk, emacs-devel On 11/23/2023 7:34 PM, Richard Stallman wrote: > > >> > (`(,hookfun . (,start ,end ,collection . ,plist)) > > > I was not sure which part of the line that rule applies to. > > > > > >> > (`(,hookfun ,start ,end ,collection . ,plist) > > > Would that be equiva;ent? > > I as a reader, trying to understand what that pcase construct did, did > not know they would be equivalent. So this specific piece of > cleverness specifically interfered with my understanding that example > and therefore with my trying to understand pcase. For cases like this, I hope to (at least partially) address it with better documentation. I'm not sure we can expect every instance of 'pcase' in the Emacs codebase to be a good teachable example for how to use 'pcase', but I do think we could achieve that with shortdocs. The shortdocs could start small with almost-trivial examples, and then build up to more-complex forms that show how the pieces interact. Broadly, my goal would be that anyone who already knows Lisp could load up the shortdocs for pcase and get the hang of 95% of it in a few minutes. (I also think we could improve the manuals and the docstring, but I think 'pcase' is a great candidate for teaching by example. The shortdoc system seems ideal for that.) ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-11-24 4:30 ` Jim Porter @ 2023-11-24 7:45 ` Eli Zaretskii 2023-11-25 3:08 ` Emanuel Berg 1 sibling, 0 replies; 342+ messages in thread From: Eli Zaretskii @ 2023-11-24 7:45 UTC (permalink / raw) To: Jim Porter; +Cc: rms, dmitry, philipk, emacs-devel > Date: Thu, 23 Nov 2023 20:30:27 -0800 > Cc: philipk@posteo.net, emacs-devel@gnu.org > From: Jim Porter <jporterbugs@gmail.com> > > For cases like this, I hope to (at least partially) address it with > better documentation. I'm not sure we can expect every instance of > 'pcase' in the Emacs codebase to be a good teachable example for how to > use 'pcase', but I do think we could achieve that with shortdocs. The > shortdocs could start small with almost-trivial examples, and then build > up to more-complex forms that show how the pieces interact. It depends on what you mean by "almost-trivial examples", but in general I find trivial examples to be at best of very limited value. First, where the use of 'pcase' is trivial, we should usually not use 'pcase' at all, but the equivalent constructs that are easier to read and understand. More importantly, trivial examples (the ones I have in mind) don't add anything to the written documentation, and thus neither help you better understand the documentation's subtle and obscure corners nor ease specific practical tasks of writing code that uses 'pcase' for specific purposes. The latter is an explicit goal of shortdocs, why we have it in the first place, so having trivial examples there for such advanced and flexible constructs defeats its very purpose, IMO. > (I also think we could improve the manuals and the docstring, but I > think 'pcase' is a great candidate for teaching by example. The shortdoc > system seems ideal for that.) I disagree that the shortdoc system is intended to teach by example. Such a system must have many explanations for each example, and shortdoc provides only a terse single-sentence description of each example. From where I stand, shortdoc is supposed to show real-life examples of doing non-trivial jobs, with the intent that given a relevant example, the reader could then go back to the documentation and say: "ah, so that's what they meant when they talked about so-and-so!" IOW, shortdoc is NOT supposed to replace the documentation, only to be a collection of examples that illustrate the documentation. ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-11-24 4:30 ` Jim Porter 2023-11-24 7:45 ` Eli Zaretskii @ 2023-11-25 3:08 ` Emanuel Berg 1 sibling, 0 replies; 342+ messages in thread From: Emanuel Berg @ 2023-11-25 3:08 UTC (permalink / raw) To: emacs-devel Jim Porter wrote: > For cases like this, I hope to (at least partially) address > it with better documentation. I'm not sure we can expect > every instance of 'pcase' in the Emacs codebase to be a good > teachable example for how to use 'pcase', but I do think we > could achieve that with shortdocs. The shortdocs could start > small with almost-trivial examples, and then build up to > more-complex forms that show how the pieces interact. > > Broadly, my goal would be that anyone who already knows Lisp > could load up the shortdocs for pcase and get the hang of > 95% of it in a few minutes. > > (I also think we could improve the manuals and the > docstring, but I think 'pcase' is a great candidate for > teaching by example. The shortdoc system seems ideal > for that.) One could make the first examples as easy as possible to show all the aspects of pcase use, this is how you do this, this is how you do that, and so on, the bunch. It would include terminology but only terminology that is visible in that example. Then there could be examples that included combinations of such aspects, this is helpful to assimilate the previous examples. After that, actual but typical use cases from the Emacs source. After that, gray areas, weird border cases and so on, also from the Emacs source (if we can find them - if not, all the better). -- underground experts united https://dataswamp.org/~incal ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-11-24 3:34 ` Richard Stallman 2023-11-24 4:30 ` Jim Porter @ 2023-11-24 17:01 ` Dmitry Gutov 1 sibling, 0 replies; 342+ messages in thread From: Dmitry Gutov @ 2023-11-24 17:01 UTC (permalink / raw) To: rms; +Cc: philipk, emacs-devel On 24/11/2023 05:34, Richard Stallman wrote: > > >> > (`(,hookfun . (,start ,end ,collection . ,plist)) > > > I was not sure which part of the line that rule applies to. > > > > > >> > (`(,hookfun ,start ,end ,collection . ,plist) > > > Would that be equiva;ent? > > I as a reader, trying to understand what that pcase construct did, did > not know they would be equivalent. So this specific piece of > cleverness specifically interfered with my understanding that example > and therefore with my trying to understand pcase. Most of the semantics-conveying tricks with advanced tools require a certain level of familiarity with the tool in question. Much like how one has to master a foreign language on a certain level to understand a lot of idioms. But then those idioms help understand each other better and more comprehensively. ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-11-21 2:42 ` Richard Stallman ` (2 preceding siblings ...) 2023-11-21 11:11 ` Dmitry Gutov @ 2023-11-24 17:29 ` Lynn Winebarger 2023-11-28 2:44 ` Richard Stallman 2023-11-25 4:15 ` Stefan Monnier 4 siblings, 1 reply; 342+ messages in thread From: Lynn Winebarger @ 2023-11-24 17:29 UTC (permalink / raw) To: Richard Stallman; +Cc: Dmitry Gutov, Philip Kaludercic, emacs-devel [-- Attachment #1: Type: text/plain, Size: 1380 bytes --] On Mon, Nov 20, 2023, 9:42 PM Richard Stallman <rms@gnu.org> wrote: > > > > They contain code that looks like Lisp but does not have the same > > > semantic rules as Lisp. > > > Yes: it's a domain-specific language. > > THat is why pcase adds to the total complexity of Emacs Lisp: because > it incorporates a domain-specific language. (I called it a "little > lajguage".) > > > To interpret those backquotes and commas, one can imagine that the > they > > do the inverse of the usual. > > I uderstand that when you say it, but when I saw the line > > > > (`(,hookfun . (,start ,end ,collection . ,plist)) > > I was not sure which part of the line that rule applies to. > > In particular, what is the reason for the period and inner > parenthsses? Why doesn't the code say this? > > > (`(,hookfun ,start ,end ,collection . ,plist) > > Would that be equiva;ent? > > I could not assume the inner parenthsses were unnecessary. Maybe > there was a conventiob by which they change the meaning. > I did not know. I haven't seen anyone point this out yet, but they have to be equivalent. The reader constructs the same data structure for those concrete expressions (text) before the pcase macro is ever evaluated. I would think the author is simply emphasizing that they are parsing an entity in an association list for which hookfun is a key. Lynn [-- Attachment #2: Type: text/html, Size: 2159 bytes --] ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-11-24 17:29 ` Lynn Winebarger @ 2023-11-28 2:44 ` Richard Stallman 2023-11-30 19:14 ` Lynn Winebarger 0 siblings, 1 reply; 342+ messages in thread From: Richard Stallman @ 2023-11-28 2:44 UTC (permalink / raw) To: Lynn Winebarger; +Cc: dmitry, philipk, 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 particular, what is the reason for the period and inner > > parenthsses? Why doesn't the code say this? > > > > (`(,hookfun ,start ,end ,collection . ,plist) > I would think the author is simply emphasizing that [perse is] parsing an > entity in an association list for which hookfun is a key. You may well be right about per intensions, and it is possible that a person who already fully understands what this code is doing would have realized that immediately. But a person who is just starting to look at this code, and reads that function first, is likely to be impeded in starting to reach that sort of understanding. -- Dr Richard Stallman (https://stallman.org) Chief GNUisance of the GNU Project (https://gnu.org) Founder, Free Software Foundation (https://fsf.org) Internet Hall-of-Famer (https://internethalloffame.org) ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-11-28 2:44 ` Richard Stallman @ 2023-11-30 19:14 ` Lynn Winebarger 2023-11-30 19:26 ` Eli Zaretskii 2023-12-02 3:20 ` Richard Stallman 0 siblings, 2 replies; 342+ messages in thread From: Lynn Winebarger @ 2023-11-30 19:14 UTC (permalink / raw) To: Richard Stallman; +Cc: Dmitry Gutov, Philip Kaludercic, emacs-devel [-- Attachment #1: Type: text/plain, Size: 1072 bytes --] On Mon, Nov 27, 2023, 9:44 PM Richard Stallman <rms@gnu.org> wrote: > > > > In particular, what is the reason for the period and inner > > > parenthsses? Why doesn't the code say this? > > > > > > > (`(,hookfun ,start ,end ,collection . ,plist) > > > I would think the author is simply emphasizing that [perse is] parsing > an > > entity in an association list for which hookfun is a key. > > You may well be right about per intensions, and it is possible that a > person who already fully understands what this code is doing would > have realized that immediately. > > But a person who is just starting to look at this code, and reads that > function first, is likely to be impeded in starting to reach that sort > of understanding. > I have to respectfully disagree - dotted pair notation is a pretty fundamental part of LISP syntax, regardless of dialect. There's no reason I'm aware of (for human-written code) for a dotted pair to have a list in the CDR unless the author is emphasizing the pair as being an entry in an association list. Lynn [-- Attachment #2: Type: text/html, Size: 1727 bytes --] ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-11-30 19:14 ` Lynn Winebarger @ 2023-11-30 19:26 ` Eli Zaretskii 2023-11-30 20:30 ` Michael Heerdegen via Emacs development discussions. 2023-11-30 20:47 ` João Távora 2023-12-02 3:20 ` Richard Stallman 1 sibling, 2 replies; 342+ messages in thread From: Eli Zaretskii @ 2023-11-30 19:26 UTC (permalink / raw) To: Lynn Winebarger; +Cc: rms, dmitry, philipk, emacs-devel > From: Lynn Winebarger <owinebar@gmail.com> > Date: Thu, 30 Nov 2023 14:14:04 -0500 > Cc: Dmitry Gutov <dmitry@gutov.dev>, Philip Kaludercic <philipk@posteo.net>, > emacs-devel <emacs-devel@gnu.org> > > > > > > (`(,hookfun ,start ,end ,collection . ,plist) > > > I would think the author is simply emphasizing that [perse is] parsing an > > entity in an association list for which hookfun is a key. > > You may well be right about per intensions, and it is possible that a > person who already fully understands what this code is doing would > have realized that immediately. > > But a person who is just starting to look at this code, and reads that > function first, is likely to be impeded in starting to reach that sort > of understanding. > > I have to respectfully disagree - dotted pair notation is a pretty fundamental part of LISP syntax, > regardless of dialect. I think you are missing the point. The point is that pcase has so many semi-magical syntax features that use punctuation characters in creative ways that every extra punctuation character presents a puzzle. Faced with (`(,hookfun . ,start ,end)) one immediately asks himself why the period, where in "normal" Lisp expressions it would be completely redundant? The fact that it is there then leaves one wondering whether that period has some "magical" meaning. That is the basic problem with every unusual syntax, and the reason why introducing such DSLs is a disadvantage. ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-11-30 19:26 ` Eli Zaretskii @ 2023-11-30 20:30 ` Michael Heerdegen via Emacs development discussions. 2023-12-01 6:24 ` Eli Zaretskii 2023-11-30 20:47 ` João Távora 1 sibling, 1 reply; 342+ messages in thread From: Michael Heerdegen via Emacs development discussions. @ 2023-11-30 20:30 UTC (permalink / raw) To: emacs-devel Eli Zaretskii <eliz@gnu.org> writes: > I think you are missing the point. The point is that pcase has so > many semi-magical syntax features that use punctuation characters in > creative ways that every extra punctuation character presents a > puzzle. Faced with > > (`(,hookfun . ,start ,end)) This is not a valid expression and will be rejected by the reader. Was it a typo or did you think this would be valid? > one immediately asks himself why the period, where in "normal" Lisp > expressions it would be completely redundant? As had been said: the syntax has been chosen intentionally to underline that it is important to view the matched thing as a cons instead of a list. If people get crazy about the dot, we can choose a different syntax without the dot. It is not necessary to use this syntax (unless the cdr is not a list). This point is not about `pcase' but about how the author has chosen to write the pattern. > The fact that it is there then leaves one wondering whether that > period has some "magical" meaning. As an alternative one can have a look at the docstring. And learn the read syntax of cons cells in Lisp. There is not more to wonder about as there is to wonder about the identity (X . (Y ...)) == (X Y ...) People should familiarize themselves a bit with Lisp when working with the Emacs Lisp source code. I know the above identity can be confusing _once_, in different situations, not only in `pcase', but it is something on has to know anyway, and this is really not that difficult or magical. Michael. ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-11-30 20:30 ` Michael Heerdegen via Emacs development discussions. @ 2023-12-01 6:24 ` Eli Zaretskii 2023-12-01 15:47 ` Michael Heerdegen via Emacs development discussions. 0 siblings, 1 reply; 342+ messages in thread From: Eli Zaretskii @ 2023-12-01 6:24 UTC (permalink / raw) To: Michael Heerdegen; +Cc: emacs-devel > Date: Thu, 30 Nov 2023 21:30:00 +0100 > From: Michael Heerdegen via "Emacs development discussions." <emacs-devel@gnu.org> > > Eli Zaretskii <eliz@gnu.org> writes: > > > I think you are missing the point. The point is that pcase has so > > many semi-magical syntax features that use punctuation characters in > > creative ways that every extra punctuation character presents a > > puzzle. Faced with > > > > (`(,hookfun . ,start ,end)) > > This is not a valid expression and will be rejected by the reader. Was > it a typo or did you think this would be valid? It was taken from one of the posted examples, perhaps with a typo. But that is not relevant. Are you saying pcase doesn't have constructs like (`(SOMETHING...), or that SOMETHING doesn't use periods in places where they are redundant in "normal" ELisp code? IOW, these details are not the point, the point is something else entirely, see below. > > one immediately asks himself why the period, where in "normal" Lisp > > expressions it would be completely redundant? > > As had been said: the syntax has been chosen intentionally to underline > that it is important to view the matched thing as a cons instead of a > list. My point focuses on the problems this syntax causes to someone who doesn't have intimate knowledge and a lot of practice with pcase. Thus, it is a disadvantage. Whether it is outweighed by advantages is a separate discussion; my message just pointed out that the disadvantage exists and is real, because Lynn seemed to be missing that point. > > The fact that it is there then leaves one wondering whether that > > period has some "magical" meaning. > > As an alternative one can have a look at the docstring. It is a disadvantage if one needs to consult doc strings all the time while reading code. And in this case, the doc string is quite long and highly non-trivial (and rightfully so, since the DSL is a rather complex one). > People should familiarize themselves a bit with Lisp when working with > the Emacs Lisp source code. I know the above identity can be confusing > _once_, in different situations, not only in `pcase', but it is > something on has to know anyway, and this is really not that difficult > or magical. If one bumps into such constructs very frequently, then eventually one will become familiarized with them. But if the frequency is low enough, one could easily forget the details, and then one will need to consult the documentation again the next time. Please don't underestimate these difficulties, even if you don't share them. ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-12-01 6:24 ` Eli Zaretskii @ 2023-12-01 15:47 ` Michael Heerdegen via Emacs development discussions. 2023-12-01 16:07 ` Eli Zaretskii 2023-12-01 20:27 ` Alan Mackenzie 0 siblings, 2 replies; 342+ messages in thread From: Michael Heerdegen via Emacs development discussions. @ 2023-12-01 15:47 UTC (permalink / raw) To: emacs-devel Eli Zaretskii <eliz@gnu.org> writes: > > This is not a valid expression and will be rejected by the reader. > > Was it a typo or did you think this would be valid? > > It was taken from one of the posted examples, perhaps with a typo. > But that is not relevant. My question was meant sincerely. Did you try to understand the syntax? How? What was or is still unclear to you? > Are you saying pcase doesn't have > constructs like (`(SOMETHING...), or that SOMETHING doesn't use > periods in places where they are redundant in "normal" ELisp code? Redundant - no. May there be different redundant ways to express lists - yes. If you use a backquote pattern `SOMETHING in pcase, when SOMETHING should match a cons (lists are conses), then SOMETHING will typically be a cons. The dot reader syntax is the canonical read syntax for conses. This is not that weird. > IOW, these details are not the point, the point is something else > entirely, see below [...] > My point focuses on the problems this syntax causes to someone who > doesn't have intimate knowledge and a lot of practice with pcase. It is repeatedly used a wording like "magical", as if that was an argument. Ok, this syntax makes one first wonder how it has to be interpreted. Happened to me, too. But this (the wondering) takes only seconds. What happens after that? Have people then seriously tried to understand the syntax? Where and why did they fail? I heard nothing about that. Just a repetition that it looks "strange" or "magical" or that one would expect a different syntax. Given that cons cells and lists are fundamental building blocks of the whole language, I had hoped to hear more about why understanding this would be hard. Nobody did that concretely apart from Richard. And it might be the case that his rewrite will reuse the backquote syntax. > > As an alternative one can have a look at the docstring. > > It is a disadvantage if one needs to consult doc strings all the time > while reading code. And in this case, the doc string is quite long > and highly non-trivial (and rightfully so, since the DSL is a rather > complex one). This is, or should, not be the case. Sometimes one might need to recall the argument order of 'let' or 'app', but more when writing code. I don't ever need to consult the documentation of `pcase' when reading code, apart from the case when additional pcase macros are involved (like 'map'). And I don't have a good such a good memory for such things. And I use it only in rare circumstances, where possible I prefer `if', `cond', and `if-let'. > If one bumps into such constructs very frequently, then eventually one > will become familiarized with them. But if the frequency is low > enough, one could easily forget the details, and then one will need to > consult the documentation again the next time. What I want to say is that if you need to consult documentation of backquote syntax in pcase again and again, you might not have understood it entirely. This is my question: do people fail to understand the concept, or don't they even try? > Please don't underestimate these difficulties, even if you don't share > them. I still try to understand them. Michael. ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-12-01 15:47 ` Michael Heerdegen via Emacs development discussions. @ 2023-12-01 16:07 ` Eli Zaretskii 2023-12-01 20:27 ` Alan Mackenzie 1 sibling, 0 replies; 342+ messages in thread From: Eli Zaretskii @ 2023-12-01 16:07 UTC (permalink / raw) To: Michael Heerdegen; +Cc: emacs-devel > Date: Fri, 01 Dec 2023 16:47:51 +0100 > From: Michael Heerdegen via "Emacs development discussions." <emacs-devel@gnu.org> > > > My point focuses on the problems this syntax causes to someone who > > doesn't have intimate knowledge and a lot of practice with pcase. > > It is repeatedly used a wording like "magical", as if that was an > argument. Ok, this syntax makes one first wonder how it has to be > interpreted. Happened to me, too. But this (the wondering) takes only > seconds. What happens after that? Have people then seriously tried to > understand the syntax? Where and why did they fail? I heard nothing > about that. Just a repetition that it looks "strange" or "magical" or > that one would expect a different syntax. You are asking me about what others have done. I don't know. I do know that having understood this once doesn't mean one will remember that the next time. If the meaning is complicated enough, and the next time is far enough from the previous one, one could simply forget, and then will have to make the same effort understanding that again. > Given that cons cells and lists are fundamental building blocks of the > whole language, I had hoped to hear more about why understanding this > would be hard. Nobody did that concretely apart from Richard. And it > might be the case that his rewrite will reuse the backquote syntax. We shall see. > > If one bumps into such constructs very frequently, then eventually one > > will become familiarized with them. But if the frequency is low > > enough, one could easily forget the details, and then one will need to > > consult the documentation again the next time. > > What I want to say is that if you need to consult documentation of > backquote syntax in pcase again and again, you might not have understood > it entirely. This is my question: do people fail to understand the > concept, or don't they even try? I'll let others answer this. Me, I just want to tell that complicated stuff frequently needs to be re-read several times before it sinks. Especially if these time instances are far apart. ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-12-01 15:47 ` Michael Heerdegen via Emacs development discussions. 2023-12-01 16:07 ` Eli Zaretskii @ 2023-12-01 20:27 ` Alan Mackenzie 2023-12-02 13:24 ` Michael Heerdegen via Emacs development discussions. 2023-12-03 3:28 ` Richard Stallman 1 sibling, 2 replies; 342+ messages in thread From: Alan Mackenzie @ 2023-12-01 20:27 UTC (permalink / raw) To: Michael Heerdegen; +Cc: emacs-devel Hello, Michael On Fri, Dec 01, 2023 at 16:47:51 +0100, Michael Heerdegen via Emacs development discussions. wrote: > Eli Zaretskii <eliz@gnu.org> writes: > > > This is not a valid expression and will be rejected by the reader. > > > Was it a typo or did you think this would be valid? > > It was taken from one of the posted examples, perhaps with a typo. > > But that is not relevant. > My question was meant sincerely. Did you try to understand the syntax? > How? What was or is still unclear to you? > > Are you saying pcase doesn't have > > constructs like (`(SOMETHING...), or that SOMETHING doesn't use > > periods in places where they are redundant in "normal" ELisp code? > Redundant - no. May there be different redundant ways to express lists > - yes. > If you use a backquote pattern `SOMETHING in pcase, when SOMETHING > should match a cons (lists are conses), then SOMETHING will typically be > a cons. The dot reader syntax is the canonical read syntax for conses. > This is not that weird. For some reason, I have little difficulty with dots in normal code, but have more difficulty with dots in pcase patterns. They must be being used differently. > > IOW, these details are not the point, the point is something else > > entirely, see below [...] > > My point focuses on the problems this syntax causes to someone who > > doesn't have intimate knowledge and a lot of practice with pcase. > It is repeatedly used a wording like "magical", as if that was an > argument. Ok, this syntax makes one first wonder how it has to be > interpreted. Happened to me, too. But this (the wondering) takes only > seconds. It took many hours for me. > What happens after that? Have people then seriously tried to > understand the syntax? Where and why did they fail? I heard nothing > about that. Just a repetition that it looks "strange" or "magical" or > that one would expect a different syntax. The syntax is confusing. Before the introduction of pcase (without any public discussion, as far as I can remember) a backslash meant what it meant, as did a comma. Now, if there are pcase's around I can't look at code and see what it means. For each backslash or comma, I've consciously got to stop and inspect it to see whether it's a standard b or c, or a pcase b or c. They tend to be mixed up indiscriminately. Also, special forms which had a fixed meaning have now become ambiguous - and and or. Again, it takes conscious inspection to determine whether one of these has its standard meaning, or the very different pcase meaning. > Given that cons cells and lists are fundamental building blocks of the > whole language, I had hoped to hear more about why understanding this > would be hard. Nobody did that concretely apart from Richard. And it > might be the case that his rewrite will reuse the backquote syntax. See my previous paragraphs for part of the problem. > > > As an alternative one can have a look at the docstring. > > It is a disadvantage if one needs to consult doc strings all the time > > while reading code. And in this case, the doc string is quite long > > and highly non-trivial (and rightfully so, since the DSL is a rather > > complex one). > This is, or should, not be the case. Sometimes one might need to recall > the argument order of 'let' or 'app', but more when writing code. > I don't ever need to consult the documentation of `pcase' when reading > code, apart from the case when additional pcase macros are involved > (like 'map'). And I don't have a good such a good memory for such > things. I don't have a good memory for them, either. When I have to read code with pcase stuff in it, I can't read it fluently. My consciousness is continually having to guess what the various constructs mean, which is demoralising. I don't have this problem with non-pcase code which is otherwise of the same difficulty. > And I use it only in rare circumstances, where possible I prefer `if', > `cond', and `if-let'. I only use it when maintaining other people's code. > > If one bumps into such constructs very frequently, then eventually one > > will become familiarized with them. But if the frequency is low > > enough, one could easily forget the details, and then one will need to > > consult the documentation again the next time. > What I want to say is that if you need to consult documentation of > backquote syntax in pcase again and again, you might not have understood > it entirely. This is my question: do people fail to understand the > concept, or don't they even try? It's not the concept, it's the details. The documentation for pcase on its own is probably bigger than that for all the standard Emacs Lisp flow control constructs put together. Another thing about pcase is that you can't usefully learn and use just part of it. It's all or nothing, and it's a terrific effor to learn at once. I don't recall anything like this difficulty learning, say, regexps. It also contrasts with something like German adjective endings, where one can usefully learn, say, just those for the three forms of nominative and accusative, and gradually extend one's fluency, say, when a dative ending becomes needed. > > Please don't underestimate these difficulties, even if you don't share > > them. > I still try to understand them. Yes. I hope I've done something to increase this understanding with this post. > Michael. -- Alan Mackenzie (Nuremberg, Germany). ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-12-01 20:27 ` Alan Mackenzie @ 2023-12-02 13:24 ` Michael Heerdegen via Emacs development discussions. 2023-12-02 13:51 ` Emanuel Berg 2023-12-04 3:11 ` Richard Stallman 2023-12-03 3:28 ` Richard Stallman 1 sibling, 2 replies; 342+ messages in thread From: Michael Heerdegen via Emacs development discussions. @ 2023-12-02 13:24 UTC (permalink / raw) To: emacs-devel Alan Mackenzie <acm@muc.de> writes: > The syntax is confusing. Before the introduction of pcase (without any > public discussion, as far as I can remember) a backslash [ ...you mean "backquote" I think... ] > meant what it meant, as did a comma. Now, if there are pcase's around > I can't look at code and see what it means. For each backslash or > comma, I've consciously got to stop and inspect it to see whether it's > a standard b or c, or a pcase b or c. They tend to be mixed up > indiscriminately. Is this really your main problem? The "meaning" of any values is context dependent, also of syntax when any macros are used. If you see `t' you also have to look around how it is used. What I could understand would be that the fact that backquote expressions can appear in `pcase' patterns and as well in the branch bodies could be confusing. One might not see whether one is reading a pattern description or a body. > Also, special forms which had a fixed meaning have now become ambiguous - > and and or. Again, it takes conscious inspection to determine whether > one of these has its standard meaning, or the very different pcase > meaning. So, would it help if they would be called differently, e.g. "pand" and "por"? > > I still try to understand them. > > Yes. I hope I've done something to increase this understanding with this > post. This helped a bit, thank you. I still wonder, among other things, whether a better documentation could help people to build a better mental model so that they don't need to consult the documentation again and again. Und außerdem wünsche ich gute und schnelle [zwinker!] Fortschritte beim Üben dieser schwierigen [zwinker!] Adjektivdeklinationen (selbst wenn sich gelegentlich sogar mal ein Genitiv einschleichen sollte) - und eine angenehme Vorwinterzeit - Schnee!. Michael. ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-12-02 13:24 ` Michael Heerdegen via Emacs development discussions. @ 2023-12-02 13:51 ` Emanuel Berg 2023-12-04 3:11 ` Richard Stallman 1 sibling, 0 replies; 342+ messages in thread From: Emanuel Berg @ 2023-12-02 13:51 UTC (permalink / raw) To: emacs-devel Michael Heerdegen via "Emacs development discussions." wrote: >> Also, special forms which had a fixed meaning have now >> become ambiguous - and and or. Again, it takes conscious >> inspection to determine whether one of these has its >> standard meaning, or the very different pcase meaning. > > So, would it help if they would be called differently, e.g. > "pand" and "por"? And "ror" for `rx'? Yeah, if one is skimming the code and expects to understand all of it from just doing that, maybe "pand" and "por" are better. But when you are inside something, pcase in this case, it is pretty much understood that then the rules are defined by that, not what is outside. Maybe the maintainers felt at some point they were 100% fluent with Elisp just by visual inspection with no manual decoding in the brain whatsoever, and now they feel cl-lib and pcase has ruined that fluency. So maybe the options are either getting as fluent with cl-lib and pcase as well, or, if that cannot be done, accepting that the "good old Elisp" days of total fluency is gone and it is not coming back. -- underground experts united https://dataswamp.org/~incal ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-12-02 13:24 ` Michael Heerdegen via Emacs development discussions. 2023-12-02 13:51 ` Emanuel Berg @ 2023-12-04 3:11 ` Richard Stallman 1 sibling, 0 replies; 342+ messages in thread From: Richard Stallman @ 2023-12-04 3:11 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. ]]] > Is this really your main problem? The "meaning" of any values is > context dependent, also of syntax when any macros are used. In principle, a macro can make any sort of transformations on the data inside the macro form. In practice, nearly all macros fall into a limited range of syntax patters. Macros that do drastic things with syntax, such as `pcase', are few. Most macros' syntax is obvious when you see it. -- Dr Richard Stallman (https://stallman.org) Chief GNUisance of the GNU Project (https://gnu.org) Founder, Free Software Foundation (https://fsf.org) Internet Hall-of-Famer (https://internethalloffame.org) ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-12-01 20:27 ` Alan Mackenzie 2023-12-02 13:24 ` Michael Heerdegen via Emacs development discussions. @ 2023-12-03 3:28 ` Richard Stallman 1 sibling, 0 replies; 342+ messages in thread From: Richard Stallman @ 2023-12-03 3:28 UTC (permalink / raw) To: Alan Mackenzie; +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. ]]] What do you think of the `cond*' construct that I'm designing? It's not finished, but what do you think of the current draft? Do you find it clearer than pcase? I hope so, but I'd like to check the reality. -- Dr Richard Stallman (https://stallman.org) Chief GNUisance of the GNU Project (https://gnu.org) Founder, Free Software Foundation (https://fsf.org) Internet Hall-of-Famer (https://internethalloffame.org) ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-11-30 19:26 ` Eli Zaretskii 2023-11-30 20:30 ` Michael Heerdegen via Emacs development discussions. @ 2023-11-30 20:47 ` João Távora 2023-12-01 6:31 ` Eli Zaretskii 1 sibling, 1 reply; 342+ messages in thread From: João Távora @ 2023-11-30 20:47 UTC (permalink / raw) To: Eli Zaretskii; +Cc: Lynn Winebarger, rms, dmitry, philipk, emacs-devel On Thu, Nov 30, 2023 at 7:27 PM Eli Zaretskii <eliz@gnu.org> wrote: > I think you are missing the point. The point is that pcase has so > many semi-magical syntax features that use punctuation characters in > creative ways that every extra punctuation character presents a > puzzle. Faced with > > (`(,hookfun . ,start ,end)) > > one immediately asks himself why the period, > where in "normal" Lisp expressions it would be completely > redundant? FWIW the period is pretty self-evident to me that it separates a car from a cdr in given cell of a cons chain. However, in your example this is an error, just as it is in this "normal" expression if what you wanted was to construct a list. `(,hookfun . ,start ,end) So I think you probably meant `(,hookfun . (,start ,end)) And this is valid in both pcase and normal backquoted list expressions. Furthermore, here the period is _not_ redundant. IMO what's relatively contrived in pcase-- but very well contrived I should add -- is the use of the backtick and comma, whose usual job is output and list construction, to do the reverse, to express input and list destructure. João ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-11-30 20:47 ` João Távora @ 2023-12-01 6:31 ` Eli Zaretskii 2023-12-01 7:07 ` Yuri Khan ` (3 more replies) 0 siblings, 4 replies; 342+ messages in thread From: Eli Zaretskii @ 2023-12-01 6:31 UTC (permalink / raw) To: João Távora; +Cc: owinebar, rms, dmitry, philipk, emacs-devel > From: João Távora <joaotavora@gmail.com> > Date: Thu, 30 Nov 2023 20:47:22 +0000 > Cc: Lynn Winebarger <owinebar@gmail.com>, rms@gnu.org, dmitry@gutov.dev, philipk@posteo.net, > emacs-devel@gnu.org > > On Thu, Nov 30, 2023 at 7:27 PM Eli Zaretskii <eliz@gnu.org> wrote: > > So I think you probably meant > > `(,hookfun . (,start ,end)) > > And this is valid in both pcase and normal backquoted list > expressions. Furthermore, here the period is _not_ redundant. The validity is not the point I wanted to make. The point I wanted to make is that the accepted syntax includes unusual uses of the period and other punctuation, some of which have special meaning. And that makes the code harder to read and understand. Incidentally, the actual code from which this were taken is (`(,hookfun . (,start ,end ,collection . ,plist)) Which has _two_ periods, not one, which are AFAIU redundant, as far as the Lisp reader is concerned. > IMO what's relatively contrived in pcase-- but very well contrived > I should add -- is the use of the backtick and comma, whose > usual job is output and list construction, to do the reverse, > to express input and list destructure. Again, the point is not that the construct cannot be explained away or interpreted correctly given enough time and consulting the docs. The point is the _effort_ required to understand this without being an expert on using pcase. That is the point Richard was making, and that is the _only_ point I wanted Lynn to understand. ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-12-01 6:31 ` Eli Zaretskii @ 2023-12-01 7:07 ` Yuri Khan 2023-12-01 8:10 ` Eli Zaretskii 2023-12-01 8:35 ` Andreas Schwab ` (2 subsequent siblings) 3 siblings, 1 reply; 342+ messages in thread From: Yuri Khan @ 2023-12-01 7:07 UTC (permalink / raw) To: Eli Zaretskii Cc: João Távora, owinebar, rms, dmitry, philipk, emacs-devel On Fri, 1 Dec 2023 at 13:32, Eli Zaretskii <eliz@gnu.org> wrote: > Incidentally, the actual code from which this were taken is > > (`(,hookfun . (,start ,end ,collection . ,plist)) > > Which has _two_ periods, not one, which are AFAIU redundant, as far as > the Lisp reader is concerned. The first period and the parentheses are redundant but they are helpful because they emphasize that the first element and the rest of the list come from different places. The second period is not redundant. It causes the (,start ,end ,collection . ,plist) to match any list of 3+ elements and the ,plist binding to receive the remainder. Without the period, (,start ,end ,collection ,plist) would only match a list of exactly 4 elements, and ,plist would bind to the fourth. Maybe you are implying ,x is equivalent to (\, x) and so `(,hookfun . (,start ,end ,collection . ,plist)) could be written `((\, hookfun) (\, start) (\, end) (\, collection) \, plist). To me, that would be… point-less? ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-12-01 7:07 ` Yuri Khan @ 2023-12-01 8:10 ` Eli Zaretskii 2023-12-01 9:04 ` Andreas Schwab 2023-12-01 10:13 ` João Távora 0 siblings, 2 replies; 342+ messages in thread From: Eli Zaretskii @ 2023-12-01 8:10 UTC (permalink / raw) To: Yuri Khan; +Cc: joaotavora, owinebar, rms, dmitry, philipk, emacs-devel > From: Yuri Khan <yuri.v.khan@gmail.com> > Date: Fri, 1 Dec 2023 14:07:40 +0700 > Cc: João Távora <joaotavora@gmail.com>, > owinebar@gmail.com, rms@gnu.org, dmitry@gutov.dev, philipk@posteo.net, > emacs-devel@gnu.org > > On Fri, 1 Dec 2023 at 13:32, Eli Zaretskii <eliz@gnu.org> wrote: > > > Incidentally, the actual code from which this were taken is > > > > (`(,hookfun . (,start ,end ,collection . ,plist)) > > > > Which has _two_ periods, not one, which are AFAIU redundant, as far as > > the Lisp reader is concerned. > > The first period and the parentheses are redundant but they are > helpful because they emphasize that the first element and the rest of > the list come from different places. > > The second period is not redundant. It causes the (,start ,end > ,collection . ,plist) to match any list of 3+ elements and the ,plist > binding to receive the remainder. Without the period, (,start ,end > ,collection ,plist) would only match a list of exactly 4 elements, and > ,plist would bind to the fourth. Exactly my point: these periods and other special characters are "magic" in pcase, but not elsewhere in Lisp. Sometimes they are just for better readability, sometimes they are significant in other ways. ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-12-01 8:10 ` Eli Zaretskii @ 2023-12-01 9:04 ` Andreas Schwab 2023-12-04 3:08 ` Richard Stallman 2023-12-01 10:13 ` João Távora 1 sibling, 1 reply; 342+ messages in thread From: Andreas Schwab @ 2023-12-01 9:04 UTC (permalink / raw) To: Eli Zaretskii Cc: Yuri Khan, joaotavora, owinebar, rms, dmitry, philipk, emacs-devel On Dez 01 2023, Eli Zaretskii wrote: > Exactly my point: these periods and other special characters are > "magic" in pcase, but not elsewhere in Lisp. This is not true. There is no magic at all in the use of this reader feature which is totally lost after reading. It is absolutely impossible to detect its use afterwards. -- Andreas Schwab, schwab@linux-m68k.org GPG Key fingerprint = 7578 EB47 D4E5 4D69 2510 2552 DF73 E780 A9DA AEC1 "And now for something completely different." ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-12-01 9:04 ` Andreas Schwab @ 2023-12-04 3:08 ` Richard Stallman 2023-12-04 11:58 ` Eli Zaretskii 0 siblings, 1 reply; 342+ messages in thread From: Richard Stallman @ 2023-12-04 3:08 UTC (permalink / raw) To: Andreas Schwab; +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. ]]] > This is not true. There is no magic at all in the use of this reader > feature which is totally lost after reading. It is absolutely > impossible to detect its use afterwards. As a factual matter about dotted pairs in pcase patterns, that is correct. However, we have repeatedly seen that experienced Lispers, who would have no trouble understanding those constructs in a backquote meant to actually construct a structure of conses, don't know what to make of them on encountering them in pcase patterns. That's another factual matter about dotted pairs in pcase patterns. It is more a psychological matter than a computational matter, but that doesn't invalidate the observation. It is part of the impact of complexity of pcase. -- Dr Richard Stallman (https://stallman.org) Chief GNUisance of the GNU Project (https://gnu.org) Founder, Free Software Foundation (https://fsf.org) Internet Hall-of-Famer (https://internethalloffame.org) ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-12-04 3:08 ` Richard Stallman @ 2023-12-04 11:58 ` Eli Zaretskii 2023-12-04 12:35 ` Lynn Winebarger 2023-12-04 12:37 ` Dmitry Gutov 0 siblings, 2 replies; 342+ messages in thread From: Eli Zaretskii @ 2023-12-04 11:58 UTC (permalink / raw) To: rms; +Cc: schwab, emacs-devel > From: Richard Stallman <rms@gnu.org> > Cc: emacs-devel@gnu.org > Date: Sun, 03 Dec 2023 22:08:21 -0500 > > > This is not true. There is no magic at all in the use of this reader > > feature which is totally lost after reading. It is absolutely > > impossible to detect its use afterwards. > > As a factual matter about dotted pairs in pcase patterns, that is > correct. > > However, we have repeatedly seen that experienced Lispers, who would > have no trouble understanding those constructs in a backquote meant to > actually construct a structure of conses, don't know what to make of > them on encountering them in pcase patterns. > > That's another factual matter about dotted pairs in pcase patterns. > It is more a psychological matter than a computational matter, but > that doesn't invalidate the observation. > > It is part of the impact of complexity of pcase. Some people are saying that everything is clear because the Lisp reader does this and that. But when humans read code, they don't normally run the Lisp reader in their head, they use other techniques to read and grasp what the code does. If there's a need to ask what does the Lisp reader do with some syntax, that is already an obstacle to understanding the code, even though eventually one can understand it, whether by thinking what the reader does or by actually running the reader and/or macro-expansion. ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-12-04 11:58 ` Eli Zaretskii @ 2023-12-04 12:35 ` Lynn Winebarger 2023-12-04 13:20 ` Eli Zaretskii 2023-12-04 12:37 ` Dmitry Gutov 1 sibling, 1 reply; 342+ messages in thread From: Lynn Winebarger @ 2023-12-04 12:35 UTC (permalink / raw) To: Eli Zaretskii; +Cc: Richard Stallman, schwab, emacs-devel [-- Attachment #1: Type: text/plain, Size: 1772 bytes --] On Mon, Dec 4, 2023, 6:58 AM Eli Zaretskii <eliz@gnu.org> wrote: > > From: Richard Stallman <rms@gnu.org> > > Cc: emacs-devel@gnu.org > > Date: Sun, 03 Dec 2023 22:08:21 -0500 > > > > > This is not true. There is no magic at all in the use of this reader > > > feature which is totally lost after reading. It is absolutely > > > impossible to detect its use afterwards. > > > > As a factual matter about dotted pairs in pcase patterns, that is > > correct. > > > > However, we have repeatedly seen that experienced Lispers, who would > > have no trouble understanding those constructs in a backquote meant to > > actually construct a structure of conses, don't know what to make of > > them on encountering them in pcase patterns. > > > > That's another factual matter about dotted pairs in pcase patterns. > > It is more a psychological matter than a computational matter, but > > that doesn't invalidate the observation. > > > > It is part of the impact of complexity of pcase. > > Some people are saying that everything is clear because the Lisp > reader does this and that. But when humans read code, they don't > normally run the Lisp reader in their head, they use other techniques > to read and grasp what the code does. If there's a need to ask what > does the Lisp reader do with some syntax, that is already an obstacle > to understanding the code, even though eventually one can understand > it, whether by thinking what the reader does or by actually running > the reader and/or macro-expansion. > I'm saying it makes no sense to me to lay the blame at the feet of the pcase syntax. Elisp will happily evaluate the expression (if . ( t . (nil . (t . nil)))) Would you, or anyone, say that reflects some flaw in the design of the "if" form? Lynn [-- Attachment #2: Type: text/html, Size: 2844 bytes --] ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-12-04 12:35 ` Lynn Winebarger @ 2023-12-04 13:20 ` Eli Zaretskii 2023-12-04 17:46 ` Andreas Schwab 2023-12-04 18:17 ` Lynn Winebarger 0 siblings, 2 replies; 342+ messages in thread From: Eli Zaretskii @ 2023-12-04 13:20 UTC (permalink / raw) To: Lynn Winebarger; +Cc: rms, schwab, emacs-devel > From: Lynn Winebarger <owinebar@gmail.com> > Date: Mon, 4 Dec 2023 07:35:48 -0500 > Cc: Richard Stallman <rms@gnu.org>, schwab@linux-m68k.org, > emacs-devel <emacs-devel@gnu.org> > > Elisp will happily evaluate the expression > (if . ( t . (nil . (t . nil)))) > > Would you, or anyone, say that reflects some flaw in the design of the "if" form? No, but if someone writes such 'if' forms, I will ask them to rewrite them. IOW, the fact that the Lisp reader will happily read something does not mean it is easily understandable by humans, or should freely be used in Emacs. ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-12-04 13:20 ` Eli Zaretskii @ 2023-12-04 17:46 ` Andreas Schwab 2023-12-07 2:48 ` Richard Stallman 2023-12-04 18:17 ` Lynn Winebarger 1 sibling, 1 reply; 342+ messages in thread From: Andreas Schwab @ 2023-12-04 17:46 UTC (permalink / raw) To: Eli Zaretskii; +Cc: Lynn Winebarger, rms, emacs-devel On Dez 04 2023, Eli Zaretskii wrote: >> From: Lynn Winebarger <owinebar@gmail.com> >> Date: Mon, 4 Dec 2023 07:35:48 -0500 >> Cc: Richard Stallman <rms@gnu.org>, schwab@linux-m68k.org, >> emacs-devel <emacs-devel@gnu.org> >> >> Elisp will happily evaluate the expression >> (if . ( t . (nil . (t . nil)))) >> >> Would you, or anyone, say that reflects some flaw in the design of the "if" form? > > No, but if someone writes such 'if' forms, I will ask them to rewrite > them. There are 1802 occurrences of the sequence " . (" in the Emacs lisp files. -- Andreas Schwab, schwab@linux-m68k.org GPG Key fingerprint = 7578 EB47 D4E5 4D69 2510 2552 DF73 E780 A9DA AEC1 "And now for something completely different." ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-12-04 17:46 ` Andreas Schwab @ 2023-12-07 2:48 ` Richard Stallman 2023-12-07 17:42 ` Andreas Schwab 0 siblings, 1 reply; 342+ messages in thread From: Richard Stallman @ 2023-12-07 2:48 UTC (permalink / raw) To: Andreas Schwab; +Cc: eliz, owinebar, 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. ]]] > >> Elisp will happily evaluate the expression > >> (if . ( t . (nil . (t . nil)))) > >> > >> Would you, or anyone, say that reflects some flaw in the design of the "if" form? > > > > No, but if someone writes such 'if' forms, I will ask them to rewrite > > them. > There are 1802 occurrences of the sequence " . (" in the Emacs lisp > files. I will take your word for it -- but di you realize that you changed the subject? Occurrences of the sequence " . (" in the Emacs sources are mostly not part of the issue at hand. -- Dr Richard Stallman (https://stallman.org) Chief GNUisance of the GNU Project (https://gnu.org) Founder, Free Software Foundation (https://fsf.org) Internet Hall-of-Famer (https://internethalloffame.org) ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-12-07 2:48 ` Richard Stallman @ 2023-12-07 17:42 ` Andreas Schwab 2023-12-09 4:02 ` Richard Stallman 0 siblings, 1 reply; 342+ messages in thread From: Andreas Schwab @ 2023-12-07 17:42 UTC (permalink / raw) To: Richard Stallman; +Cc: eliz, owinebar, emacs-devel On Dez 06 2023, Richard Stallman wrote: > I will take your word for it -- but di you realize that you changed > the subject? No, not at all. It's 100% spot on. -- Andreas Schwab, schwab@linux-m68k.org GPG Key fingerprint = 7578 EB47 D4E5 4D69 2510 2552 DF73 E780 A9DA AEC1 "And now for something completely different." ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-12-07 17:42 ` Andreas Schwab @ 2023-12-09 4:02 ` Richard Stallman 0 siblings, 0 replies; 342+ messages in thread From: Richard Stallman @ 2023-12-09 4:02 UTC (permalink / raw) To: Andreas Schwab; +Cc: eliz, owinebar, 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. ]]] > > I will take your word for it -- but di you realize that you changed > > the subject? > No, not at all. It's 100% spot on. I suppose Eli and others will see that I am right. -- Dr Richard Stallman (https://stallman.org) Chief GNUisance of the GNU Project (https://gnu.org) Founder, Free Software Foundation (https://fsf.org) Internet Hall-of-Famer (https://internethalloffame.org) ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-12-04 13:20 ` Eli Zaretskii 2023-12-04 17:46 ` Andreas Schwab @ 2023-12-04 18:17 ` Lynn Winebarger 1 sibling, 0 replies; 342+ messages in thread From: Lynn Winebarger @ 2023-12-04 18:17 UTC (permalink / raw) To: Eli Zaretskii; +Cc: Richard Stallman, schwab, emacs-devel [-- Attachment #1: Type: text/plain, Size: 1247 bytes --] On Mon, Dec 4, 2023, 8:20 AM Eli Zaretskii <eliz@gnu.org> wrote: > > From: Lynn Winebarger <owinebar@gmail.com> > > Date: Mon, 4 Dec 2023 07:35:48 -0500 > > Cc: Richard Stallman <rms@gnu.org>, schwab@linux-m68k.org, > > emacs-devel <emacs-devel@gnu.org> > > > > Elisp will happily evaluate the expression > > (if . ( t . (nil . (t . nil)))) > > > > Would you, or anyone, say that reflects some flaw in the design of the > "if" form? > > No, but if someone writes such 'if' forms, I will ask them to rewrite > them. > > IOW, the fact that the Lisp reader will happily read something does > not mean it is easily understandable by humans, or should freely be > used in Emacs. > Right, it's a style issue. The issue Richard raised that I've begun to appreciate is that backquote is redefined in the context of patterns in a way that is not compatible with its definition everywhere else. I don't think the same could be said of the "," and ",@" read-syntax or symbols, because those symbols are not defined as macros themselves, only as auxiliary syntax in the context of quasiquotation. It should be fine to incorporate them as auxiliary syntax in the context of a destructuring macro, preferably with a reasonably consistent semantics. Lynn [-- Attachment #2: Type: text/html, Size: 2304 bytes --] ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-12-04 11:58 ` Eli Zaretskii 2023-12-04 12:35 ` Lynn Winebarger @ 2023-12-04 12:37 ` Dmitry Gutov 2023-12-08 3:54 ` Richard Stallman 1 sibling, 1 reply; 342+ messages in thread From: Dmitry Gutov @ 2023-12-04 12:37 UTC (permalink / raw) To: Eli Zaretskii, rms; +Cc: schwab, emacs-devel On 04/12/2023 13:58, Eli Zaretskii wrote: >> From: Richard Stallman<rms@gnu.org> >> Cc:emacs-devel@gnu.org >> Date: Sun, 03 Dec 2023 22:08:21 -0500 >> >> > This is not true. There is no magic at all in the use of this reader >> > feature which is totally lost after reading. It is absolutely >> > impossible to detect its use afterwards. >> >> As a factual matter about dotted pairs in pcase patterns, that is >> correct. >> >> However, we have repeatedly seen that experienced Lispers, who would >> have no trouble understanding those constructs in a backquote meant to >> actually construct a structure of conses, don't know what to make of >> them on encountering them in pcase patterns. >> >> That's another factual matter about dotted pairs in pcase patterns. >> It is more a psychological matter than a computational matter, but >> that doesn't invalidate the observation. >> >> It is part of the impact of complexity of pcase. > Some people are saying that everything is clear because the Lisp > reader does this and that. But when humans read code, they don't > normally run the Lisp reader in their head, they use other techniques > to read and grasp what the code does. If there's a need to ask what > does the Lisp reader do with some syntax, that is already an obstacle > to understanding the code, even though eventually one can understand > it, whether by thinking what the reader does or by actually running > the reader and/or macro-expansion. Note that this subthread is not about pcase but about a particular instance where it was used together with the dotted syntax. In other places, people would use the dotted reader syntax inside a backquote without pcase, and the above considerations would stil apply. Finally, in the example that was brought up, the dot syntax really *was* used to make comprehension more easy. But to see that you have to actually read the surrounding code and try to understand the data flow. And if the dotted syntax were not used, the spectator *would* have to conjure up the knowledge that (a . (b c)) is the same as (a b c). Whereas the current solution avoids that need. ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-12-04 12:37 ` Dmitry Gutov @ 2023-12-08 3:54 ` Richard Stallman 0 siblings, 0 replies; 342+ messages in thread From: Richard Stallman @ 2023-12-08 3:54 UTC (permalink / raw) To: Dmitry Gutov; +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. ]]] > Note that this subthread is not about pcase but about a particular > instance where it was used together with the dotted syntax. That is true. But please keep in mind that this example is presented to people as a way to learn to understand pcase. In other > places, people would use the dotted reader syntax inside a backquote > without pcase, and the above considerations would stil apply. If "the above considerations" means the point that I raised, I don't think they would. My point was that that I am accustomed to reading, and writing, backquote constructs with periods -- usually before commas -- and I found this pcase hard to understand given that basis. > Finally, in the example that was brought up, the dot syntax really *was* > used to make comprehension more easy. But to see that you have to > actually read the surrounding code and try to understand the data flow. I did not come across in reading the code of a file. I have never even seen the surrounding code. I asked about what the valid options for that data would be, but got a nonresponsive reply. -- Dr Richard Stallman (https://stallman.org) Chief GNUisance of the GNU Project (https://gnu.org) Founder, Free Software Foundation (https://fsf.org) Internet Hall-of-Famer (https://internethalloffame.org) ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-12-01 8:10 ` Eli Zaretskii 2023-12-01 9:04 ` Andreas Schwab @ 2023-12-01 10:13 ` João Távora 1 sibling, 0 replies; 342+ messages in thread From: João Távora @ 2023-12-01 10:13 UTC (permalink / raw) To: Eli Zaretskii; +Cc: Yuri Khan, owinebar, rms, dmitry, philipk, emacs-devel On Fri, Dec 1, 2023 at 8:10 AM Eli Zaretskii <eliz@gnu.org> wrote: > Exactly my point: these periods and other special characters are > "magic" in pcase, but not elsewhere in Lisp. Sometimes they are just > for better readability, sometimes they are significant in other ways. What you're saying isn't correct, Eli. That period you are pointing to has _exactly_ the same magic "elsewhere in Lisp" as it does in "pcase". Forget pcase for a minute. "Elsewhere in Lisp", if all those 5 symbols are bound, then your example (now corrected): `(,hookfun . (,start ,end ,collection . ,plist)) produces a list made up with four cons cells. If you take out the periods: `(,hookfun (,start ,end ,collection ,plist)) This still produces a list, but now it's made up of six cons cells! That's a world of difference. In a different email, I've explained how, both in 'pcase' and "elsewhere in Lisp", your example can be rewritten with one less period to still use four cons cells exactly. João ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-12-01 6:31 ` Eli Zaretskii 2023-12-01 7:07 ` Yuri Khan @ 2023-12-01 8:35 ` Andreas Schwab 2023-12-01 10:02 ` João Távora 2023-12-01 16:04 ` Michael Heerdegen via Emacs development discussions. 3 siblings, 0 replies; 342+ messages in thread From: Andreas Schwab @ 2023-12-01 8:35 UTC (permalink / raw) To: Eli Zaretskii Cc: João Távora, owinebar, rms, dmitry, philipk, emacs-devel On Dez 01 2023, Eli Zaretskii wrote: > Incidentally, the actual code from which this were taken is > > (`(,hookfun . (,start ,end ,collection . ,plist)) > > Which has _two_ periods, not one, which are AFAIU redundant, as far as > the Lisp reader is concerned. This is an intrinsic part of Lisp which has nothing at all to do with pcase. It is frequently used throughout the whole Emacs codebase. -- Andreas Schwab, schwab@linux-m68k.org GPG Key fingerprint = 7578 EB47 D4E5 4D69 2510 2552 DF73 E780 A9DA AEC1 "And now for something completely different." ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-12-01 6:31 ` Eli Zaretskii 2023-12-01 7:07 ` Yuri Khan 2023-12-01 8:35 ` Andreas Schwab @ 2023-12-01 10:02 ` João Távora 2023-12-01 11:52 ` Eli Zaretskii 2024-01-09 5:33 ` Stefan Kangas 2023-12-01 16:04 ` Michael Heerdegen via Emacs development discussions. 3 siblings, 2 replies; 342+ messages in thread From: João Távora @ 2023-12-01 10:02 UTC (permalink / raw) To: Eli Zaretskii; +Cc: owinebar, rms, dmitry, philipk, emacs-devel On Fri, Dec 1, 2023 at 6:31 AM Eli Zaretskii <eliz@gnu.org> wrote: > The validity is not the point I wanted to make. The point I wanted to > make is that the accepted syntax includes unusual uses of the period > and other punctuation, some of which have special meaning. And that > makes the code harder to read and understand. > > Incidentally, the actual code from which this were taken is > > (`(,hookfun . (,start ,end ,collection . ,plist)) > > Which has _two_ periods, not one, which are AFAIU redundant, as far as > the Lisp reader is concerned. They are NOT redundant. Meaning you can't simply take them out and have the expression mean the same: that's what "redundant" means to me, at least. But like so often in programming, there are different ways to say the same. In pcase as in normal list-making life, the above form is the same as. (`(,hookfun ,start ,end ,collection . plist)) So while it's reasonable to take issue with the author's choice of one of many equivalent list-representing constructs, I don't think one should blame their choice of 'pcase' here. Personally, I don't really fault the author too much in this case: if the thing to be destructured were an entry of an alist, I actually like to see things represented in the original alternative. As you probably know, one as a maintainer often has to work with data structures that one didn't invent and wishes weren't like they are. Very often these structures are contorted, incrementally evolving lists where certain positional elements mean certain things for the structure. One may be completely innocent of inventing this spaghetti and yet one has to work with it. This happens very frequently in Emacs, it certainly happens to me. > > IMO what's relatively contrived in pcase-- but very well contrived > > I should add -- is the use of the backtick and comma, whose > > usual job is output and list construction, to do the reverse, > > to express input and list destructure. > > Again, the point is not that the construct cannot be explained away or > interpreted correctly given enough time and consulting the docs. First, I'd like to say that when I first met pcase, I used to share your views and now I don't. It's not that I encounter pcase on constantly these days (I don't), it's just that I quickly changed my view once someone gave me a piece of insight about it. That insight has already surfaced here, but perhaps has not been underlined enough. So, in these emails, I'm trying to explain to you how to change your view of these pcase constructs in a constructive way, to help speed up your understanding of important parts of our code base. I hope this message gets across. If you've already decided you will never understand 'pcase' and will forever reach for the docs, that's a legitimate position, but it also means I can't be much help in this sub-discussion. It is _easy_ to explain that "scary" construct _if_ you learn to _lean_ on what should be probably existing knowledge. No doc-consulting necessary. You take a backtick-starting construct with as many scary periods things as you can find and then, say `(,foo . (,bar . ,baz)) And then ask yourself: "what kind of list does this build if I just let-bind foo, bar and baz to 42?". And then you answer yourself "Why, it's the improper list (42 42 . 42) made up of just two cons cells and 3 fixnums!". So _that's_ the kind of list that can be destructured with the pcase expression. This solves the reading problem. Now the writing problem. To author new pcase patterns one uses more or less the same process. One again leans on one's existing knowledge of how the list structure would be expressed with backtick-and-quote. So once you know the list structure in your mind you write it as a backtick-and-quote expression, just as if you were going to craft that list (though you aren't of course). Then once you're happy with your expression, you may take it and you put it in one of the BINDINGS left-hand part of a 'let'. Then you rename that 'let' to 'pcase-let' and away you go! HTH ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-12-01 10:02 ` João Távora @ 2023-12-01 11:52 ` Eli Zaretskii 2023-12-01 12:48 ` Dmitry Gutov ` (2 more replies) 2024-01-09 5:33 ` Stefan Kangas 1 sibling, 3 replies; 342+ messages in thread From: Eli Zaretskii @ 2023-12-01 11:52 UTC (permalink / raw) To: João Távora; +Cc: owinebar, rms, dmitry, philipk, emacs-devel > From: João Távora <joaotavora@gmail.com> > Date: Fri, 1 Dec 2023 10:02:37 +0000 > Cc: owinebar@gmail.com, rms@gnu.org, dmitry@gutov.dev, philipk@posteo.net, > emacs-devel@gnu.org > > On Fri, Dec 1, 2023 at 6:31 AM Eli Zaretskii <eliz@gnu.org> wrote: > > So, in these emails, I'm trying to explain to you how to change your > view of these pcase constructs in a constructive way This is a misunderstanding: I'm not expressing _my_ views. I'm expressing the views of someone who bumps into this code the first or the second time, and/or didn't yet have the advantage of someone giving them "a piece of insight" that caused you to change your mind. IOW, I'm expressing _your_ views before you changed your mind. In Emacs development and maintenance, being able to look at stuff from the POV of an innocent user or Lisp programmer is sometimes required to realize the true impact of some constructs and features. We cannot regard that only from the height of our own knowledge and experience, which usually far surpass those of many Emacs users and programmers. > You take a backtick-starting construct with as many scary periods > things as you can find and then, say > > `(,foo . (,bar . ,baz)) > > And then ask yourself: "what kind of list does this build if I just > let-bind foo, bar and baz to 42?". And then you answer yourself > "Why, it's the improper list (42 42 . 42) made up of just two cons > cells and 3 fixnums!". So _that's_ the kind of list that can be > destructured with the pcase expression. > > This solves the reading problem. Now the writing problem. To author > new pcase patterns one uses more or less the same process. One again > leans on one's existing knowledge of how the list structure would be > expressed with backtick-and-quote. So once you know the list > structure in your mind you write it as a backtick-and-quote expression, > just as if you were going to craft that list (though you aren't of > course). Then once you're happy with your expression, you may take it > and you put it in one of the BINDINGS left-hand part of a 'let'. > Then you rename that 'let' to 'pcase-let' and away you go! If this is that easy, then why do we need no less than 120 lines to describe pcase in the doc string, and no less than 600 lines to document its features in the ELisp manual? You and others seem to assume that I'm against pcase, or that I'm attacking its syntax, or don't understand it. Andreas Schwab has even gone as far as lecture me on the basics of the Lisp reader and the syntax of Emacs Lisp, apparently under the assumption that I don't understand that. None of that is true. All I'm trying to say is that there _are_ inherent problems in the DSL whose knowledge is required to understand code written using pcase, and that you and others should recognize these inherent problems are real, even though you have overcome them, and anyone could overcome them given enough time and experience. ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-12-01 11:52 ` Eli Zaretskii @ 2023-12-01 12:48 ` Dmitry Gutov 2023-12-01 14:44 ` Eli Zaretskii 2023-12-01 13:28 ` João Távora 2023-12-01 16:25 ` Andreas Schwab 2 siblings, 1 reply; 342+ messages in thread From: Dmitry Gutov @ 2023-12-01 12:48 UTC (permalink / raw) To: Eli Zaretskii, João Távora; +Cc: owinebar, rms, philipk, emacs-devel On 01/12/2023 13:52, Eli Zaretskii wrote: > If this is that easy, then why do we need no less than 120 lines to > describe pcase in the doc string, and no less than 600 lines to > document its features in the ELisp manual? Most of those describe the extensions, or additional features, which are not essential to understanding the basics, to understand the examples which we were looking at in this thread. > All I'm trying to say is that > there_are_ inherent problems in the DSL whose knowledge is required > to understand code written using pcase, and that you and others should > recognize these inherent problems are real, even though you have > overcome them, and anyone could overcome them given enough time and > experience. Most of us can agree that these DLS have associated costs. Whether they are "problems" (to be fixed?), meaning the costs outweigh the benefits, seems to be the main theme of this thread. ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-12-01 12:48 ` Dmitry Gutov @ 2023-12-01 14:44 ` Eli Zaretskii 2023-12-01 18:28 ` Dmitry Gutov 0 siblings, 1 reply; 342+ messages in thread From: Eli Zaretskii @ 2023-12-01 14:44 UTC (permalink / raw) To: Dmitry Gutov; +Cc: joaotavora, owinebar, rms, philipk, emacs-devel > Date: Fri, 1 Dec 2023 14:48:22 +0200 > Cc: owinebar@gmail.com, rms@gnu.org, philipk@posteo.net, emacs-devel@gnu.org > From: Dmitry Gutov <dmitry@gutov.dev> > > On 01/12/2023 13:52, Eli Zaretskii wrote: > > If this is that easy, then why do we need no less than 120 lines to > > describe pcase in the doc string, and no less than 600 lines to > > document its features in the ELisp manual? > > Most of those describe the extensions, or additional features, which are > not essential to understanding the basics, to understand the examples > which we were looking at in this thread. This doesn't match the reality. The node "pcase Macro" holds over 400 lines. The first 145 lines describe the various feature of pcase itself. The rest are examples and caveats, but the very fact that we decided to have them there means that pcase is not easy to understand. The node "Extending pcase" is indeed about extensions, which is why I didn't include its line count in the number above. The node "Backquote Patterns" is actually part of the pcase description in the "pcase Macro" node, and was moved to a separate node for methodological and didactic reasons; it holds more than 100 lines. The node "Destructuring with pcase Patterns" describes an important part of pcase functionality. At least the first 45 lines of it are about pcase, even if you consider pcase-let etc. as "extensions". So, even if you want to exclude "extensions and additional features", the description takes 145+100+45=290 lines, or 400+100+45=545 if you agree that all of the first node is documentation, not "extensions". That's quite a lot, and we have all that for a reason: you may remember the disputes and several significant edits that this section went through, because the original, much shorter text was deemed insufficient. > > All I'm trying to say is that > > there_are_ inherent problems in the DSL whose knowledge is required > > to understand code written using pcase, and that you and others should > > recognize these inherent problems are real, even though you have > > overcome them, and anyone could overcome them given enough time and > > experience. > > Most of us can agree that these DLS have associated costs. Then we agree. I just attempted to broaden this agreement. > Whether they are "problems" (to be fixed?), meaning the costs outweigh > the benefits, seems to be the main theme of this thread. You read too much into the words. "Problems" are not necessarily something that must be fixed, and "costs" is not necessarily something that need not be fixed. Those are basically synonyms in this discussion. ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-12-01 14:44 ` Eli Zaretskii @ 2023-12-01 18:28 ` Dmitry Gutov 2023-12-01 18:40 ` Eli Zaretskii 2023-12-01 18:45 ` João Távora 0 siblings, 2 replies; 342+ messages in thread From: Dmitry Gutov @ 2023-12-01 18:28 UTC (permalink / raw) To: Eli Zaretskii; +Cc: joaotavora, owinebar, rms, philipk, emacs-devel On 01/12/2023 16:44, Eli Zaretskii wrote: >> Date: Fri, 1 Dec 2023 14:48:22 +0200 >> Cc: owinebar@gmail.com, rms@gnu.org, philipk@posteo.net, emacs-devel@gnu.org >> From: Dmitry Gutov <dmitry@gutov.dev> >> >> On 01/12/2023 13:52, Eli Zaretskii wrote: >>> If this is that easy, then why do we need no less than 120 lines to >>> describe pcase in the doc string, and no less than 600 lines to >>> document its features in the ELisp manual? >> >> Most of those describe the extensions, or additional features, which are >> not essential to understanding the basics, to understand the examples >> which we were looking at in this thread. > > This doesn't match the reality. > > The node "pcase Macro" holds over 400 lines. The first 145 lines > describe the various feature of pcase itself. The rest are examples > and caveats, but the very fact that we decided to have them there > means that pcase is not easy to understand. > > The node "Extending pcase" is indeed about extensions, which is why I > didn't include its line count in the number above. > > The node "Backquote Patterns" is actually part of the pcase > description in the "pcase Macro" node, and was moved to a separate > node for methodological and didactic reasons; it holds more than 100 > lines. > > The node "Destructuring with pcase Patterns" describes an important > part of pcase functionality. At least the first 45 lines of it are > about pcase, even if you consider pcase-let etc. as "extensions". That just reaffirms my understanding that the main problem with 'pcase' that we have is documentation. The nodes are written very bottom-up, whereas what's really needed for someone to understand the core usage, would look more like the first half of the node "Destructuring with ‘pcase’ Patterns". > So, even if you want to exclude "extensions and additional features", > the description takes 145+100+45=290 lines, or 400+100+45=545 if you > agree that all of the first node is documentation, not "extensions". > That's quite a lot, and we have all that for a reason: you may > remember the disputes and several significant edits that this section > went through, because the original, much shorter text was deemed > insufficient. Looks like it's still insufficient. Jim Porter's suggestions for improving the docs are in a separate thread ("Improving 'pcase' documentation"), it really deserves more attention. >>> All I'm trying to say is that >>> there_are_ inherent problems in the DSL whose knowledge is required >>> to understand code written using pcase, and that you and others should >>> recognize these inherent problems are real, even though you have >>> overcome them, and anyone could overcome them given enough time and >>> experience. >> >> Most of us can agree that these DLS have associated costs. > > Then we agree. I just attempted to broaden this agreement. > >> Whether they are "problems" (to be fixed?), meaning the costs outweigh >> the benefits, seems to be the main theme of this thread. > > You read too much into the words. "Problems" are not necessarily > something that must be fixed, and "costs" is not necessarily something > that need not be fixed. Those are basically synonyms in this > discussion. Hopefully this clarification can bring most of the argument to a close. ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-12-01 18:28 ` Dmitry Gutov @ 2023-12-01 18:40 ` Eli Zaretskii 2023-12-01 18:45 ` João Távora 1 sibling, 0 replies; 342+ messages in thread From: Eli Zaretskii @ 2023-12-01 18:40 UTC (permalink / raw) To: Dmitry Gutov; +Cc: joaotavora, owinebar, rms, philipk, emacs-devel > Date: Fri, 1 Dec 2023 20:28:43 +0200 > Cc: joaotavora@gmail.com, owinebar@gmail.com, rms@gnu.org, > philipk@posteo.net, emacs-devel@gnu.org > From: Dmitry Gutov <dmitry@gutov.dev> > > That just reaffirms my understanding that the main problem with 'pcase' > that we have is documentation. The nodes are written very bottom-up, > whereas what's really needed for someone to understand the core usage, > would look more like the first half of the node "Destructuring with > ‘pcase’ Patterns". Suggestions to improve the documentation are always welcome. However, what we have now is the result of efforts by several people, so I'd hesitate to conclude that the documentation is the main problem. > Jim Porter's suggestions for improving the docs are in a separate thread > ("Improving 'pcase' documentation"), it really deserves more attention. It already did get attention. It will get much more when Jim posts patches to the manual and the doc string. ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-12-01 18:28 ` Dmitry Gutov 2023-12-01 18:40 ` Eli Zaretskii @ 2023-12-01 18:45 ` João Távora 2024-01-09 5:36 ` Stefan Kangas 1 sibling, 1 reply; 342+ messages in thread From: João Távora @ 2023-12-01 18:45 UTC (permalink / raw) To: Dmitry Gutov; +Cc: Eli Zaretskii, owinebar, rms, philipk, emacs-devel On Fri, Dec 1, 2023 at 6:28 PM Dmitry Gutov <dmitry@gutov.dev> wrote: > That just reaffirms my understanding that the main problem with 'pcase' > that we have is documentation. The nodes are written very bottom-up, > whereas what's really needed for someone to understand the core usage, > would look more like the first half of the node "Destructuring with > ‘pcase’ Patterns". +1 Instead of "11.4 Pattern-Matching Conditional", that section could be called "Pcase and friends" or "The pcase family of macros family". Though it is original use of pcase, pcase conditionals are just one of the things you can do with it, and in my recent experience, not necessarily the most common or useful one. Also 'pcase-let' is probably easier to understand than 'pcase', as it only does destructuring and binding whereas the other macros do that and something more on top. Besides renaming, that section could start with a 11.4.1 "quick-start" with some brief explanation about how pcase relates to backquote-and-tick and with an example for 'pcase-let', not unlike the one that surfaced here. If space allows, an example for 'pcase' that introduces the conditional macro can be added. João ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-12-01 18:45 ` João Távora @ 2024-01-09 5:36 ` Stefan Kangas 0 siblings, 0 replies; 342+ messages in thread From: Stefan Kangas @ 2024-01-09 5:36 UTC (permalink / raw) To: João Távora, Dmitry Gutov Cc: Eli Zaretskii, owinebar, rms, philipk, emacs-devel João Távora <joaotavora@gmail.com> writes: > On Fri, Dec 1, 2023 at 6:28 PM Dmitry Gutov <dmitry@gutov.dev> wrote: > >> That just reaffirms my understanding that the main problem with 'pcase' >> that we have is documentation. The nodes are written very bottom-up, >> whereas what's really needed for someone to understand the core usage, >> would look more like the first half of the node "Destructuring with >> ‘pcase’ Patterns". > > +1 > > Instead of "11.4 Pattern-Matching Conditional", that section could > be called "Pcase and friends" or "The pcase family of macros family". > > Though it is original use of pcase, pcase conditionals are just one > of the things you can do with it, and in my recent experience, not > necessarily the most common or useful one. Also 'pcase-let' is > probably easier to understand than 'pcase', as it only does > destructuring and binding whereas the other macros do that and something > more on top. > > Besides renaming, that section could start with a 11.4.1 "quick-start" > with some brief explanation about how pcase relates to backquote-and-tick > and with an example for 'pcase-let', not unlike the one that surfaced here. > > If space allows, an example for 'pcase' that introduces the conditional > macro can be added. Please reformat this also as documentation patches and send to the bug tracker. ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-12-01 11:52 ` Eli Zaretskii 2023-12-01 12:48 ` Dmitry Gutov @ 2023-12-01 13:28 ` João Távora 2023-12-01 16:25 ` Andreas Schwab 2 siblings, 0 replies; 342+ messages in thread From: João Távora @ 2023-12-01 13:28 UTC (permalink / raw) To: Eli Zaretskii; +Cc: owinebar, rms, dmitry, philipk, emacs-devel On Fri, Dec 1, 2023 at 11:52 AM Eli Zaretskii <eliz@gnu.org> wrote: > > So, in these emails, I'm trying to explain to you how to change your > > view of these pcase constructs in a constructive way > > This is a misunderstanding: I'm not expressing _my_ views. I'm > expressing the views of someone who bumps into this code the first or > the second time, and/or didn't yet have the advantage of someone > giving them "a piece of insight" that caused you to change your mind. > IOW, I'm expressing _your_ views before you changed your mind. Fair enough. Though, given your statements about the "redundancy" of '.' and its different "magic" role in 'pcase' vs "elsewhere in Lisp" one can be easily led to believe the contrary, because both those statements are demonstrably false (at least in the only interpretation of them I could find). > In Emacs development and maintenance, being able to look at stuff from > the POV of an innocent user or Lisp programmer is sometimes required > to realize the true impact of some constructs and features. We cannot > regard that only from the height of our own knowledge and experience, > which usually far surpass those of many Emacs users and programmers. Again, this is perfectly fair. Elisp, like many other languages, has constructs for different levels of proficiency. You wouldn't refrain from using C functions or C typedefs just because it requires more knowledge about the how the C language than a simple untyped program where everything is inlined in main() and every piece of data is in an array. > If this is that easy, then why do we need no less than 120 lines to > describe pcase in the doc string, and no less than 600 lines to > document its features in the ELisp manual? _I_ didn't write that docstring. Maybe the docstring and the manual should start by making the easy and common use cases prominent and visible, just like I tried to do in that 10 line paragraph. As you know, writing good docstrings and manuals is a challenge in itself. But that shouldn't be an argument against the validity of the tool being described. > understand that. None of that is true. All I'm trying to say is that > there _are_ inherent problems in the DSL whose knowledge is required > to understand code written using pcase, and that you and others should > recognize these inherent problems are real The only _inherent_ difficulty I recognize in pcase DSL's is the _inherit_ difficulty in understand the backtick-and-quote in so-called "normal Lisp". > , even though you have > overcome them, and anyone could overcome them given enough time and > experience. My point is that "time and experience" isn't necessary to understand the most common uses of pcase's DSL. That one piece of insight paired a knowledge about how backtick-and-quote works "in normal Lisp" for list construction will suffice to fully master pcase's list destructuring abilities. ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-12-01 11:52 ` Eli Zaretskii 2023-12-01 12:48 ` Dmitry Gutov 2023-12-01 13:28 ` João Távora @ 2023-12-01 16:25 ` Andreas Schwab 2 siblings, 0 replies; 342+ messages in thread From: Andreas Schwab @ 2023-12-01 16:25 UTC (permalink / raw) To: Eli Zaretskii Cc: João Távora, owinebar, rms, dmitry, philipk, emacs-devel On Dez 01 2023, Eli Zaretskii wrote: > attacking its syntax, or don't understand it. Andreas Schwab has even > gone as far as lecture me on the basics of the Lisp reader and the > syntax of Emacs Lisp, apparently under the assumption that I don't > understand that. None of that is true. Then why have you taken it up when it has nothing at all to do with pcase? That looked very much like you desperately tried to find a case against pcase and failed. -- Andreas Schwab, schwab@linux-m68k.org GPG Key fingerprint = 7578 EB47 D4E5 4D69 2510 2552 DF73 E780 A9DA AEC1 "And now for something completely different." ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-12-01 10:02 ` João Távora 2023-12-01 11:52 ` Eli Zaretskii @ 2024-01-09 5:33 ` Stefan Kangas 2024-01-09 10:43 ` João Távora 1 sibling, 1 reply; 342+ messages in thread From: Stefan Kangas @ 2024-01-09 5:33 UTC (permalink / raw) To: João Távora, Eli Zaretskii Cc: owinebar, rms, dmitry, philipk, emacs-devel João Távora <joaotavora@gmail.com> writes: > It is _easy_ to explain that "scary" construct _if_ you learn to _lean_ > on what should be probably existing knowledge. No doc-consulting > necessary. > > You take a backtick-starting construct with as many scary periods > things as you can find and then, say > > `(,foo . (,bar . ,baz)) > > And then ask yourself: "what kind of list does this build if I just > let-bind foo, bar and baz to 42?". And then you answer yourself > "Why, it's the improper list (42 42 . 42) made up of just two cons > cells and 3 fixnums!". So _that's_ the kind of list that can be > destructured with the pcase expression. > > This solves the reading problem. Now the writing problem. To author > new pcase patterns one uses more or less the same process. One again > leans on one's existing knowledge of how the list structure would be > expressed with backtick-and-quote. So once you know the list > structure in your mind you write it as a backtick-and-quote expression, > just as if you were going to craft that list (though you aren't of > course). Then once you're happy with your expression, you may take it > and you put it in one of the BINDINGS left-hand part of a 'let'. > Then you rename that 'let' to 'pcase-let' and away you go! Could you reformat this as a documentation patch? ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2024-01-09 5:33 ` Stefan Kangas @ 2024-01-09 10:43 ` João Távora 0 siblings, 0 replies; 342+ messages in thread From: João Távora @ 2024-01-09 10:43 UTC (permalink / raw) To: Stefan Kangas; +Cc: Eli Zaretskii, owinebar, rms, dmitry, philipk, emacs-devel On Tue, Jan 9, 2024 at 5:33 AM Stefan Kangas <stefankangas@gmail.com> wrote: > > You take a backtick-starting construct with as many scary periods > > things as you can find and then, say > > > > `(,foo . (,bar . ,baz)) > > > > And then ask yourself: "what kind of list does this build if I just > > let-bind foo, bar and baz to 42?". And then you answer yourself > > "Why, it's the improper list (42 42 . 42) made up of just two cons > > cells and 3 fixnums!". So _that's_ the kind of list that can be > > destructured with the pcase expression. > > > > This solves the reading problem. Now the writing problem. To author > > new pcase patterns one uses more or less the same process. One again > > leans on one's existing knowledge of how the list structure would be > > expressed with backtick-and-quote. So once you know the list > > structure in your mind you write it as a backtick-and-quote expression, > > just as if you were going to craft that list (though you aren't of > > course). Then once you're happy with your expression, you may take it > > and you put it in one of the BINDINGS left-hand part of a 'let'. > > Then you rename that 'let' to 'pcase-let' and away you go! > > Could you reformat this as a documentation patch? TL;DR: Maybe I will do that "if noone beats me to it" (TM). All the ideas I had to share are already there and free to use. If you find these ideas useful or their exposition elegant, I'm flattered :-) but there's still the work of finding the correct spot in the pcase documentation where they would fit better and identifying what other parts of that doc they now supersede, so that a cohesive whole can be achieved. This is usually the most difficult part of adding to existing documentation (very similar to maintaining code, actually). Then there are more minor stylistic and formatting issues, but these are still some effort. I don't have the resources to do this work right now, and properly coordinate with other people updating other parts of that documentation. João ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-12-01 6:31 ` Eli Zaretskii ` (2 preceding siblings ...) 2023-12-01 10:02 ` João Távora @ 2023-12-01 16:04 ` Michael Heerdegen via Emacs development discussions. 2023-12-01 16:33 ` Eli Zaretskii 3 siblings, 1 reply; 342+ messages in thread From: Michael Heerdegen via Emacs development discussions. @ 2023-12-01 16:04 UTC (permalink / raw) To: emacs-devel Eli Zaretskii <eliz@gnu.org> writes: > Incidentally, the actual code from which this were taken is > > (`(,hookfun . (,start ,end ,collection . ,plist)) > > Which has _two_ periods, not one, which are AFAIU redundant, as far as > the Lisp reader is concerned. #+begin_src emacs-lisp (let ((hookfun #'my-hookfun) (start 1) (end 99) (collection (list "foo" "bar")) (plist `((prop . val)))) (pcase `(,hookfun . (,start ,end ,collection . ,plist)) (`(,hookfun . (,start ,end ,collection . ,plist)) (list hookfun start end collection plist)))) ;; ==> (my-hookfun 1 99 ("foo" "bar") ((prop . val))) #+end_src The `pcase' pattern is _literally_ identical to a `backquote' call used to create the same value. Whatever problem you have with `pcase' also exists for backquote. Michael. ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-12-01 16:04 ` Michael Heerdegen via Emacs development discussions. @ 2023-12-01 16:33 ` Eli Zaretskii 0 siblings, 0 replies; 342+ messages in thread From: Eli Zaretskii @ 2023-12-01 16:33 UTC (permalink / raw) To: Michael Heerdegen; +Cc: emacs-devel > Date: Fri, 01 Dec 2023 17:04:09 +0100 > From: Michael Heerdegen via "Emacs development discussions." <emacs-devel@gnu.org> > > (let ((hookfun #'my-hookfun) > (start 1) (end 99) > (collection (list "foo" "bar")) > (plist `((prop . val)))) > > (pcase `(,hookfun . (,start ,end ,collection . ,plist)) > (`(,hookfun . (,start ,end ,collection . ,plist)) > (list hookfun start end collection plist)))) > ;; ==> (my-hookfun 1 99 ("foo" "bar") ((prop . val))) > #+end_src > > The `pcase' pattern is _literally_ identical to a `backquote' call used > to create the same value. Whatever problem you have with `pcase' also > exists for backquote. I don't have any problems with pcase. ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-11-30 19:14 ` Lynn Winebarger 2023-11-30 19:26 ` Eli Zaretskii @ 2023-12-02 3:20 ` Richard Stallman 2023-12-02 8:41 ` Andreas Schwab ` (3 more replies) 1 sibling, 4 replies; 342+ messages in thread From: Richard Stallman @ 2023-12-02 3:20 UTC (permalink / raw) To: Lynn Winebarger; +Cc: dmitry, philipk, 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. ]]] > > But a person who is just starting to look at this code, and reads that > > function first, is likely to be impeded in starting to reach that sort > > of understanding. > > > I have to respectfully disagree - dotted pair notation is a pretty > fundamental part of LISP syntax, regardless of dialect. That is true, but it is not pertinent to my finding that pcase code confusing. I know what dotted pairs mean, but I was not sure what they meant in pcase patterns. Likewise for Eli. It is unkind and unhelpful to lecture him about what dotted paris are. -- Dr Richard Stallman (https://stallman.org) Chief GNUisance of the GNU Project (https://gnu.org) Founder, Free Software Foundation (https://fsf.org) Internet Hall-of-Famer (https://internethalloffame.org) ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-12-02 3:20 ` Richard Stallman @ 2023-12-02 8:41 ` Andreas Schwab 2023-12-02 9:02 ` Philip Kaludercic 2023-12-05 2:58 ` Richard Stallman 2023-12-02 14:33 ` Michael Heerdegen via Emacs development discussions. ` (2 subsequent siblings) 3 siblings, 2 replies; 342+ messages in thread From: Andreas Schwab @ 2023-12-02 8:41 UTC (permalink / raw) To: Richard Stallman; +Cc: Lynn Winebarger, dmitry, philipk, emacs-devel On Dez 01 2023, Richard Stallman wrote: > confusing. I know what dotted pairs mean, but I was not sure what > they meant in pcase patterns. They don't mean anything. It's pure lisp syntax. -- Andreas Schwab, schwab@linux-m68k.org GPG Key fingerprint = 7578 EB47 D4E5 4D69 2510 2552 DF73 E780 A9DA AEC1 "And now for something completely different." ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-12-02 8:41 ` Andreas Schwab @ 2023-12-02 9:02 ` Philip Kaludercic 2023-12-02 10:14 ` Emanuel Berg 2023-12-05 2:58 ` Richard Stallman 1 sibling, 1 reply; 342+ messages in thread From: Philip Kaludercic @ 2023-12-02 9:02 UTC (permalink / raw) To: Andreas Schwab; +Cc: Richard Stallman, Lynn Winebarger, dmitry, emacs-devel Andreas Schwab <schwab@linux-m68k.org> writes: > On Dez 01 2023, Richard Stallman wrote: > >> confusing. I know what dotted pairs mean, but I was not sure what >> they meant in pcase patterns. > > They don't mean anything. It's pure lisp syntax. Right, the doc-string mentions this as well: --8<---------------cut here---------------start------------->8--- -- `QPAT Backquote-style pcase patterns: `QPAT QPAT can take the following forms: (QPAT1 . QPAT2) matches if QPAT1 matches the car and QPAT2 the cdr. [...] --8<---------------cut here---------------end--------------->8--- Just like cons-cells are the "real" constituents of a list, so pattern-matching on a list "really" means pattern matching on cons-cells. I believe this is the kind of behaviour that would arise naturally, whenever someone tries to re-implement this themselves. As has been said many times already in this thread: All of this seems to point in the direction that the main issue people are having is that of documentation, and part of the problem might be that pcase is generating its doc-string dynamically, which -- while cool -- might not present the information in the most understandable way. Another question I meant to raise, and forgive me if I missed it somewhere in the remaining discussions, is those who find themselves confused by `pcase': Do you have experience with programming languages that heavily rely on pattern matching and/or unification (ML, Haskell, Prolog, ...)? Myself having experience with this kind of programming, all I had to do to understand `pcase' was to translate the existing abstract notion I had to the syntax that `pcase' provides. While I can imagine that one is more prone to be confused, if trying to learn both the syntax and the point of `pcase', assuming that this kind of articulating oneself is not natural. ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-12-02 9:02 ` Philip Kaludercic @ 2023-12-02 10:14 ` Emanuel Berg 2023-12-02 17:02 ` Barry Fishman 0 siblings, 1 reply; 342+ messages in thread From: Emanuel Berg @ 2023-12-02 10:14 UTC (permalink / raw) To: emacs-devel Philip Kaludercic wrote: > As has been said many times already in this thread: All of > this seems to point in the direction that the main issue > people are having is that of documentation, and part of the > problem might be that pcase is generating its doc-string > dynamically, which -- while cool -- might not present the > information in the most understandable way. Haha, agreed :) > Another question I meant to raise, and forgive me if > I missed it somewhere in the remaining discussions, is those > who find themselves confused by `pcase': Do you have > experience with programming languages that heavily rely on > pattern matching and/or unification (ML, Haskell, Prolog, > ...)? I have experience from all three of those, I think fiddling with pattern matching in those can be quite neurotic to the point I like Elisp better, but sometimes it, and `pcase', is really useful. I thought pattern matching with in particular Haskell was neurotic because one would spend more time on it than one felt was called for, but I think Haskell invited to that kind of fiddling, I always thought of Elisp including `pcase' to be much more calm and relaxed? I don't know if there is something with pattern matching that makes it take over the language, this I felt in languages like Haskell a lot, in Erlang to some noticable extent, in SML I didn't think of it as a problem at all. In Elisp, I also don't think of it as a problem at all. Maybe if one would have pattern matching in the function line definition like we see in Haskell and Erlang, I think that would be too much, but still maybe it is just me who does things in a way that works for me, and everyone else is just shooting the Emacs source so full of pattern matching this has become a problem for the maintainers. -- underground experts united https://dataswamp.org/~incal ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-12-02 10:14 ` Emanuel Berg @ 2023-12-02 17:02 ` Barry Fishman 2023-12-02 20:25 ` Michael Heerdegen via Emacs development discussions. 2023-12-03 4:30 ` Emanuel Berg 0 siblings, 2 replies; 342+ messages in thread From: Barry Fishman @ 2023-12-02 17:02 UTC (permalink / raw) To: emacs-devel On 2023-12-02 11:14:19 +01, Emanuel Berg wrote: > I thought pattern matching with in particular Haskell was > neurotic because one would spend more time on it than one felt > was called for, but I think Haskell invited to that kind of > fiddling, I always thought of Elisp including `pcase' to be > much more calm and relaxed? Your sense of calm and relaxation about `pcase' does not seem to be shared by a lot of people, who think of it as overly complex and ugly. To me Haskell starts with just Scheme changed to fix every criticism that has been make about Lisp whether it was valid or not. But they end up with something very different. The Haskell pattern matching construct, unlike `pcase' is broken into three independent steps. First the declaration of types for each of the variables to be extracted, although this is sometimes done automatically by the (static) type system. Then, the list of accepted patterns, given in the form of constructors using the variables to build the patterns being matched. Then possibly a list of tests to be tried on the values of the matching variables. And finally for the first valid "pattern" and "guard" test, the code is execute using the extracted variables. My example `proto-case' more resembled this, although I did not allow for multiple guard clauses for each constructor match. It did not use back-quoting, but instead required used a prototype constructions add those needed for each atomic type, or type class (in the sense of CLOS). This is less powerful than `pcase', but didn't require a subset of back-quoting merged with modified type specifier syntax in one new `pcase' specific language. But comparing what goes on in Haskell `case' vs. any pattern matching in a Lisp like language is hard, primarily because Haskell evaluation rules are so different from those of other languages. Haskell is a curried, non-strict, statically typed, syntactically complex language, so can reorder code in ways that are very different than Elisp. So simple Haskell code can becomes very complex in Lisp, and simple Lisp code can be very complex in Haskell. But my issue with `pcase' is more related to that people will tend to use it by copying and pasting its example cases (which they don't fully understand), in places where a simpler syntax would be used. This is partly because Elisp does not have the simpler Common Lisp `typecase' (it does have the discouraged `cl-typecase') and a more flexible 'case' and Scheme like `cond' constructs that are easier to understand and use, and work in most situations. Yes, you can come up with `pcase' situations that are shorter or more powerful, but its seems that the `pcase' proponents don't seem to be able to provide obvious examples which show that power. Without those examples people will tend to cut and paste code in places where simpler more readable code could be use. Their use of pointing to existing Elisp code using `pcase' involves understanding the context of the code. This makes giving the any alternative examples harder to do, because it require understanding and possibly restructuring more complex situations. Its should be the burden on the proponents of a new feature to provide useful examples of their construct in a simple explainable context, and not the alternative. I see the Haskell pattern matching given very little time in introductory Haskell books, because its well formulated and easy to understand in the context of the language. Of course understanding Haskell, especially after being exposed to most other languages, requires a mental reset that is not easy. It took me about four re-reads to gain any understanding what was going on, but I was burdened with having used a lot of other languages. It was the first time I couldn't just recast things in terms of how I would do them better in Lisp. But using a constructor based rather than a backquote-splice/type-specifier approach seems (to me) simpler to understand. Or at least give an example of code (in a simple context) to show `pcase' in something that shows its full power. -- Barry Fishman ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-12-02 17:02 ` Barry Fishman @ 2023-12-02 20:25 ` Michael Heerdegen via Emacs development discussions. 2023-12-03 4:30 ` Emanuel Berg 1 sibling, 0 replies; 342+ messages in thread From: Michael Heerdegen via Emacs development discussions. @ 2023-12-02 20:25 UTC (permalink / raw) To: emacs-devel Barry Fishman <barry@ecubist.org> writes: > Or at least give an example of code (in a simple context) to show > `pcase' in something that shows its full power. I suggest to have a look at the examples I had posted as a response to a similar request by Richard. Michael. ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-12-02 17:02 ` Barry Fishman 2023-12-02 20:25 ` Michael Heerdegen via Emacs development discussions. @ 2023-12-03 4:30 ` Emanuel Berg 1 sibling, 0 replies; 342+ messages in thread From: Emanuel Berg @ 2023-12-03 4:30 UTC (permalink / raw) To: emacs-devel Barry Fishman wrote: >> I thought pattern matching with in particular Haskell was >> neurotic because one would spend more time on it than one >> felt was called for, but I think Haskell invited to that >> kind of fiddling, I always thought of Elisp including >> `pcase' to be much more calm and relaxed? > > Your sense of calm and relaxation about `pcase' does not > seem to be shared by a lot of people, who think of it as > overly complex and ugly. Perception is reality, even when that perception is irrational. But in this case, I don't think anyone disapproved of some of the maintainers saying they perceived `cl-lib' and `pcase' to be sources of increased complexity, or that that perception was irrational in any way. If it came across that way, I don't think it was intentional from anyone. It was just how the whole thing was perceived by other people, they perceived it is a categorical stance, cl-lib and pcase are the root of evil, and we don't feel the need to nuance or discuss that with anyone because we are the maintainers. So if those people perceived it in that way, be it correct or incorrect, that was reality for them as well. So this is were it got ugly to some extent alltho it was held at a reasonable level for the most part. It is good that people are working on cond* now and it'll be interesting to use it if and when it gets added. Probably increased complexity in terms of the so-called "DSLs" introduced - but also increased expressiveness and power - from cl-lib and pcase will remain, but if we add cond* and improve documentation for cl-lib and pcase that can reduce the negativity how the whole thing is perceived by some people, and hopefully the kind of frustration that was felt can be chanelled into something creative and ultimately beneficial for our software. -- underground experts united https://dataswamp.org/~incal ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-12-02 8:41 ` Andreas Schwab 2023-12-02 9:02 ` Philip Kaludercic @ 2023-12-05 2:58 ` Richard Stallman 2023-12-05 3:36 ` chad 1 sibling, 1 reply; 342+ messages in thread From: Richard Stallman @ 2023-12-05 2:58 UTC (permalink / raw) To: Andreas Schwab; +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. ]]] > > confusing. I know what dotted pairs mean, but I was not sure what > > they meant in pcase patterns. > They don't mean anything. It's pure lisp syntax. I explained why I found it hard to understand that example. Your response to my explanation is to argue with it. To argue with someone's explanation of why something was confusing does not change teh fact that it was confusing. You can either pay attention to the cause, and perhaps reach a useful conclusion, or ignore the cause. But ignoring it will not make the confusion not happen. -- Dr Richard Stallman (https://stallman.org) Chief GNUisance of the GNU Project (https://gnu.org) Founder, Free Software Foundation (https://fsf.org) Internet Hall-of-Famer (https://internethalloffame.org) ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-12-05 2:58 ` Richard Stallman @ 2023-12-05 3:36 ` chad 2023-12-08 3:53 ` Richard Stallman 0 siblings, 1 reply; 342+ messages in thread From: chad @ 2023-12-05 3:36 UTC (permalink / raw) To: rms; +Cc: Andreas Schwab, emacs-devel [-- Attachment #1: Type: text/plain, Size: 1798 bytes --] On Mon, Dec 4, 2023 at 9:59 PM Richard Stallman <rms@gnu.org> wrote: > > > confusing. I know what dotted pairs mean, but I was not sure what > > > they meant in pcase patterns. > > > They don't mean anything. It's pure lisp syntax. > > I explained why I found it hard to understand that example. > > Your response to my explanation is to argue with it. [...] > I understand your point, and I don't disagree, but I do see another viewpoint that also makes sense to me: that the misunderstanding is not in the place that is being discussed. (In other words, that this is largely an issue of mis-communication.) The particular point that *I think* was being expressed but not effectively communicated is this: The example was cited as a place where pcase's use of special syntax lead to confusion, but this the example doesn't use any special pcase syntax. This doesn't remove the problem, but if it's correct, then it suggests that the problem is perhaps more accurately described as "pcase makes some experienced Lisp programmers so unsure about special syntax that they worry it might be present where it is not". This could be a general problem with any programming language, but is perhaps especially relevant to Lisp. Coming back to the particular potential disagreement: > I explained why I found it hard to understand that example. > > Your response to my explanation is to argue with it. I *suspect* that the "argument* you see is not an attempt to tell you that your explanation is wrong, but rather to suggest that the misunderstanding might not be where you thought it was. (You are certainly correct that the example was hard for you to understand, but you may or may not be correct about the reasons.) I hope that helps, ~Chad [-- Attachment #2: Type: text/html, Size: 2351 bytes --] ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-12-05 3:36 ` chad @ 2023-12-08 3:53 ` Richard Stallman 0 siblings, 0 replies; 342+ messages in thread From: Richard Stallman @ 2023-12-08 3:53 UTC (permalink / raw) To: chad; +Cc: schwab, 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. ]]] > The example was cited as a place where pcase's use of special syntax lead > to confusion, but this the example doesn't use any special pcase syntax. > This doesn't remove the problem, but if it's correct, then it suggests that > the problem is perhaps more accurately described as "pcase makes some > experienced Lisp programmers so unsure about special syntax that they worry > it might be present where it is not". I think you are right. That is a clearer analysis of what happened to me, and perhaps to Eli as well. I don't think it affects the overall conclusions about pcase and its syntax. To some experienced Emacs Lisp hackers, they are confusing, and that increases the effective complexity that they add to the Emacs Lisp language. -- Dr Richard Stallman (https://stallman.org) Chief GNUisance of the GNU Project (https://gnu.org) Founder, Free Software Foundation (https://fsf.org) Internet Hall-of-Famer (https://internethalloffame.org) ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-12-02 3:20 ` Richard Stallman 2023-12-02 8:41 ` Andreas Schwab @ 2023-12-02 14:33 ` Michael Heerdegen via Emacs development discussions. 2023-12-04 3:11 ` Richard Stallman 2023-12-02 18:01 ` Lynn Winebarger 2023-12-03 3:27 ` Richard Stallman 3 siblings, 1 reply; 342+ messages in thread From: Michael Heerdegen via Emacs development discussions. @ 2023-12-02 14:33 UTC (permalink / raw) To: emacs-devel Richard Stallman <rms@gnu.org> writes: > Likewise for Eli. It is unkind and unhelpful to lecture him about > what dotted paris are. I hope I didn't. I did not understand that some, and which, of his questions were rhetorical. Or if the questions were his own questions. That had not been really clear. Might have been the case for others. Michael. ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-12-02 14:33 ` Michael Heerdegen via Emacs development discussions. @ 2023-12-04 3:11 ` Richard Stallman 0 siblings, 0 replies; 342+ messages in thread From: Richard Stallman @ 2023-12-04 3:11 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. ]]] > I hope I didn't. I did not understand that some, and which, of his > questions were rhetorical. Or if the questions were his own questions. > That had not been really clear. Might have been the case for others. I see that you're sincere about treating other people with respect, and I respect that. None of us is perfect. -- Dr Richard Stallman (https://stallman.org) Chief GNUisance of the GNU Project (https://gnu.org) Founder, Free Software Foundation (https://fsf.org) Internet Hall-of-Famer (https://internethalloffame.org) ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-12-02 3:20 ` Richard Stallman 2023-12-02 8:41 ` Andreas Schwab 2023-12-02 14:33 ` Michael Heerdegen via Emacs development discussions. @ 2023-12-02 18:01 ` Lynn Winebarger 2023-12-04 3:11 ` Richard Stallman 2023-12-03 3:27 ` Richard Stallman 3 siblings, 1 reply; 342+ messages in thread From: Lynn Winebarger @ 2023-12-02 18:01 UTC (permalink / raw) To: Richard Stallman; +Cc: Dmitry Gutov, Philip Kaludercic, emacs-devel [-- Attachment #1: Type: text/plain, Size: 2199 bytes --] On Fri, Dec 1, 2023, 10:20 PM Richard Stallman <rms@gnu.org> wrote: > > > But a person who is just starting to look at this code, and reads > that > > > function first, is likely to be impeded in starting to reach that > sort > > > of understanding. > > > > > > I have to respectfully disagree - dotted pair notation is a pretty > > fundamental part of LISP syntax, regardless of dialect. > > That is true, but it is not pertinent to my finding that pcase code > confusing. I know what dotted pairs mean, but I was not sure what > they meant in pcase patterns. > > Likewise for Eli. It is unkind and unhelpful to lecture him about > what dotted paris are. > I don't believe stating a disagreement is lecturing. My understanding is that we (or at least Eli and my response to him) are discussing concern for a hypothetical Elisp programmer, as Eli has (if I understood correctly) no problem understanding pcase. Maybe it would be more useful to say that LISP has at least 3 kinds of syntax - read syntax, special forms, and macros (forms defined by a function written in LISP itself). The difference between special forms and macros can largely be ignored, which is one of the special characteristics of LISP. The difference between read syntax and the latter two is more substantial. I think it's reasonable to expect a LISP programmer to recognize distinct text expressions for which the lisp "read" primitive produces identical S-exressions. Those differences cannot have anything to do with the LISP forms processed by the expander/evaluator. That being said, it wouldn't hurt to have a table exhaustively list all read syntax recognized by the reader in one place, for reference. It can be difficult to determine what a particular bit of LISP source code means when it contains infrequently used characters, since LISP is very permissive in the use of characters in symbols in general. I just don't think this dotted pair concern is a credible criticism of pcase. Maybe of a particular style preferences or idioms of different programmers, but it is orthogonal to pcase. Why would it only be confusing when used in a pcase form? pcase is not read-level syntax. Lynn [-- Attachment #2: Type: text/html, Size: 3047 bytes --] ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-12-02 18:01 ` Lynn Winebarger @ 2023-12-04 3:11 ` Richard Stallman 2023-12-04 12:27 ` Lynn Winebarger 0 siblings, 1 reply; 342+ messages in thread From: Richard Stallman @ 2023-12-04 3:11 UTC (permalink / raw) To: Lynn Winebarger; +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. ]]] > > Likewise for Eli. It is unkind and unhelpful to lecture him about > > what dotted paris are. > I don't believe stating a disagreement is lecturing. I was talking about the words you said to Eli to explain dotted pairs to him. I don't that they stated a disagreement, but they sure sounded like lecturing. -- Dr Richard Stallman (https://stallman.org) Chief GNUisance of the GNU Project (https://gnu.org) Founder, Free Software Foundation (https://fsf.org) Internet Hall-of-Famer (https://internethalloffame.org) ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-12-04 3:11 ` Richard Stallman @ 2023-12-04 12:27 ` Lynn Winebarger 0 siblings, 0 replies; 342+ messages in thread From: Lynn Winebarger @ 2023-12-04 12:27 UTC (permalink / raw) To: Richard Stallman; +Cc: emacs-devel [-- Attachment #1: Type: text/plain, Size: 842 bytes --] On Sun, Dec 3, 2023, 10:11 PM Richard Stallman <rms@gnu.org> wrote: > > > Likewise for Eli. It is unkind and unhelpful to lecture him about > > > what dotted paris are. > > > I don't believe stating a disagreement is lecturing. > > I was talking about the words you said to Eli to explain dotted pairs > to him. I don't that they stated a disagreement, but they sure > sounded like lecturing. > It's difficult for me to assess your statement with most of my text removed. I do tend to the pedantic (or precise), but this is a public forum. I'm not crafting my response specifically for the person I'm responding to. Without knowing the specific passages you find objectionable, I can't tell if you think I'm talking down to Eli when I'm trying to be clear for anyone reading, or if there is some other issue with my prose. Lynn [-- Attachment #2: Type: text/html, Size: 1501 bytes --] ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-12-02 3:20 ` Richard Stallman ` (2 preceding siblings ...) 2023-12-02 18:01 ` Lynn Winebarger @ 2023-12-03 3:27 ` Richard Stallman 3 siblings, 0 replies; 342+ messages in thread From: Richard Stallman @ 2023-12-03 3:27 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. ]]] I foudn it necessary to add a little of the complexity of pcase, but in a more elegant form. Here's what I have now, for patterns to match. **Possible types of patterns for :match and the match-... functions** `CONSTANT A constant means to match any value equal to CONSTANT. VARIABLE, a symbol A symbol means to match any value and set VARIABLE to it. nil nil means to match any value and not store it anywhere. Constrained variable, (TESTFN VARIABLE OTHER-ARGS...) This matches any value VALUE provided (TESTFN VALUE OTHER-ARGS...) evaluates to true. If so, it sets VARIABLE to VALUE. (symbolp sym) Match any symbol, store it in `sym'. (> num-foos 1) Match any thing greater than 1, store it in `num-foos'. When matching to bind variables, this pattern unconditionally binds VARIABLE whether it matches or not. `quote', `constrain' and `or' cannot be used as TESTFN. Constrained variable constructs can be nested. For example, (< (numberp num-foos) 1) Match any number > 1, store it in mum-foos. General constrained variable, (constrain VAR EXPRESSION) This general constrained variable pattern binds VAR to the value being matched against, only for evaluating EXPRESSION. If the result is non-nil, the match succeeds and sets VAR to the value. For instance, (constrain x (and (> x 0) (< x 100))) Multi-alternative, (or SUBPATTERNS...) This tries to match each of the SUBPATTERNS in order until one matches. If the pattern is being used to bind variables, it binds all the variables specified in any of SUBPATTERNS \f -- Dr Richard Stallman (https://stallman.org) Chief GNUisance of the GNU Project (https://gnu.org) Founder, Free Software Foundation (https://fsf.org) Internet Hall-of-Famer (https://internethalloffame.org) ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-11-21 2:42 ` Richard Stallman ` (3 preceding siblings ...) 2023-11-24 17:29 ` Lynn Winebarger @ 2023-11-25 4:15 ` Stefan Monnier 2023-11-27 3:12 ` Richard Stallman 4 siblings, 1 reply; 342+ messages in thread From: Stefan Monnier @ 2023-11-25 4:15 UTC (permalink / raw) To: emacs-devel; +Cc: monnier > > To interpret those backquotes and commas, one can imagine that the they > > do the inverse of the usual. > I uderstand that when you say it, but when I saw the line > > (`(,hookfun . (,start ,end ,collection . ,plist)) > > I was not sure which part of the line that rule applies to. Interesting. I find this one to be very straightforward. The previous line with the `and` and the `pred` is the more problematic one. > In particular, what is the reason for the period and inner > parenthsses? Because (HOOKFUN . VALUE) is what is returned by the `run-hook-wrapped` function and (,START ,END ,COLLECTION . ,PLIST) is the format of the value returned by the hook's functions. IOW, a merely stylistic choice. > Why doesn't the code say this? > > (`(,hookfun ,start ,end ,collection . ,plist) > > Would that be equiva;ent? Interesting. `pcase` is a macro, so it does not see the above characters, it only sees the resulting Sexp returned by the Lisp reader, and as you may remember, the reader returns *exactly* the same Sexp for the above two lines of text. So `pcase` would be hard pressed to make those two *not* equivalent :-) Stefan ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-11-25 4:15 ` Stefan Monnier @ 2023-11-27 3:12 ` Richard Stallman 2023-11-30 18:06 ` Michael Heerdegen 0 siblings, 1 reply; 342+ messages in thread From: Richard Stallman @ 2023-11-27 3:12 UTC (permalink / raw) To: Stefan Monnier; +Cc: emacs-devel, monnier [[[ 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. ]]] > Interesting. `pcase` is a macro, so it does not see the above > characters, it only sees the resulting Sexp returned by the Lisp reader, > and as you may remember, the reader returns *exactly* the same Sexp > for the above two lines of text. You're right, but I didn't see that, because I was thinking of it as part of a pcase construct and assumed it would produce some unknown code to do the matching. I didn't see that pcase and backwuote itself would not notice the difference. For me, pcase shines a cone of mystery. -- Dr Richard Stallman (https://stallman.org) Chief GNUisance of the GNU Project (https://gnu.org) Founder, Free Software Foundation (https://fsf.org) Internet Hall-of-Famer (https://internethalloffame.org) ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-11-27 3:12 ` Richard Stallman @ 2023-11-30 18:06 ` Michael Heerdegen 0 siblings, 0 replies; 342+ messages in thread From: Michael Heerdegen @ 2023-11-30 18:06 UTC (permalink / raw) To: Richard Stallman; +Cc: Stefan Monnier, emacs-devel Richard Stallman <rms@gnu.org> writes: > You're right, but I didn't see that, because I was thinking of it as > part of a pcase construct and assumed it would produce some unknown > code to do the matching. I didn't see that pcase and backwuote itself > would not notice the difference. Note that `pcase' sees the same sexp produced by the reader, but the backquote macro is not expanded. The backquote sexp produced by the reader is recognized and handled by the `pcase' macro. Michael. ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-11-16 18:39 ` T.V Raman 2023-11-16 18:47 ` Philip Kaludercic @ 2023-11-16 18:49 ` Dmitry Gutov 1 sibling, 0 replies; 342+ messages in thread From: Dmitry Gutov @ 2023-11-16 18:49 UTC (permalink / raw) To: T.V Raman; +Cc: philipk, rms, emacs-devel On 16/11/2023 20:39, T.V Raman wrote: > when-let let-alist etc have worked well for me. when-let is not destructuring. let-alias is very limited -- destructuring only for one type. What I meant is there are similar constructs in functional languages like ML/Haskell which have also been available lately in Python/Ruby/Rust, that allow both matching and getting the data out in the same construct, accepting many or all data types available in the language. pcase is an implementation of that idea. Perhaps it looks a bit cryptic, but I'm not sure what better syntax it would have in Lisp, while retaining the same capabilities. > What threw me with pcase is there are lots of special chars in that > particular example whose meaning I dont know, and looking those up and > understanding their use at the same time was what chased me away Perhaps (info "(elisp) pcase Macro") will help? ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-11-16 17:18 ` T.V Raman 2023-11-16 17:44 ` Michael Heerdegen 2023-11-16 18:21 ` Dmitry Gutov @ 2023-11-16 23:41 ` Emanuel Berg 2023-11-17 7:34 ` Eli Zaretskii 2 siblings, 1 reply; 342+ messages in thread From: Emanuel Berg @ 2023-11-16 23:41 UTC (permalink / raw) To: emacs-devel T.V Raman wrote: > RMS' message makes some very valuable points re specialized > languages like pcase -- pcase has its strengths, but in > general, it's definitely not easy to understand complex code > that leverages it -- as an example: > > I recently tried to understand some of the completion code; > -- specifically, completion-at-point, and immediately hit > the pcase wall and gave up --- my lack of understanding of > pcase made that code in Emacs Core read like line-noise. I grepped my own Elisp for pcase and found this. Interestingly, it uses cl-lib as well. So here we have cl-lib and pcase in combination, so should be downright incomprehensible, right? You will see that the use of pcase is very clear. I'm sure you can understand it. From there, more complex use should be very possible for you to understand as well, I'm positive. But really: code that is difficult to understand can be written using non-cl-lib Elisp and non-pcase Elisp as well. Good use of cl-lib and good use of pcase reduces complexity. Complex use of cl-lib and pcase will be complex, sure, but there are no guarantees solving that complexity in any other way will be any less complex. If everyone did that instead of using libraries we would end up with much more code, and code that essentially - but not quite, and that would be a big problem - did the same thing over and over. ;;; -*- lexical-binding: t -*- ;; ;; this file: ;; https://dataswamp.org/~incal/emacs-init/time-cmp.el (require 'cl-lib) (require 'pcase) (defun days (y1 m1 d1 y2 m2 d2) (let*((then (float-time (encode-time 0 0 0 d1 m1 y1))) (now (float-time (encode-time 0 0 0 d2 m2 y2))) (diff (- now then)) ) (string-to-number (format-seconds "%d" diff)) )) ;; (days 1958 04 13 1958 08 30) ; 139 days between Tahiti Nui 2 & 3 (defun days-date (date1 date2) (pcase-let*( (sep "-") (`(,y1 ,m1 ,d1) (cl-map 'list #'string-to-number (split-string date1 sep))) (`(,y2 ,m2 ,d2) (cl-map 'list #'string-to-number (split-string date2 sep))) ) (days y1 m1 d1 y2 m2 d2) )) ;; (days-date "2021-03-19" "2021-04-20") ; 31 ;; (days-date "1964-07-26" "2021-03-22") ; 20 693 -- underground experts united https://dataswamp.org/~incal ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-11-16 23:41 ` Emanuel Berg @ 2023-11-17 7:34 ` Eli Zaretskii 0 siblings, 0 replies; 342+ messages in thread From: Eli Zaretskii @ 2023-11-17 7:34 UTC (permalink / raw) To: Emanuel Berg; +Cc: emacs-devel > From: Emanuel Berg <incal@dataswamp.org> > Date: Fri, 17 Nov 2023 00:41:43 +0100 > > I grepped my own Elisp for pcase and found this. > Interestingly, it uses cl-lib as well. No, pcase.el doesn't use cl-lib. ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-11-16 7:37 ` Philip Kaludercic 2023-11-16 17:18 ` T.V Raman @ 2023-11-26 3:17 ` Richard Stallman 1 sibling, 0 replies; 342+ messages in thread From: Richard Stallman @ 2023-11-26 3:17 UTC (permalink / raw) To: Philip Kaludercic; +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. ]]] > The question is, if > one would restrict pcase to just matching expressions using ` and , like > (pcase sexp ;match various top-level constructs I am not sure what ";match various top-level constructs" means. > (`(defun ,name ,args ,body) ...) > (`(defvar ,name, ,value) ...) > (`(require ',symbol) ...) > ...) That part is conceptually simple. > would that be simple enough in your opinion? -- Dr Richard Stallman (https://stallman.org) Chief GNUisance of the GNU Project (https://gnu.org) Founder, Free Software Foundation (https://fsf.org) Internet Hall-of-Famer (https://internethalloffame.org) ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-11-16 3:04 Instead of pcase Richard Stallman 2023-11-16 7:37 ` Philip Kaludercic @ 2023-11-16 15:06 ` Michael Heerdegen 2023-11-16 17:31 ` T.V Raman 2023-11-20 3:06 ` Richard Stallman 2023-11-16 15:20 ` Spencer Baugh ` (2 subsequent siblings) 4 siblings, 2 replies; 342+ messages in thread From: Michael Heerdegen @ 2023-11-16 15:06 UTC (permalink / raw) To: emacs-devel Richard Stallman <rms@gnu.org> writes: > What makes `pcase' such a complication is that it introduces an > additional "little language" that duplicates the functionality of part > of Emacs Lisp. Even worse, that little language is so concise it is > downright cryptic. It is not cryptic per se. People are sometimes frightened by the syntax, for some it seems to be hard to learn and understand, I don't know why, but I accept that as a fact. > Those of you who are fans of `pcase' may not recognize the cost it > imposes on the Emacs Lisp language. You paid that cost already, > perhaps a few years ago, and perhaps you enjoy each new language > construct you learn. Perhaps, for you, the more complexity of > features to be learned, the better. > > But don't argue that this cost does not exist, simply because it > doesn't feel like a burden to you. Hmm, I must say that cost was small for me. There is also a cost of reading a more complicated rewrite using less suited language constructs. And i have to pay the price each time I need to read the more complicated rewrite, instead of only once. > I'm looking at adapting some of the features of `pcase' into other > constructs, so as to make type-discrimination code more concise than > in old-fashioned Lisp, but _not_ so concise as to be cryptic and > burdensome. I wonder how that would look like and if it would really be simpler. Or if it would be structurally more or less equivalent and only avoid the concise syntax. Because, we need different semantic features, and we want that it's possible for them to be combined. I think we would more or less end either with `pattern-case' that is like pcase but more verbose, or with something that is simpler, but when some requirement in the code changes, like a destructering having to be made conditional, has to be rewritten to use a more complicated construct, or plain Elisp. Michael. ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-11-16 15:06 ` Michael Heerdegen @ 2023-11-16 17:31 ` T.V Raman 2023-11-16 18:26 ` Jim Porter 2023-11-20 3:06 ` Richard Stallman 1 sibling, 1 reply; 342+ messages in thread From: T.V Raman @ 2023-11-16 17:31 UTC (permalink / raw) To: Michael Heerdegen; +Cc: emacs-devel Michael Heerdegen <michael_heerdegen@web.de> writes: See my other response re pcase and its use in emacs core; specifically completion-at-point. A good compromize might be for the pcase fan who wrote that code to explain its use just before the function with some comments; that would actually help someone looking at the code to understand it, and perhaps even turn a pcase sceptic into a pcase fan. > Richard Stallman <rms@gnu.org> writes: > >> What makes `pcase' such a complication is that it introduces an >> additional "little language" that duplicates the functionality of part >> of Emacs Lisp. Even worse, that little language is so concise it is >> downright cryptic. > > It is not cryptic per se. People are sometimes frightened by the > syntax, for some it seems to be hard to learn and understand, I don't > know why, but I accept that as a fact. > >> Those of you who are fans of `pcase' may not recognize the cost it >> imposes on the Emacs Lisp language. You paid that cost already, >> perhaps a few years ago, and perhaps you enjoy each new language >> construct you learn. Perhaps, for you, the more complexity of >> features to be learned, the better. >> >> But don't argue that this cost does not exist, simply because it >> doesn't feel like a burden to you. > > Hmm, I must say that cost was small for me. There is also a cost of > reading a more complicated rewrite using less suited language > constructs. And i have to pay the price each time I need to read the > more complicated rewrite, instead of only once. > >> I'm looking at adapting some of the features of `pcase' into other >> constructs, so as to make type-discrimination code more concise than >> in old-fashioned Lisp, but _not_ so concise as to be cryptic and >> burdensome. > > I wonder how that would look like and if it would really be simpler. Or > if it would be structurally more or less equivalent and only avoid the > concise syntax. > > Because, we need different semantic features, and we want that it's > possible for them to be combined. I think we would more or less end > either with `pattern-case' that is like pcase but more verbose, or with > something that is simpler, but when some requirement in the code > changes, like a destructering having to be made conditional, has to be > rewritten to use a more complicated construct, or plain Elisp. > > > Michael. > > -- ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-11-16 17:31 ` T.V Raman @ 2023-11-16 18:26 ` Jim Porter 2023-11-16 18:40 ` T.V Raman 0 siblings, 1 reply; 342+ messages in thread From: Jim Porter @ 2023-11-16 18:26 UTC (permalink / raw) To: T.V Raman, Michael Heerdegen; +Cc: emacs-devel On 11/16/2023 9:31 AM, T.V Raman wrote: > See my other response re pcase and its use in emacs core; specifically > completion-at-point. A good compromize might be for the pcase fan who > wrote that code to explain its use just before the function with some > comments; that would actually help someone looking at the code to > understand it, and perhaps even turn a pcase sceptic into a pcase fan. Just a thought... would you find a pcase shortdoc with lots of examples to be useful? I find I learn best from examples, and I think some well-annotated pcase examples could help demystify the syntax in an easier-to-digest way compared to the full manual. (The manual has a few examples already, but I think there's room for a lot more examples.) ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-11-16 18:26 ` Jim Porter @ 2023-11-16 18:40 ` T.V Raman 2023-11-16 19:13 ` Jim Porter 0 siblings, 1 reply; 342+ messages in thread From: T.V Raman @ 2023-11-16 18:40 UTC (permalink / raw) To: jporterbugs; +Cc: raman, michael_heerdegen, emacs-devel Yes. especially if a use I was trying to understand had some helpful guidance right next to it; that would also help one learn. Jim Porter writes: > On 11/16/2023 9:31 AM, T.V Raman wrote: > > See my other response re pcase and its use in emacs core; specifically > > completion-at-point. A good compromize might be for the pcase fan who > > wrote that code to explain its use just before the function with some > > comments; that would actually help someone looking at the code to > > understand it, and perhaps even turn a pcase sceptic into a pcase fan. > > Just a thought... would you find a pcase shortdoc with lots of examples > to be useful? I find I learn best from examples, and I think some > well-annotated pcase examples could help demystify the syntax in an > easier-to-digest way compared to the full manual. (The manual has a few > examples already, but I think there's room for a lot more examples.) -- ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-11-16 18:40 ` T.V Raman @ 2023-11-16 19:13 ` Jim Porter 0 siblings, 0 replies; 342+ messages in thread From: Jim Porter @ 2023-11-16 19:13 UTC (permalink / raw) To: T.V Raman; +Cc: michael_heerdegen, emacs-devel On 11/16/2023 10:40 AM, T.V Raman wrote: > Yes. especially if a use I was trying to understand had some helpful > guidance right next to it; that would also help one learn. I'm hoping that putting examples in some separate place (e.g. shortdoc) would be helpful. By my count, there are 1182 calls to pcase in the Emacs tree, so it would be difficult to provide an intro to the syntax before every such use. (To be fair, 433 of those are in Org, but that still leaves us 749 cases in other parts of the tree.) That said, for unusually-tricky uses of pcase, it would probably be nice to sprinkle in a few comments so you don't need to be a pcase master in order to understand what's going on. ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-11-16 15:06 ` Michael Heerdegen 2023-11-16 17:31 ` T.V Raman @ 2023-11-20 3:06 ` Richard Stallman 2023-11-20 14:35 ` Michael Heerdegen 1 sibling, 1 reply; 342+ messages in thread From: Richard Stallman @ 2023-11-20 3:06 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. ]]] > > But don't argue that this cost does not exist, simply because it > > doesn't feel like a burden to you. > Hmm, I must say that cost was small for me. There is also a cost of > reading a more complicated rewrite using less suited language > constructs. It would not be more complicated in substance. It would only be less terse in the way it is written. > I wonder how that would look like and if it would really be simpler. Or > if it would be structurally more or less equivalent and only avoid the > concise syntax. I hope it will be similar but avoid the tersd syntax. I have not finished design it, but I made some progress today. Would you like to help design matching functions to do the same jobs that pcase does? I would like to make it possible to combine various matching and destructuring functions using `and' and `or' (plus any other Lisp functions you like). -- Dr Richard Stallman (https://stallman.org) Chief GNUisance of the GNU Project (https://gnu.org) Founder, Free Software Foundation (https://fsf.org) Internet Hall-of-Famer (https://internethalloffame.org) ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-11-20 3:06 ` Richard Stallman @ 2023-11-20 14:35 ` Michael Heerdegen 2023-11-23 2:57 ` Richard Stallman 0 siblings, 1 reply; 342+ messages in thread From: Michael Heerdegen @ 2023-11-20 14:35 UTC (permalink / raw) To: emacs-devel Richard Stallman <rms@gnu.org> writes: > Would you like to help design matching functions to do the same jobs > that pcase does? With pleasure, I'll try to do my best. > I would like to make it possible to combine various matching and > destructuring functions using `and' and `or' (plus any other Lisp > functions you like). Would this still be based on pcase or be something completely new? Michael. ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-11-20 14:35 ` Michael Heerdegen @ 2023-11-23 2:57 ` Richard Stallman 0 siblings, 0 replies; 342+ messages in thread From: Richard Stallman @ 2023-11-23 2:57 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. ]]] > > Would you like to help design matching functions to do the same jobs > > that pcase does? > With pleasure, I'll try to do my best. Thank you. > > I would like to make it possible to combine various matching and > > destructuring functions using `and' and `or' (plus any other Lisp > > functions you like). > Would this still be based on pcase or be something completely new? It would become part of the cond* idea that I previously posted the first draft of. I posted a newer version today. -- Dr Richard Stallman (https://stallman.org) Chief GNUisance of the GNU Project (https://gnu.org) Founder, Free Software Foundation (https://fsf.org) Internet Hall-of-Famer (https://internethalloffame.org) ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-11-16 3:04 Instead of pcase Richard Stallman 2023-11-16 7:37 ` Philip Kaludercic 2023-11-16 15:06 ` Michael Heerdegen @ 2023-11-16 15:20 ` Spencer Baugh 2023-11-16 20:16 ` Tomas Hlavaty 2023-11-18 3:03 ` combining cond and let, to replace pcase Richard Stallman 2023-11-16 18:11 ` Instead of pcase Emanuel Berg 2023-11-16 18:22 ` Jim Porter 4 siblings, 2 replies; 342+ messages in thread From: Spencer Baugh @ 2023-11-16 15:20 UTC (permalink / raw) To: emacs-devel Setting aside whether pcase is good or not: I've thought before that it would be nice to have a cond-let construct, like if-let and when-let. The body of a cond clause would be bound to the result of the condition. Perhaps that could be a good alternative to some use-cases for pcase? For example, if one has a cons whose cdr is a string if the car is 'foo, and whose cdr is a number if the car is 'bar, then with pcase one can write: (let ((exp (if t '(foo . "str") '(bar . 7)))) (pcase exp (`(foo . ,val) (concat "str" val)) (`(bar . ,val) (+ 1 val)))) and with cond-let one could write: (let ((exp (if t '(foo . "str") '(bar . 7)))) (cond-let ((val (and (eq (car exp) 'foo) (cdr exp))) (concat "str" val)) ((val (and (eq (car exp) 'bar) (cdr exp))) (+ 1 val)))) Which is maybe nicer? ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-11-16 15:20 ` Spencer Baugh @ 2023-11-16 20:16 ` Tomas Hlavaty 2023-11-16 21:37 ` [External] : " Drew Adams 2023-11-25 4:34 ` Stefan Monnier via Emacs development discussions. 2023-11-18 3:03 ` combining cond and let, to replace pcase Richard Stallman 1 sibling, 2 replies; 342+ messages in thread From: Tomas Hlavaty @ 2023-11-16 20:16 UTC (permalink / raw) To: Spencer Baugh, emacs-devel On Thu 16 Nov 2023 at 10:20, Spencer Baugh <sbaugh@janestreet.com> wrote: > (let ((exp (if t '(foo . "str") '(bar . 7)))) > (pcase exp > (`(foo . ,val) (concat "str" val)) > (`(bar . ,val) (+ 1 val)))) (`(foo . ,val) (concat "str" val)) looks very strange. One does not write (let ((,val ...)) ...). Maybe (('foo . val) (concat "str" val)) would make more sense? > and with cond-let one could write: > > (let ((exp (if t '(foo . "str") '(bar . 7)))) > (cond-let > ((val > (and (eq (car exp) 'foo) (cdr exp))) > (concat "str" val)) > ((val > (and (eq (car exp) 'bar) (cdr exp))) > (+ 1 val)))) > > Which is maybe nicer? (let ((exp (if t '(foo . "str") '(bar . 7)))) (cl-case (car exp) (foo (when-let ((d (cdr exp))) (concat "str" val))) (bar (when-let ((d (cdr exp))) (1+ val))))) It is a shame that case, ecase, typecase and etypecase are (were moved?) to cl-lib. ^ permalink raw reply [flat|nested] 342+ messages in thread
* RE: [External] : Re: Instead of pcase 2023-11-16 20:16 ` Tomas Hlavaty @ 2023-11-16 21:37 ` Drew Adams 2023-11-25 4:34 ` Stefan Monnier via Emacs development discussions. 1 sibling, 0 replies; 342+ messages in thread From: Drew Adams @ 2023-11-16 21:37 UTC (permalink / raw) To: Tomas Hlavaty, Spencer Baugh, emacs-devel@gnu.org > It is a shame that case, ecase, typecase and etypecase are (were moved?) > to cl-lib. +1. (Not literally a shame - no shame. But a pity.) ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-11-16 20:16 ` Tomas Hlavaty 2023-11-16 21:37 ` [External] : " Drew Adams @ 2023-11-25 4:34 ` Stefan Monnier via Emacs development discussions. 2023-11-25 8:53 ` Eli Zaretskii 1 sibling, 1 reply; 342+ messages in thread From: Stefan Monnier via Emacs development discussions. @ 2023-11-25 4:34 UTC (permalink / raw) To: emacs-devel > (let ((exp (if t '(foo . "str") '(bar . 7)))) > (cl-case (car exp) > (foo > (when-let ((d (cdr exp))) > (concat "str" val))) > (bar > (when-let ((d (cdr exp))) > (1+ val))))) AKA (let ((exp (if t '(foo . "str") '(bar . 7)))) (case (car exp) ('foo (when-let ((d (cdr exp))) (concat "str" val))) ('bar (when-let ((d (cdr exp))) (1+ val))))) Funnily enough this quoting of the values against which we want to match is so natural for coders not familiar with `cl-case` that we went through some efforts to try and detect their mis-use. So at least for some coders, in the above case, the `pcase` syntax is the more natural one :-) Stefan ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-11-25 4:34 ` Stefan Monnier via Emacs development discussions. @ 2023-11-25 8:53 ` Eli Zaretskii 0 siblings, 0 replies; 342+ messages in thread From: Eli Zaretskii @ 2023-11-25 8:53 UTC (permalink / raw) To: Stefan Monnier; +Cc: emacs-devel > Date: Fri, 24 Nov 2023 23:34:24 -0500 > From: Stefan Monnier via "Emacs development discussions." <emacs-devel@gnu.org> > > > (let ((exp (if t '(foo . "str") '(bar . 7)))) > > (cl-case (car exp) > > (foo > > (when-let ((d (cdr exp))) > > (concat "str" val))) > > (bar > > (when-let ((d (cdr exp))) > > (1+ val))))) > > AKA > > (let ((exp (if t '(foo . "str") '(bar . 7)))) > (case (car exp) > ('foo > (when-let ((d (cdr exp))) > (concat "str" val))) > ('bar > (when-let ((d (cdr exp))) > (1+ val))))) > > Funnily enough this quoting of the values against which we want to match > is so natural for coders not familiar with `cl-case` that we went > through some efforts to try and detect their mis-use. > > So at least for some coders, in the above case, the `pcase` syntax is the > more natural one :-) And 'cond' is more natural yet (in these simple cases). Basically, all that pcase saves us there is the call to 'eq'. ^ permalink raw reply [flat|nested] 342+ messages in thread
* combining cond and let, to replace pcase. 2023-11-16 15:20 ` Spencer Baugh 2023-11-16 20:16 ` Tomas Hlavaty @ 2023-11-18 3:03 ` Richard Stallman 2023-11-19 11:20 ` Michael Heerdegen ` (3 more replies) 1 sibling, 4 replies; 342+ messages in thread From: Richard Stallman @ 2023-11-18 3:03 UTC (permalink / raw) To: Spencer Baugh; +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. ]]] > I've thought before that it would be nice to have a cond-let construct, > like if-let and when-let. Here's an example to show what I have come up with along these lines: (cond* (:bind (x foobar) y z (foo 5) a) ;; variables to bind, as in let ;; I'm also thinking of using nil instead of :bind. ;; t as condition means run this clause unconditionally ;; then continue with next clause. (t do-this-unconditionally-and-dont-stop...) ;; Tests with a new function `match' which I'm going to work on next. ((match x 'foo) ...) ;; t in the last clause means the same as in previous clauses, ;; but you can think of it as being the same as in `cond'. (t do-this-as-last-resort) ) Rhe idea is that conf* does part of pcase's added functionality, and `match' will do the rest. But it is not necessary to cram _all_ the additional matching functionality (to compare to pcase) into a single new function. We could have more than one new function, eacn for its own kind of pattern matching. Some of them could do destructuring as well as matching. I hoipe that using a few constructs to divide up the job will avoid the kludginess of pcase's bells-and-whistles-for-everything approach, resulting in something equally convenient but made of simple components. -- Dr Richard Stallman (https://stallman.org) Chief GNUisance of the GNU Project (https://gnu.org) Founder, Free Software Foundation (https://fsf.org) Internet Hall-of-Famer (https://internethalloffame.org) ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: combining cond and let, to replace pcase. 2023-11-18 3:03 ` combining cond and let, to replace pcase Richard Stallman @ 2023-11-19 11:20 ` Michael Heerdegen 2023-11-19 11:43 ` Eli Zaretskii ` (3 more replies) 2023-11-19 16:08 ` Axel Forsman ` (2 subsequent siblings) 3 siblings, 4 replies; 342+ messages in thread From: Michael Heerdegen @ 2023-11-19 11:20 UTC (permalink / raw) To: Richard Stallman; +Cc: Spencer Baugh, emacs-devel Richard Stallman <rms@gnu.org> writes: > Some of them could do destructuring as well as matching. > > I hoipe that using a few constructs to divide up the job will avoid > the kludginess of pcase's bells-and-whistles-for-everything approach, > resulting in something equally convenient but made of simple > components. I really don't know how you come to such a conclusion. The original docstring of `pcase' was half of a screen page and it was _complete_. Syntax and semantics are simple, nearly trivial, and consistent. It took one minute for me to learn everything. Then the doc has been extended to the current form adding more prose, in my eyes, it added not a single bit of information. If some people have a problem understanding the abstract approach, this is something different. But a "kludginess of pcase's bells-and-whistles-for-everything approach" does not exist. So please understand that your approach will make the situation worse for others. To me this discussion looks like some people aren't willing to accept multiplication like 10*5 because it "looks strange" and "one would rather write "5+5+5+5+5+5+5+5+5+5" because this would be much simpler and we don't need this strange "*" at all. Is this unfair? I don't know. But are there any _objective_ reasons why the design of `pcase' would not be optimal? To me this all looks more like being based on vague feelings because the approach is a bit different from what people are used to. But the approach is extremely simple. I think that replacing it with multiple other tools would complicate the matter. Any additionally defined pcase macros are a different thing of course. They extend pcase patterns to a richer but more complicated mini-language. You need to remember more definitions. OTOH, this is not a design fault of pcase patterns: any matching tool that wants to provide specialized tools to support matching of special things (like structs) will have to extend the semantics in one way or the other, and necessarily complicate the tool(s). To sum up, I question your premise of this discussion. In my opinion `pcase' comes very close to the optimal solution for its task. For some reason, people don't accept the backquote syntax it uses, although it perfectly fits the task of destructuring. I just don't understand it. People get crazy about that backquote. Dunno what's the matter with it. But it seems this is one of the main problems. Michael. ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: combining cond and let, to replace pcase. 2023-11-19 11:20 ` Michael Heerdegen @ 2023-11-19 11:43 ` Eli Zaretskii 2023-11-19 12:16 ` Gerd Möllmann 2023-11-19 12:50 ` Michael Heerdegen 2023-11-19 12:04 ` Gerd Möllmann ` (2 subsequent siblings) 3 siblings, 2 replies; 342+ messages in thread From: Eli Zaretskii @ 2023-11-19 11:43 UTC (permalink / raw) To: Michael Heerdegen; +Cc: rms, sbaugh, emacs-devel > From: Michael Heerdegen <michael_heerdegen@web.de> > Cc: Spencer Baugh <sbaugh@janestreet.com>, emacs-devel@gnu.org > Date: Sun, 19 Nov 2023 12:20:20 +0100 > > To sum up, I question your premise of this discussion. Don't. It's a real issue. Maybe not for you, but for some others. No one in their right mind would assume that Richard has "a problem understanding the abstract approach". Just look at which pieces of software he wrote and the various DSLs he designed while at that. So when Richard, of all the people, tells us there's a problem, I suggest that we listen, especially since a few other veteran Emacs developers, who are not unfamiliar with Emacs Lisp and its subtleties, tell something similar if not identical. It could be that pcase is not a problem for you, but that's not what this discussion is about. When on several occasions I told you that some piece of documentation is clear for me, you still insisted for it to be fixed because it wasn't clear for you, and you were right. Because the documentation I write is not for me, it's for others. > In my opinion `pcase' comes very close to the optimal solution for > its task. The same is true for regular expressions. But we still have rx, and some people really prefer it. Maybe this imperfect analogy will help you understand the issue with pcase. ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: combining cond and let, to replace pcase. 2023-11-19 11:43 ` Eli Zaretskii @ 2023-11-19 12:16 ` Gerd Möllmann 2023-11-19 13:21 ` Eli Zaretskii 2023-11-19 16:03 ` Joost Kremers 2023-11-19 12:50 ` Michael Heerdegen 1 sibling, 2 replies; 342+ messages in thread From: Gerd Möllmann @ 2023-11-19 12:16 UTC (permalink / raw) To: Eli Zaretskii; +Cc: Michael Heerdegen, rms, sbaugh, emacs-devel Eli Zaretskii <eliz@gnu.org> writes: >> From: Michael Heerdegen <michael_heerdegen@web.de> >> Cc: Spencer Baugh <sbaugh@janestreet.com>, emacs-devel@gnu.org >> Date: Sun, 19 Nov 2023 12:20:20 +0100 >> >> To sum up, I question your premise of this discussion. > > Don't. It's a real issue. Maybe not for you, but for some others. > No one in their right mind would assume that Richard has "a problem > understanding the abstract approach". Just look at which pieces of > software he wrote and the various DSLs he designed while at that. So > when Richard, of all the people, tells us there's a problem, I suggest > that we listen, especially since a few other veteran Emacs developers, > who are not unfamiliar with Emacs Lisp and its subtleties, tell > something similar if not identical. One should always listen, almost always anyway, IMO. You named a few reasons. But to the full truth also belongs that Richard has stopped programming completely in 2008, says he himself, and that he doesn't seem to be very familiar with current Elisp, if he's seen pcase for the first time a few days ago. One must keep that in mind. ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: combining cond and let, to replace pcase. 2023-11-19 12:16 ` Gerd Möllmann @ 2023-11-19 13:21 ` Eli Zaretskii 2023-11-19 13:32 ` Gerd Möllmann 2023-11-19 16:03 ` Joost Kremers 1 sibling, 1 reply; 342+ messages in thread From: Eli Zaretskii @ 2023-11-19 13:21 UTC (permalink / raw) To: Gerd Möllmann; +Cc: michael_heerdegen, rms, sbaugh, emacs-devel > From: Gerd Möllmann <gerd.moellmann@gmail.com> > Cc: Michael Heerdegen <michael_heerdegen@web.de>, rms@gnu.org, > sbaugh@janestreet.com, emacs-devel@gnu.org > Date: Sun, 19 Nov 2023 13:16:58 +0100 > > But to the full truth also belongs that Richard has stopped programming > completely in 2008 'git log --author="rms@gnu.org" --pretty=format:"%an%x09%ad%x09%s"' begs to differ, FWIW. > and that he doesn't seem to be very familiar with current Elisp ?? How is "current ELisp" different from 2008-vintage ELisp? ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: combining cond and let, to replace pcase. 2023-11-19 13:21 ` Eli Zaretskii @ 2023-11-19 13:32 ` Gerd Möllmann 2023-11-19 14:41 ` Eli Zaretskii 0 siblings, 1 reply; 342+ messages in thread From: Gerd Möllmann @ 2023-11-19 13:32 UTC (permalink / raw) To: Eli Zaretskii; +Cc: michael_heerdegen, rms, sbaugh, emacs-devel Eli Zaretskii <eliz@gnu.org> writes: >> From: Gerd Möllmann <gerd.moellmann@gmail.com> >> Cc: Michael Heerdegen <michael_heerdegen@web.de>, rms@gnu.org, >> sbaugh@janestreet.com, emacs-devel@gnu.org >> Date: Sun, 19 Nov 2023 13:16:58 +0100 >> >> But to the full truth also belongs that Richard has stopped programming >> completely in 2008 > > 'git log --author="rms@gnu.org" --pretty=format:"%an%x09%ad%x09%s"' > begs to differ, FWIW. I was remembering some interview I read on the Internet, which I can't find anymore. Anyway, https://stallman.org/stallman-computing.html seems to say some similar: My favorite programming languages are Lisp and C. However, since around 1992 I have worked mainly on free software activism, which means I am too busy to do much programming. Around 2008 I stopped doing programming projects. As a result, I have not had time or occasion to learn newer languages such as Perl, Python, PHP, Ruby, Lua, Go, Scala, Rust, and so on. Therefore, I don't have an opinion about them as languages. >> and that he doesn't seem to be very familiar with current Elisp > > ?? How is "current ELisp" different from 2008-vintage ELisp? CLOS, generalized variables, pcase, apparently, I don't know. ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: combining cond and let, to replace pcase. 2023-11-19 13:32 ` Gerd Möllmann @ 2023-11-19 14:41 ` Eli Zaretskii 2023-11-19 15:27 ` Gerd Möllmann 0 siblings, 1 reply; 342+ messages in thread From: Eli Zaretskii @ 2023-11-19 14:41 UTC (permalink / raw) To: Gerd Möllmann; +Cc: michael_heerdegen, rms, sbaugh, emacs-devel > From: Gerd Möllmann <gerd.moellmann@gmail.com> > Cc: michael_heerdegen@web.de, rms@gnu.org, sbaugh@janestreet.com, > emacs-devel@gnu.org > Date: Sun, 19 Nov 2023 14:32:25 +0100 > > Eli Zaretskii <eliz@gnu.org> writes: > > >> But to the full truth also belongs that Richard has stopped programming > >> completely in 2008 > > > > 'git log --author="rms@gnu.org" --pretty=format:"%an%x09%ad%x09%s"' > > begs to differ, FWIW. > > I was remembering some interview I read on the Internet, which I can't > find anymore. Anyway, https://stallman.org/stallman-computing.html seems > to say some similar: > > My favorite programming languages are Lisp and C. However, since around > 1992 I have worked mainly on free software activism, which means I am > too busy to do much programming. Around 2008 I stopped doing programming > projects. As a result, I have not had time or occasion to learn newer > languages such as Perl, Python, PHP, Ruby, Lua, Go, Scala, Rust, and so > on. Therefore, I don't have an opinion about them as languages. "...stopped doing programming PROJECTS" (emphasis mine). That's not the same as "stopped programming completely". Yours truly, for example, didn't do any programming project whatsoever. > >> and that he doesn't seem to be very familiar with current Elisp > > > > ?? How is "current ELisp" different from 2008-vintage ELisp? > > CLOS, generalized variables, pcase, apparently, I don't know. We all are only starting to get to know these. ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: combining cond and let, to replace pcase. 2023-11-19 14:41 ` Eli Zaretskii @ 2023-11-19 15:27 ` Gerd Möllmann 2023-11-19 15:29 ` Eli Zaretskii 0 siblings, 1 reply; 342+ messages in thread From: Gerd Möllmann @ 2023-11-19 15:27 UTC (permalink / raw) To: Eli Zaretskii; +Cc: michael_heerdegen, rms, sbaugh, emacs-devel Eli Zaretskii <eliz@gnu.org> writes: >> My favorite programming languages are Lisp and C. However, since around >> 1992 I have worked mainly on free software activism, which means I am >> too busy to do much programming. Around 2008 I stopped doing programming >> projects. As a result, I have not had time or occasion to learn newer >> languages such as Perl, Python, PHP, Ruby, Lua, Go, Scala, Rust, and so >> on. Therefore, I don't have an opinion about them as languages. > > "...stopped doing programming PROJECTS" (emphasis mine). That's not > the same as "stopped programming completely". Yours truly, for > example, didn't do any programming project whatsoever. Ok, but it also says before that "which means I am too busy to do much programming" (since 1992). I guess what that means when combined with the later "since 2008" in open to interpretation. What I really meant to say with all this, is that I find doubting a premise is always a good thing. There is more to a given su.bject than what a person has done in the past. I myself, for example, can generally not be trusted. People should always use their own brain. BTW, since you mention it, I've been programming the whole time, until recently, partially because of age. I worked in commercial projects, as a freelance programmer. No Emacs at all, that is 100% true. Not even as a user, for the most time, since say 2004, I don't know. And I'm still not doing much, partially because no-one wanted it (C++, CL packages (kind of there, but rotting)), and partially because I've realized that meanwhile things qre too big for me (concurrent redisplay). But I've done sometihing. Adding packages to Elisp leads one to a lot of strange places :-). However, despite the long absence, in the 1.5 or so that I've picked up Emacs again, and did stuff, I never had any problems understanding things. Which makes what's going on so perplexing. ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: combining cond and let, to replace pcase. 2023-11-19 15:27 ` Gerd Möllmann @ 2023-11-19 15:29 ` Eli Zaretskii 0 siblings, 0 replies; 342+ messages in thread From: Eli Zaretskii @ 2023-11-19 15:29 UTC (permalink / raw) To: Gerd Möllmann; +Cc: michael_heerdegen, rms, sbaugh, emacs-devel > From: Gerd Möllmann <gerd.moellmann@gmail.com> > Cc: michael_heerdegen@web.de, rms@gnu.org, sbaugh@janestreet.com, > emacs-devel@gnu.org > Date: Sun, 19 Nov 2023 16:27:54 +0100 > > However, despite the long absence, in the 1.5 or so that I've picked up > Emacs again, and did stuff, I never had any problems understanding > things. Which makes what's going on so perplexing. People are different. ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: combining cond and let, to replace pcase. 2023-11-19 12:16 ` Gerd Möllmann 2023-11-19 13:21 ` Eli Zaretskii @ 2023-11-19 16:03 ` Joost Kremers 2023-11-19 16:59 ` Eli Zaretskii 1 sibling, 1 reply; 342+ messages in thread From: Joost Kremers @ 2023-11-19 16:03 UTC (permalink / raw) To: emacs-devel; +Cc: Eli Zaretskii, Michael Heerdegen, rms, Gerd Möllmann On Sun, Nov 19 2023, Gerd Möllmann wrote: > But to the full truth also belongs that Richard has stopped programming > completely in 2008, says he himself, and that he doesn't seem to be very > familiar with current Elisp, if he's seen pcase for the first time a few > days ago. One must keep that in mind. Actually, it's not the first time Richard has seen pcase. There was a very similar thread to this one in 2018, where he asked about pcase. See e.g., <https://lists.gnu.org/archive/html/emacs-devel/2018-10/msg00440.html>: ``` > 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? ``` I wrote a somewhat lengthy reply to that message trying to pinpoint the things that I found unintuitive (read: unfamiliar) about pcase's syntax. I won't repeat the whole thing here (the message can be found here: https://lists.gnu.org/archive/html/emacs-devel/2018-10/msg00448.html). The gist of it is that pcase uses a couple of syntax elements that *look* familiar but don't have their familiar meaning. That has actually been said in this thread before, so that's no revelation. I do think the documentation could be improved, however, if it were (re?)written with that aspect in mind. Or perhaps it would be better to add an introductory section explaining those aspects. I'd be willing to give it a shot, BTW, if there's interest. No promise on an ETA, but I should have some spare time in the coming weeks. -- Joost Kremers Life has its moments ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: combining cond and let, to replace pcase. 2023-11-19 16:03 ` Joost Kremers @ 2023-11-19 16:59 ` Eli Zaretskii 2023-11-19 18:29 ` Joost Kremers 0 siblings, 1 reply; 342+ messages in thread From: Eli Zaretskii @ 2023-11-19 16:59 UTC (permalink / raw) To: Joost Kremers; +Cc: emacs-devel, michael_heerdegen, rms, gerd.moellmann > From: Joost Kremers <joostkremers@fastmail.fm> > Cc: Eli Zaretskii <eliz@gnu.org>, Michael Heerdegen > <michael_heerdegen@web.de>, rms@gnu.org, Gerd Möllmann > <gerd.moellmann@gmail.com> > Date: Sun, 19 Nov 2023 17:03:25 +0100 > > That has actually been said in this thread before, so that's no revelation. I do > think the documentation could be improved, however, if it were (re?)written with > that aspect in mind. Or perhaps it would be better to add an introductory > section explaining those aspects. > > I'd be willing to give it a shot, BTW, if there's interest. No promise on an > ETA, but I should have some spare time in the coming weeks. There's always interest in improving the documentation. So from where I stand, please feel free to suggest such improvements. But please note that there are several different methodological approaches to documenting pcase, which already caused in the past quite a bit of arguments about what and how to say there. So please don't feel offended if you hear some objections to portions of what you post when you post it. TIA ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: combining cond and let, to replace pcase. 2023-11-19 16:59 ` Eli Zaretskii @ 2023-11-19 18:29 ` Joost Kremers 2023-11-19 18:35 ` Eli Zaretskii 0 siblings, 1 reply; 342+ messages in thread From: Joost Kremers @ 2023-11-19 18:29 UTC (permalink / raw) To: Eli Zaretskii; +Cc: emacs-devel On Sun, Nov 19 2023, Eli Zaretskii wrote: > There's always interest in improving the documentation. So from where > I stand, please feel free to suggest such improvements. But please > note that there are several different methodological approaches to > documenting pcase, which already caused in the past quite a bit of > arguments about what and how to say there. So please don't feel > offended if you hear some objections to portions of what you post when > you post it. No worries, I've been lurking here long enough to know that brutal honesty is the modus operandi of this list. :D I can really only write what I think I would have found helpful at the time. Whether it's suitable for inclusion or not is for others to decide. -- Joost Kremers Life has its moments ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: combining cond and let, to replace pcase. 2023-11-19 18:29 ` Joost Kremers @ 2023-11-19 18:35 ` Eli Zaretskii 0 siblings, 0 replies; 342+ messages in thread From: Eli Zaretskii @ 2023-11-19 18:35 UTC (permalink / raw) To: Joost Kremers; +Cc: emacs-devel > From: Joost Kremers <joostkremers@fastmail.fm> > Cc: emacs-devel@gnu.org > Date: Sun, 19 Nov 2023 19:29:49 +0100 > > I can really only write what I think I would have found helpful at the time. > Whether it's suitable for inclusion or not is for others to decide. SGTM, TIA. ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: combining cond and let, to replace pcase. 2023-11-19 11:43 ` Eli Zaretskii 2023-11-19 12:16 ` Gerd Möllmann @ 2023-11-19 12:50 ` Michael Heerdegen 2023-11-19 13:08 ` Eli Zaretskii 1 sibling, 1 reply; 342+ messages in thread From: Michael Heerdegen @ 2023-11-19 12:50 UTC (permalink / raw) To: emacs-devel Eli Zaretskii <eliz@gnu.org> writes: > > To sum up, I question your premise of this discussion. > > Don't. It's a real issue. Maybe not for you, but for some others. > No one in their right mind would assume that Richard has "a problem > understanding the abstract approach". Just look at which pieces of > software he wrote and the various DSLs he designed while at that. So > when Richard, of all the people, tells us there's a problem, I suggest > that we listen, especially since a few other veteran Emacs developers, > who are not unfamiliar with Emacs Lisp and its subtleties, tell > something similar if not identical. There is a problem. And I see it. I already said that. But the problem is "some people can't read pcase calls well". The problem is not "pcase is bad". The latter is a subjective conclusion, and this is the part I do not accept as objective truth. And this makes a difference to how we aim to find a solution. Maybe we people actually understanding pcase could also contribute something to a solution? This is not possible if "pcase is badly designed" is the starting point of the discussion that everybody should take as granted objective truth that is meant to be blindly accepted - I don't do that. I accept that people having a problem reading code involving pcase is a problem. > The same is true for regular expressions. But we still have rx, and > some people really prefer it. Maybe this imperfect analogy will help > you understand the issue with pcase. This is an excellent analogy. Which one is the counterpart to `pcase'? `rx' or the string form? Actually both and none, this is exactly the point I raised in my other reply - both have exactly the same complexity, and it is totally subjective and only habit which one you prefer. The amount of knowledge you need to remember, the amount of documentation you need to consult, is the same. And although the string form is normal Lisp (strings are expressions), this fact makes the thing not any easier to use, not a tiny bit. The complexity is in the task. And hidden in the algorithm that runs after you have specified the pattern/the regexp in whatever language you prefer. Michael. ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: combining cond and let, to replace pcase. 2023-11-19 12:50 ` Michael Heerdegen @ 2023-11-19 13:08 ` Eli Zaretskii 2023-11-19 13:52 ` Michael Heerdegen 2023-11-19 13:59 ` Dmitry Gutov 0 siblings, 2 replies; 342+ messages in thread From: Eli Zaretskii @ 2023-11-19 13:08 UTC (permalink / raw) To: Michael Heerdegen; +Cc: emacs-devel > From: Michael Heerdegen <michael_heerdegen@web.de> > Date: Sun, 19 Nov 2023 13:50:26 +0100 > > There is a problem. And I see it. I already said that. > > But the problem is "some people can't read pcase calls well". The > problem is not "pcase is bad". The latter is a subjective conclusion, > and this is the part I do not accept as objective truth. Code that is hard to read, even if only to some of the people, is a problem for us, since we are a project that advances mainly through sporadic contributions of people who tend to disappear after a relatively short time. > I accept that people having a problem reading code involving pcase is a > problem. So we agree. Then arguments about how easy pcase is for some are not relevant, because this is not what this is about, right? > > The same is true for regular expressions. But we still have rx, and > > some people really prefer it. Maybe this imperfect analogy will help > > you understand the issue with pcase. > > This is an excellent analogy. Which one is the counterpart to `pcase'? > `rx' or the string form? The string, of course. > Actually both and none, this is exactly the point I raised in my other > reply - both have exactly the same complexity, and it is totally > subjective and only habit which one you prefer. It isn't only that. It is also that the obscure and subtle nature of regexp strings makes it easy to make mistakes. Just look at the sheer number of regexp mistakes uncovered in our code base by Mattias Engdegård during the last year. It isn't an accident. > The amount of knowledge you need to remember, the amount of > documentation you need to consult, is the same. The rx notation is easier to read and interpret, at least for some, and I submit leads to fewer mistakes. So no, I don't agree that it is "just the habit", and nothing else. ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: combining cond and let, to replace pcase. 2023-11-19 13:08 ` Eli Zaretskii @ 2023-11-19 13:52 ` Michael Heerdegen 2023-11-19 14:45 ` Eli Zaretskii 2023-11-19 13:59 ` Dmitry Gutov 1 sibling, 1 reply; 342+ messages in thread From: Michael Heerdegen @ 2023-11-19 13:52 UTC (permalink / raw) To: emacs-devel Eli Zaretskii <eliz@gnu.org> writes: > So we agree. Then arguments about how easy pcase is for some are not > relevant, because this is not what this is about, right? It is a part of the picture. How many these "some" are is another part. And how harder it will become for those others to work with an alternative tool is again another part. And why is it always suggested that people not liking pcase are the norm and those understanding it well are the deviation from the norm? We don't know whether some different tool is actually easier to learn on average. And we won't find a fair solution if we leave out half of the people. > > This is an excellent analogy. Which one is the counterpart to `pcase'? > > `rx' or the string form? > > The string, of course. Interesting. `rx' is more similar to pcase in some regards - it's extensible with macro definitions (rx-defmacro), has descendants (even more macros: rx-let) and adds syntax to the language that is not Lisp. > It isn't only that. It is also that the obscure and subtle nature of > regexp strings makes it easy to make mistakes. Just look at the sheer > number of regexp mistakes uncovered in our code base by Mattias > Engdegård during the last year. It isn't an accident. We have converters to convert between the two representations. Did we look at mistakes that are typical for `rx' forms? It would be trivial that we find less mistakes in `rx' forms when we only have a small number of them compared to string regexps. > > The amount of knowledge you need to remember, the amount of > > documentation you need to consult, is the same. > > The rx notation is easier to read and interpret, at least for some, > and I submit leads to fewer mistakes. Yes, for some. For me, too, actually. Whether it leads to fewer mistakes I don't know, both representations are really directly isomorphic in this case. > So no, I don't agree that it is "just the habit", and nothing else. Personally I hate it if I have to read string regexps. But I guess some of the pcase critics don't like `rx' and others don't like string regexps. It is also not trivial which of both leads to more programming errors, and why. It is not trivial that `pcase' is a larger hurdle than an alternative. I'm not convinced this is not "just the habit" - but there seems a lot of psychology involved here, too. Michael. ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: combining cond and let, to replace pcase. 2023-11-19 13:52 ` Michael Heerdegen @ 2023-11-19 14:45 ` Eli Zaretskii 2023-11-20 15:35 ` Michael Heerdegen 0 siblings, 1 reply; 342+ messages in thread From: Eli Zaretskii @ 2023-11-19 14:45 UTC (permalink / raw) To: Michael Heerdegen; +Cc: emacs-devel > From: Michael Heerdegen <michael_heerdegen@web.de> > Date: Sun, 19 Nov 2023 14:52:31 +0100 > > And why is it always suggested that people not liking pcase are the norm > and those understanding it well are the deviation from the norm? Who and where suggested that? [I snipped all the rest of your message because it just expresses your opinions, and we already agreed that opinions differ on this.] ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: combining cond and let, to replace pcase. 2023-11-19 14:45 ` Eli Zaretskii @ 2023-11-20 15:35 ` Michael Heerdegen 2023-11-20 16:37 ` Eli Zaretskii 0 siblings, 1 reply; 342+ messages in thread From: Michael Heerdegen @ 2023-11-20 15:35 UTC (permalink / raw) To: emacs-devel Eli Zaretskii <eliz@gnu.org> writes: > > And why is it always suggested that people not liking pcase are the > > norm and those understanding it well are the deviation from the > > norm? > > Who and where suggested that? That's how it feels on this side of the discussion. Do I really need to prove this? I could do that, but it would be a waste of time I guess, and I partially did that in other places of this thread. > [I snipped all the rest of your message because it just expresses your > opinions, and we already agreed that opinions differ on this.] Sure. Michael. ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: combining cond and let, to replace pcase. 2023-11-20 15:35 ` Michael Heerdegen @ 2023-11-20 16:37 ` Eli Zaretskii 2023-11-21 8:33 ` Michael Heerdegen 0 siblings, 1 reply; 342+ messages in thread From: Eli Zaretskii @ 2023-11-20 16:37 UTC (permalink / raw) To: Michael Heerdegen; +Cc: emacs-devel > From: Michael Heerdegen <michael_heerdegen@web.de> > Date: Mon, 20 Nov 2023 16:35:33 +0100 > > Eli Zaretskii <eliz@gnu.org> writes: > > > > And why is it always suggested that people not liking pcase are the > > > norm and those understanding it well are the deviation from the > > > norm? > > > > Who and where suggested that? > > That's how it feels on this side of the discussion. Do I really need to > prove this? You don't need to prove how you feel, but I respectfully request that before you make such feelings public, you double-check your feelings with the actual postings. It is quite possible that your initial interpretation of what you've read was not the only one. This is supposed to be a rational discussion, not one based on feelings. As a matter of fact, I'm not aware of any such suggestions in this and other similar discussions, and if someone actually said that (which I doubt), they don't speak for the project as a whole. So let's drop this part of the discussion, since it is nowhere near being constructive. ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: combining cond and let, to replace pcase. 2023-11-20 16:37 ` Eli Zaretskii @ 2023-11-21 8:33 ` Michael Heerdegen 2023-11-21 8:39 ` Michael Heerdegen 0 siblings, 1 reply; 342+ messages in thread From: Michael Heerdegen @ 2023-11-21 8:33 UTC (permalink / raw) To: emacs-devel Eli Zaretskii <eliz@gnu.org> writes: > You don't need to prove how you feel, but I respectfully request that > before you make such feelings public, you double-check your feelings > with the actual postings. I assure you they are there for a reason. > It is quite possible that your initial interpretation of what you've > read was not the only one. This is supposed to be a rational > discussion, not one based on feelings. As far as I know, there is no rational discussion between humans, this is naïve wishful thinking. This discussion has been _highly_ emotional from the beginning, and not because of me. It had been based on feelings to a large extent. Just not explicitly. As far as I know, hiding feelings behind arguments leads to more subliminal aggression, leads to women staying out of the discussion (has anyone ever wondered why nearly no women are present here?) and lets discussions escalate more quickly, as we already have seen in this thread. Please don't misunderstood: of course should any discussion revolve around arguments and ideas. But we are humans and also have to deal with that aspect. So far, we haven't dealt with it in an optimal way, in my opinion. Michael. ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: combining cond and let, to replace pcase. 2023-11-21 8:33 ` Michael Heerdegen @ 2023-11-21 8:39 ` Michael Heerdegen 0 siblings, 0 replies; 342+ messages in thread From: Michael Heerdegen @ 2023-11-21 8:39 UTC (permalink / raw) To: emacs-devel Michael Heerdegen <michael_heerdegen@web.de> writes: > But we are humans and also have to deal with that aspect. So far, we > haven't dealt with it in an optimal way, in my opinion. I didn't intent to say that you would not be doing a good job as a moderator, you are doing an excellent job. Nonetheless do I think I added an important point and it is worth to think about it (not in this thread of course). Michael. ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: combining cond and let, to replace pcase. 2023-11-19 13:08 ` Eli Zaretskii 2023-11-19 13:52 ` Michael Heerdegen @ 2023-11-19 13:59 ` Dmitry Gutov 2023-11-19 14:49 ` Eli Zaretskii 1 sibling, 1 reply; 342+ messages in thread From: Dmitry Gutov @ 2023-11-19 13:59 UTC (permalink / raw) To: Eli Zaretskii, Michael Heerdegen; +Cc: emacs-devel On 19/11/2023 15:08, Eli Zaretskii wrote: >> Actually both and none, this is exactly the point I raised in my other >> reply - both have exactly the same complexity, and it is totally >> subjective and only habit which one you prefer. > It isn't only that. It is also that the obscure and subtle nature of > regexp strings makes it easy to make mistakes. Just look at the sheer > number of regexp mistakes uncovered in our code base by Mattias > Engdegård during the last year. It isn't an accident. pcase is much better guarded against programmer mistakes because in a lot of cases typos or misunderstandings will be highlighted by the byte-compiler (potentially, with flymake directly in the buffer, which I also recommend everyone to enable). Both rx and string regexps aren't able to take advantage of such. Mattias's checker took a lot of steps toward the same functionality, but it's ultimately limited, e.g. because we don't annotate regexps any differently from strings in the code. ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: combining cond and let, to replace pcase. 2023-11-19 13:59 ` Dmitry Gutov @ 2023-11-19 14:49 ` Eli Zaretskii 2023-11-19 14:53 ` Dmitry Gutov 0 siblings, 1 reply; 342+ messages in thread From: Eli Zaretskii @ 2023-11-19 14:49 UTC (permalink / raw) To: Dmitry Gutov; +Cc: michael_heerdegen, emacs-devel > Date: Sun, 19 Nov 2023 15:59:46 +0200 > Cc: emacs-devel@gnu.org > From: Dmitry Gutov <dmitry@gutov.dev> > > On 19/11/2023 15:08, Eli Zaretskii wrote: > >> Actually both and none, this is exactly the point I raised in my other > >> reply - both have exactly the same complexity, and it is totally > >> subjective and only habit which one you prefer. > > It isn't only that. It is also that the obscure and subtle nature of > > regexp strings makes it easy to make mistakes. Just look at the sheer > > number of regexp mistakes uncovered in our code base by Mattias > > Engdegård during the last year. It isn't an accident. > > pcase is much better guarded against programmer mistakes because in a > lot of cases typos or misunderstandings will be highlighted by the > byte-compiler (potentially, with flymake directly in the buffer, which I > also recommend everyone to enable). When we review patches, we don't normally byte-compile the changes, nor need to run flymake on it. Usually, it's enough to read the code. Having to use non-trivial tools (which means apply the changes, which means use some scratch branch or something similar) is extra hurdle. It also means patches cannot be easily reviewed if all you have is a MUA, without a full-blown Emacs development environment. IOW, it means extra requirements and restrictions, so it's a disadvantage. It raises the bar. ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: combining cond and let, to replace pcase. 2023-11-19 14:49 ` Eli Zaretskii @ 2023-11-19 14:53 ` Dmitry Gutov 0 siblings, 0 replies; 342+ messages in thread From: Dmitry Gutov @ 2023-11-19 14:53 UTC (permalink / raw) To: Eli Zaretskii; +Cc: michael_heerdegen, emacs-devel On 19/11/2023 16:49, Eli Zaretskii wrote: >> Date: Sun, 19 Nov 2023 15:59:46 +0200 >> Cc:emacs-devel@gnu.org >> From: Dmitry Gutov<dmitry@gutov.dev> >> >> On 19/11/2023 15:08, Eli Zaretskii wrote: >>>> Actually both and none, this is exactly the point I raised in my other >>>> reply - both have exactly the same complexity, and it is totally >>>> subjective and only habit which one you prefer. >>> It isn't only that. It is also that the obscure and subtle nature of >>> regexp strings makes it easy to make mistakes. Just look at the sheer >>> number of regexp mistakes uncovered in our code base by Mattias >>> Engdegård during the last year. It isn't an accident. >> pcase is much better guarded against programmer mistakes because in a >> lot of cases typos or misunderstandings will be highlighted by the >> byte-compiler (potentially, with flymake directly in the buffer, which I >> also recommend everyone to enable). > When we review patches, we don't normally byte-compile the changes, > nor need to run flymake on it. Usually, it's enough to read the code. > Having to use non-trivial tools (which means apply the changes, which > means use some scratch branch or something similar) is extra hurdle. > It also means patches cannot be easily reviewed if all you have is a > MUA, without a full-blown Emacs development environment. > > IOW, it means extra requirements and restrictions, so it's a > disadvantage. It raises the bar. When we don't run a patch through CI, or apply it locally, we can just as well miss typos in "simple" code (and have done that on many occasions). That just puts the burden of testing code code and using flymake on the contributor (both good practices anyway). ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: combining cond and let, to replace pcase. 2023-11-19 11:20 ` Michael Heerdegen 2023-11-19 11:43 ` Eli Zaretskii @ 2023-11-19 12:04 ` Gerd Möllmann 2023-11-19 18:10 ` Tomas Hlavaty 2023-11-19 21:36 ` Alan Mackenzie 3 siblings, 0 replies; 342+ messages in thread From: Gerd Möllmann @ 2023-11-19 12:04 UTC (permalink / raw) To: Michael Heerdegen; +Cc: Richard Stallman, Spencer Baugh, emacs-devel Michael Heerdegen <michael_heerdegen@web.de> writes: > Is this unfair? I don't know. But are there any _objective_ reasons > why the design of `pcase' would not be optimal? To me this all looks > more like being based on vague feelings because the approach is a bit > different from what people are used to. Kind of the same here. And I'm quasi waiting for the next thing to pop up, say generic functions, or generelized variables (gv.el). I'm wondering where the journey goes. ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: combining cond and let, to replace pcase. 2023-11-19 11:20 ` Michael Heerdegen 2023-11-19 11:43 ` Eli Zaretskii 2023-11-19 12:04 ` Gerd Möllmann @ 2023-11-19 18:10 ` Tomas Hlavaty 2023-11-25 4:45 ` Stefan Monnier via Emacs development discussions. 2023-11-19 21:36 ` Alan Mackenzie 3 siblings, 1 reply; 342+ messages in thread From: Tomas Hlavaty @ 2023-11-19 18:10 UTC (permalink / raw) To: Michael Heerdegen, Richard Stallman; +Cc: Spencer Baugh, emacs-devel On Sun 19 Nov 2023 at 12:20, Michael Heerdegen <michael_heerdegen@web.de> wrote: > Richard Stallman <rms@gnu.org> writes: > >> Some of them could do destructuring as well as matching. >> >> I hoipe that using a few constructs to divide up the job will avoid >> the kludginess of pcase's bells-and-whistles-for-everything approach, >> resulting in something equally convenient but made of simple >> components. > > I really don't know how you come to such a conclusion. [...] > To me this discussion looks like some people aren't willing to accept > multiplication like 10*5 because it "looks strange" and "one would rather > write "5+5+5+5+5+5+5+5+5+5" because this would be much simpler and we > don't need this strange "*" at all. no, one would rather write (* 10 5) and (+ 5 (* 3 2) 1) than 5+3*2+1 instead of a form with complex syntax, e.g. have * and + functions instead of infix macro that is why cl-loop and maybe pcase are "ugly" one heuristic could be if autodoc can display something useful ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: combining cond and let, to replace pcase. 2023-11-19 18:10 ` Tomas Hlavaty @ 2023-11-25 4:45 ` Stefan Monnier via Emacs development discussions. 2023-11-28 15:31 ` João Távora 0 siblings, 1 reply; 342+ messages in thread From: Stefan Monnier via Emacs development discussions. @ 2023-11-25 4:45 UTC (permalink / raw) To: emacs-devel > that is why cl-loop and maybe pcase are "ugly" > one heuristic could be if autodoc can display something useful I suspect it would be difficult to do for `cl-loop` (would require heavy hacking on `cl-loop` itself), but for `pcase` (and `bindat-type`) I think it would not be too terribly hard to add Eldoc support, and it would be definitely a nice improvement. Stefan ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: combining cond and let, to replace pcase. 2023-11-25 4:45 ` Stefan Monnier via Emacs development discussions. @ 2023-11-28 15:31 ` João Távora 2023-11-28 15:55 ` Stefan Monnier 0 siblings, 1 reply; 342+ messages in thread From: João Távora @ 2023-11-28 15:31 UTC (permalink / raw) To: Stefan Monnier; +Cc: emacs-devel On Sat, Nov 25, 2023 at 4:45 AM Stefan Monnier via Emacs development discussions. <emacs-devel@gnu.org> wrote: > > > that is why cl-loop and maybe pcase are "ugly" > > one heuristic could be if autodoc can display something useful > > I suspect it would be difficult to do for `cl-loop` (would require heavy > hacking on `cl-loop` itself), Would it? Isn't this more or less the same information that Edebug already has for stepping through it? Also, has someone also posted the obligatory https://xkcd.com/927/ here? ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: combining cond and let, to replace pcase. 2023-11-28 15:31 ` João Távora @ 2023-11-28 15:55 ` Stefan Monnier 0 siblings, 0 replies; 342+ messages in thread From: Stefan Monnier @ 2023-11-28 15:55 UTC (permalink / raw) To: João Távora; +Cc: emacs-devel >> > that is why cl-loop and maybe pcase are "ugly" >> > one heuristic could be if autodoc can display something useful >> >> I suspect it would be difficult to do for `cl-loop` (would require heavy >> hacking on `cl-loop` itself), > > Would it? Isn't this more or less the same information that Edebug > already has for stepping through it? No, I think Eldoc on subexpressions inside `cl-loop` and `pcase` already work, the question was rather how to make Eldoc give tips about the macro's own syntax, e.g. when you're inside a `pred` or a `guard` display things like (guard BOOLEXP) or (pred FUN) and when you're after an `in` on `cl-loop` maybe something like PATTERN in LIST This info is not included in the Edebug specs :-( But you're right that maybe we could do that without too much extra work by adding that info to the Edebug spec. Stefan ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: combining cond and let, to replace pcase. 2023-11-19 11:20 ` Michael Heerdegen ` (2 preceding siblings ...) 2023-11-19 18:10 ` Tomas Hlavaty @ 2023-11-19 21:36 ` Alan Mackenzie 2023-11-21 16:14 ` Michael Heerdegen 3 siblings, 1 reply; 342+ messages in thread From: Alan Mackenzie @ 2023-11-19 21:36 UTC (permalink / raw) To: Michael Heerdegen; +Cc: Richard Stallman, Spencer Baugh, emacs-devel Hello, Michael. On Sun, Nov 19, 2023 at 12:20:20 +0100, Michael Heerdegen wrote: > Richard Stallman <rms@gnu.org> writes: > > Some of them could do destructuring as well as matching. > > I hoipe that using a few constructs to divide up the job will avoid > > the kludginess of pcase's bells-and-whistles-for-everything approach, > > resulting in something equally convenient but made of simple > > components. > I really don't know how you come to such a conclusion. > The original docstring of `pcase' was half of a screen page and it was > _complete_. Syntax and semantics are simple, nearly trivial, and > consistent. It took one minute for me to learn everything. Then the > doc has been extended to the current form adding more prose, in my eyes, > it added not a single bit of information. The original doc string of pcase was not a high quality one. See the thread in emacs-devel Subject: The poor state of documentation of pcase like things, started by me on 2015-12-16. Some of its deficiencies, listed in that post, were (i) Use of obscure terms like U-pattern and Q-pattern which it failed to define; (ii) the semantics of these structures was not elucidated; (iii) there was no rigorous definition of what ` and , mean in pcase structures; (iv) there was no specification of when a pcase pattern matched something; (v) there was no specification of when and how variables got bound. The doc string didn't say in accessible language what pcase does. But I'm repeating myself. It's all in that 8 year old post. I may be mis-remembering, but I think it was you, Michael, who put in the work to fix these defects in pcase's doc string. The result was far better than the original. > If some people have a problem understanding the abstract approach, this > is something different. But a "kludginess of pcase's > bells-and-whistles-for-everything approach" does not exist. So please > understand that your approach will make the situation worse for others. > To me this discussion looks like some people aren't willing to accept > multiplication like 10*5 because it "looks strange" and "one would rather > write "5+5+5+5+5+5+5+5+5+5" because this would be much simpler and we > don't need this strange "*" at all. > Is this unfair? I don't know. But are there any _objective_ reasons > why the design of `pcase' would not be optimal? To me this all looks > more like being based on vague feelings because the approach is a bit > different from what people are used to. But the approach is extremely > simple. I think that replacing it with multiple other tools would > complicate the matter. pcase complicated the meaning of ` and ,. Before pcase these had definite meanings. Afterwards, they became highly context dependent. The usual evasive reply from pcase proponents here is that ` has always been an abbreviation for backslash and that didn't change. A lot changed, here. An alternative here would have been to invent new reader macros instead of complicating and ambiguating ` and ,. [ .... ] > Michael. -- Alan Mackenzie (Nuremberg, Germany). ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: combining cond and let, to replace pcase. 2023-11-19 21:36 ` Alan Mackenzie @ 2023-11-21 16:14 ` Michael Heerdegen 0 siblings, 0 replies; 342+ messages in thread From: Michael Heerdegen @ 2023-11-21 16:14 UTC (permalink / raw) To: Alan Mackenzie; +Cc: Richard Stallman, Spencer Baugh, emacs-devel Alan Mackenzie <acm@muc.de> writes: > I may be mis-remembering, but I think it was you, Michael, who put in > the work to fix these defects in pcase's doc string. The result was > far better than the original. Only some work was done by me. For me, personally (and only that) the documentation got worse. That's ok if it helps a lot of people. If you have a more mathematical background, the intention and the idea behind `pcase' are somewhat shadowed now. > An alternative here would have been to invent new reader macros > instead of complicating and ambiguating ` and ,. That would further shadow the idea. It is obviously necessary to understand that design idea. Seems this is the major problem for most people. We should probably do this in the documentation if we have not yet. Or did we? Michael. ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: combining cond and let, to replace pcase. 2023-11-18 3:03 ` combining cond and let, to replace pcase Richard Stallman 2023-11-19 11:20 ` Michael Heerdegen @ 2023-11-19 16:08 ` Axel Forsman 2023-11-21 15:53 ` Michael Heerdegen 2023-11-23 2:58 ` Richard Stallman 3 siblings, 0 replies; 342+ messages in thread From: Axel Forsman @ 2023-11-19 16:08 UTC (permalink / raw) To: rms; +Cc: Spencer Baugh, emacs-devel Richard Stallman <rms@gnu.org> writes: > > I've thought before that it would be nice to have a cond-let construct, > > like if-let and when-let. > > Here's an example to show what I have come up with along these lines: > > (cond* (:bind (x foobar) y z (foo 5) a) ;; variables to bind, as in let > ;; I'm also thinking of using nil instead of :bind. > > ;; t as condition means run this clause unconditionally > ;; then continue with next clause. > (t do-this-unconditionally-and-dont-stop...) > > ;; Tests with a new function `match' which I'm going to work on next. > ((match x 'foo) ...) > > ;; t in the last clause means the same as in previous clauses, > ;; but you can think of it as being the same as in `cond'. > (t do-this-as-last-resort) > ) > > Rhe idea is that conf* does part of pcase's added functionality, and > `match' will do the rest. But it is not necessary to cram _all_ the > additional matching functionality (to compare to pcase) into a single > new function. > > We could have more than one new function, eacn for its own kind of > pattern matching. > > Some of them could do destructuring as well as matching. pcase is not concerned with your proposed :bind and t keywords. For a discussion about pcase being too "large", it seems weird to suggest an alternative that does even more. What am I missing? Also, the various `match' constructs would have to be part of the conf* macro as destructuring needs to bind variables, so I fail to see how this would be an improvement over the status quo? I may be misinterpreting what you are proposing here, and in that case I apologize, but in general should one not try to understand the thing they are attempting to replace, or else likely make the same mistakes? > I hoipe that using a few constructs to divide up the job will avoid > the kludginess of pcase's bells-and-whistles-for-everything approach, > resulting in something equally convenient but made of simple components. I will preface this by saying that I like pcase, I think it is one of the better-written Emacs Lisp packages. History has shown that declarative pattern matching à la ML is a good concept, with languages on the "other side of the pond" such as Java; Python; C++; JavaScript; and C#, all eventually adopting it. Any discussion about the purported complexity of pcase should start with delineating the essentials of pcase, (something I do not think this mailing thread has done a good job of), which is that the pcase syntax for destructuring a value should mirror the syntax for constructing that same value. E.g. `(if ,condition ,consequent ,alternative) constructs a list if condition, consequent, and alternative are variables currently bound, and is also a pcase pattern for deconstructing that same list. IMO that is perfectly simple. Does the addition of other pcase pattern-forms such as pred/app/guard/and/or complicate things too much? I would say maybe; it is certainly possible to abuse them. On the other hand, it is very useful to match against an integer in some range, nested withing a list, e.g. (pcase x (`(integer ,(and (pred (lambda (i) (< 0 i 5))) i)) (print i)) (`(integer ,i) (do-something-else i)) ...) From what I have seen from languages that do not have special syntax for matching integers in ranges, this would usually be handled by guard expressions as a second step after matching is done, e.g. (pcase x (`(integer ,i) :when (< 0 i 5) (print i)) (`(integer ,i) (do-something-else i)) ...) Something like that would work to keep the patterns simpler. Without pred/app/guard/and/or one could think of getting rid of the messy backquote/comma syntax, for something cleaner based just on lists, e.g. (pcase x (('integer i) (print i)) (('if condition consequent alternative) (message "if")) ...) however that would not good for a couple of reasons: 1. The syntax for constructing lists is no longer the same as for destructuring. 2. It would leave little room for incorporating syntax for destructuring cl-struct:s, etc. pcase has the (cl-struct TYPE &rest FIELDS) form for this purpose, which is what it is, but at least I think it is good that it exists. This is all to say that I disagree with your claim that pcase has a bells-and-whistles-for-everything approach. Rather it is maximally compositional and based on the easy-to-learn and neat duality of constructing/destructuring. I also consider it a mistake to introduce forms such as > ;; t as condition means run this clause unconditionally > ;; then continue with next clause. > (t do-this-unconditionally-and-dont-stop...) with non-descriptive names such as nil/t, that introduce side-effects in the middle of matching something. Pattern matching is great because it is declarative and makes it possible to communicate intent, rather than concerning ourselves with what combination of car/cdr/equal/let/if is needed to achieve what we want. ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: combining cond and let, to replace pcase. 2023-11-18 3:03 ` combining cond and let, to replace pcase Richard Stallman 2023-11-19 11:20 ` Michael Heerdegen 2023-11-19 16:08 ` Axel Forsman @ 2023-11-21 15:53 ` Michael Heerdegen 2023-11-23 2:58 ` Richard Stallman 3 siblings, 0 replies; 342+ messages in thread From: Michael Heerdegen @ 2023-11-21 15:53 UTC (permalink / raw) To: Richard Stallman; +Cc: Spencer Baugh, emacs-devel Richard Stallman <rms@gnu.org> writes: > Here's an example to show what I have come up with along these lines: > > (cond* (:bind (x foobar) y z (foo 5) a) ;; variables to bind, as in let > ;; I'm also thinking of using nil instead of :bind. > > ;; t as condition means run this clause unconditionally > ;; then continue with next clause. > (t do-this-unconditionally-and-dont-stop...) > > ;; Tests with a new function `match' which I'm going to work on next. > ((match x 'foo) ...) > > ;; t in the last clause means the same as in previous clauses, > ;; but you can think of it as being the same as in `cond'. > (t do-this-as-last-resort) > ) > > Rhe idea is that conf* does part of pcase's added functionality, and > `match' will do the rest. But it is not necessary to cram _all_ the > additional matching functionality (to compare to pcase) into a single > new function. We could have more than one new function, eacn for its > own kind of pattern matching. I've also sometimes missed a cond-let. I think the above example shows something slightly different: binding is done in one branch, but the bindings are visible in all (following?) branches (instead of only the branch BODY). So that's, at least in this example, more or less an amalgamated let + cond. The interesting part, the matching, is not shown, so I only have a vague imagination of the whole picture. Have you continued working on this approach in the meantime? Michael. ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: combining cond and let, to replace pcase. 2023-11-18 3:03 ` combining cond and let, to replace pcase Richard Stallman ` (2 preceding siblings ...) 2023-11-21 15:53 ` Michael Heerdegen @ 2023-11-23 2:58 ` Richard Stallman 2023-11-23 7:02 ` Tomas Hlavaty ` (3 more replies) 3 siblings, 4 replies; 342+ messages in thread From: Richard Stallman @ 2023-11-23 2:58 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. ]]] I've done more work on designing `cond*'; here is what I have now. Please send me constructive suggestions, including for features you suggest adding. (cond* ;; Same as a clause in `cond', (CONDITION do-this-if-CONDITION-then-exit...) ;; Variables to bind, as in let (:bind (x foobar) y z (foo 5) a) ;; Bindings continue in effect. ;; t as condition means run this clause unconditionally ;; then always continue with next clause. (t do-this-unconditionally-and-dont-stop...) ;; Extracts substructure and binds variables around the rest ;; of the cond*. (:match (`(expt ,foo ,bar) x) do-this-if-it-matched-then-exit...) ;; Bindings continue in effect. ;; Like above but always falls thru to next clause. (:match (`(expt ,foo ,bar) x)) ;; Bindings continue in effect. ;; t in the last clause means the same as in previous clauses, ;; but you can think of it as being the same as in `cond'. (t do-this-as-last-resort...) ) Here are three macros that would be useful as conditions in `cond*' but can also be used elsewhere. (match PATTERN VALUE) This is a macro. PATTERN is a backquote form which specifies which parts of VALUE should be fixed. For instance (match `(+ (expt nil nil)) (get-complex-list)) would decompose the result of (get-complex-list) and check for `+' and `expt' in it. PATTERN will not be evaluated, just used as guidance when the `match' form is macroexpanded. If PATTERN includes substitutions, it will virtually perform those substitutions and compare parts of VALUE against them. (match `(foo ,foo) x) compares (car x) with `foo' and compares (cadr x) with the value of foo. `match' can also handle vectors and maybe some other kinds of structures. (match-set PATTERN VALUE) This is a macro. PATTERN is a backquote form which specifies which parts of VALUE to match and parts to extract and store. For instance (match-set `(+ ,y ,z) (get-complex-list)) would decompose the result of (get-complex-list), verify the car, and set y and z. PATTERN will not be evaluated, just used as guidance when the `match-set' form is macroexpanded, producing code like this: (if (eq (car value) '+) (progn (setq y (car (cadr value)) z (cadr (cadr value))) t)) `match' can also handle vectors and maybe some other kinds of structures. (match-bind PATTERN VALUE BODY...) Much like `match-set', except that instead of setting the variables found in PATTERN, it let-binds them and runs BODY with those bindings. -- Dr Richard Stallman (https://stallman.org) Chief GNUisance of the GNU Project (https://gnu.org) Founder, Free Software Foundation (https://fsf.org) Internet Hall-of-Famer (https://internethalloffame.org) ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: combining cond and let, to replace pcase. 2023-11-23 2:58 ` Richard Stallman @ 2023-11-23 7:02 ` Tomas Hlavaty 2023-11-26 3:14 ` Richard Stallman 2023-11-23 8:58 ` Manuel Giraud via Emacs development discussions. ` (2 subsequent siblings) 3 siblings, 1 reply; 342+ messages in thread From: Tomas Hlavaty @ 2023-11-23 7:02 UTC (permalink / raw) To: rms, emacs-devel On Wed 22 Nov 2023 at 21:58, Richard Stallman <rms@gnu.org> wrote: > (cond* > ;; Same as a clause in `cond', > (CONDITION > do-this-if-CONDITION-then-exit...) > > ;; Variables to bind, as in let > (:bind (x foobar) y z (foo 5) a) > ;; Bindings continue in effect. This seems nicer: (if CONDITION do-this-if-CONDITION-then-exit... (let ((x foobar) y z (foo 5) a) ...)) Are there other macros where bindings continue in effect cond* style? It looks like everybody is trying to design a "do it all super-macro" instead of using something like cl-destructuring-bind. > (:match (`(expt ,foo ,bar) x) That looks like writing (let (`(,foo 42)) ...) Are there other macros where unquote marks variable name? ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: combining cond and let, to replace pcase. 2023-11-23 7:02 ` Tomas Hlavaty @ 2023-11-26 3:14 ` Richard Stallman 2023-11-27 17:07 ` Tomas Hlavaty 0 siblings, 1 reply; 342+ messages in thread From: Richard Stallman @ 2023-11-26 3:14 UTC (permalink / raw) To: Tomas Hlavaty; +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. ]]] > > ;; Same as a clause in `cond', > > (CONDITION > > do-this-if-CONDITION-then-exit...) > > > > ;; Variables to bind, as in let > > (:bind (x foobar) y z (foo 5) a) > > ;; Bindings continue in effect. > This seems nicer: > (if CONDITION > do-this-if-CONDITION-then-exit... > (let ((x foobar) y z (foo 5) a) > ...)) That is what you can do now with `if' and `let', but many levels of nexting get to be inconvenient and hard to read. That is one of the practical conveniences of _using_ `pcase'. I think a replacement for `pcase' should offer the same advantage. > It looks like everybody is trying to design a "do it all super-macro" If that refers to the approach of `pcase', in which there are dozens of different features one must learn, then `cond*' represents turning away from that approach. `cond*' has just four features, two of which are modified from `cond'. That's why `cond*' will impose less burden of language complexity than `pcase'. -- Dr Richard Stallman (https://stallman.org) Chief GNUisance of the GNU Project (https://gnu.org) Founder, Free Software Foundation (https://fsf.org) Internet Hall-of-Famer (https://internethalloffame.org) ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: combining cond and let, to replace pcase. 2023-11-26 3:14 ` Richard Stallman @ 2023-11-27 17:07 ` Tomas Hlavaty 2023-11-27 17:59 ` Yuri Khan 0 siblings, 1 reply; 342+ messages in thread From: Tomas Hlavaty @ 2023-11-27 17:07 UTC (permalink / raw) To: rms; +Cc: emacs-devel On Sat 25 Nov 2023 at 22:14, Richard Stallman <rms@gnu.org> wrote: > > > ;; Same as a clause in `cond', > > > (CONDITION > > > do-this-if-CONDITION-then-exit...) > > > > > > ;; Variables to bind, as in let > > > (:bind (x foobar) y z (foo 5) a) > > > ;; Bindings continue in effect. > > > This seems nicer: > > > (if CONDITION > > do-this-if-CONDITION-then-exit... > > (let ((x foobar) y z (foo 5) a) > > ...)) > > That is what you can do now with `if' and `let', but many levels of > nexting get to be inconvenient and hard to read. That is one of the > practical conveniences of _using_ `pcase'. I think a replacement for > `pcase' should offer the same advantage. if you are after less nesting, cond or or can already do that: (cond ;; Same as a clause in `cond', (CONDITION do-this-if-CONDITION-then-exit...) ;; Variables to bind, as in let ((let ((x foobar) y z (foo 5) a) ;; Bindings continue in effect. ...)) ...) even better: (or ;; Same as a clause in `cond', (when CONDITION do-this-if-CONDITION-then-exit...) ;; Variables to bind, as in let (let ((x foobar) y z (foo 5) a) ;; Bindings continue in effect. ...) ...) no need for :bind which seems like superficial syntax that requires extra cond* macro definition with weird rules. > > It looks like everybody is trying to design a "do it all super-macro" > > If that refers to the approach of `pcase', in which there are dozens > of different features one must learn, then `cond*' represents turning > away from that approach. `cond*' has just four features, two of which > are modified from `cond'. > > That's why `cond*' will impose less burden of language complexity than > `pcase'. or, when, let are even simpler and the example with or is even more readable. I do not see what cond* brings. It seems that existing forms cover the control flow part well enough. What should be the focus is the destructuring part, like cl-destructuring-bind or your match, match-set, match-bind or the matching part of pcase. Btw there is even a kind of user-configurable version of the or macro, a kind of pluggable-or called run-hook-with-args-until-success which is like the or macro but with cases as functions in a list. This could allow for use-extensible variant, if the destructuring part was separate and reuseable. ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: combining cond and let, to replace pcase. 2023-11-27 17:07 ` Tomas Hlavaty @ 2023-11-27 17:59 ` Yuri Khan 2023-11-28 14:25 ` Tomas Hlavaty 0 siblings, 1 reply; 342+ messages in thread From: Yuri Khan @ 2023-11-27 17:59 UTC (permalink / raw) To: Tomas Hlavaty; +Cc: rms, emacs-devel On Tue, 28 Nov 2023 at 00:10, Tomas Hlavaty <tom@logand.com> wrote: > even better:> > (or > ;; Same as a clause in `cond', > (when CONDITION > do-this-if-CONDITION-then-exit...) > ;; Variables to bind, as in let > (let ((x foobar) y z (foo 5) a) > ;; Bindings continue in effect. > ...) > ...) This reminds me of the times before Python 2.x had a ternary operator ‘X if CONDITION else Y’. Some FAQs said “you can use this trick: ‘CONDITION and X or Y’”, with a small print (sometimes skipped) “as long as you guarantee that X evaluates to a truthy value”. This is very error-prone. Novices can and will get bitten by this. * ‘or’ evaluates its arguments in turn until one of them evaluates to non-nil. * ‘when’ and ‘let’ evaluate to the last body form if any, or nil if none. So, for the intended effect of exiting the ‘or’ when a branch is taken, one has to make sure to terminate that branch with a truthy expression: (or (when CONDITION do-this-possibly-returning-nil :break) (let (BINDINGS) do-something-else-possibly-returning-nil :break) …more branches…) Also, a ‘cond’ or a ‘pcase’ form will return the result of the branch taken, which can be nil. An ‘or’ form will return the result of the branch taken, as long as it is not nil. A branch that returns nil will result in evaluation of the next branch. ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: combining cond and let, to replace pcase. 2023-11-27 17:59 ` Yuri Khan @ 2023-11-28 14:25 ` Tomas Hlavaty 0 siblings, 0 replies; 342+ messages in thread From: Tomas Hlavaty @ 2023-11-28 14:25 UTC (permalink / raw) To: Yuri Khan; +Cc: rms, emacs-devel On Tue 28 Nov 2023 at 00:59, Yuri Khan <yuri.v.khan@gmail.com> wrote: > So, for the intended effect of exiting the ‘or’ when a branch is > taken, one has to make sure to terminate that branch with a truthy > expression: > > (or > (when CONDITION > do-this-possibly-returning-nil > :break) > (let (BINDINGS) > do-something-else-possibly-returning-nil > :break) > …more branches…) > > Also, a ‘cond’ or a ‘pcase’ form will return the result of the branch > taken, which can be nil. An ‘or’ form will return the result of the > branch taken, as long as it is not nil. A branch that returns nil will > result in evaluation of the next branch. same issue with cond: (cond ((let (bindings) 'do-something-else-possibly-returning-nil nil)) (t :default)) => :default (cond ((let (bindings) 'do-something-else-possibly-returning-nil :break)) (t :default)) => :break ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: combining cond and let, to replace pcase. 2023-11-23 2:58 ` Richard Stallman 2023-11-23 7:02 ` Tomas Hlavaty @ 2023-11-23 8:58 ` Manuel Giraud via Emacs development discussions. 2023-11-26 3:14 ` Richard Stallman 2023-11-24 3:08 ` Daniel Semyonov 2023-11-25 5:11 ` Stefan Monnier via Emacs development discussions. 3 siblings, 1 reply; 342+ messages in thread From: Manuel Giraud via Emacs development discussions. @ 2023-11-23 8:58 UTC (permalink / raw) To: Richard Stallman; +Cc: 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. ]]] > > I've done more work on designing `cond*'; here is what I have now. > Please send me constructive suggestions, including for features you > suggest adding. Only gut feelings here, but fall thru with bindings by default and multiple t may surprise users and lead to not simple to debug code. -- Manuel Giraud ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: combining cond and let, to replace pcase. 2023-11-23 8:58 ` Manuel Giraud via Emacs development discussions. @ 2023-11-26 3:14 ` Richard Stallman 0 siblings, 0 replies; 342+ messages in thread From: Richard Stallman @ 2023-11-26 3:14 UTC (permalink / raw) To: Manuel Giraud; +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. ]]] > Only gut feelings here, but fall thru with bindings by default and > multiple t may surprise users and lead to not simple to debug code. It would be a trivial change to replace t with some keyword, for that functionality. Would it actually be better? What do other s think? Here's a more uniform version, in which each clause exits if it contains more than one element (after the possible keyword), and falls through otherwise. This makes it unnecessary to redefine what t means as a condition -- that can be written another way (see below). (cond* ;; Same as a clause in `cond', (CONDITION DO-THIS-IF-TRUE-THEN-EXIT...) ;; Execute FORM and ignore its value. (FORM) ;; Variables to bind, as in let (:bind ((x foobar) y z (foo 5) a)) ;; Bindings continue in effect. ;; Extracts substructure and binds variables around the rest ;; of the cond*. (:match (`(expt ,foo ,bar) x) DO-THIS-IF-IT-MATCHED-THEN-EXIT...) ;; Bindings continue in effect. ;; Like above but always falls thru to next clause. (:match (`(expt ,foo ,bar) x)) ;; Bindings continue in effect. ) To execute several expressions and not exit, use this: ((progn DO-THIS-UNCONDITIONALLY-AND-DONT-STOP...) -- Dr Richard Stallman (https://stallman.org) Chief GNUisance of the GNU Project (https://gnu.org) Founder, Free Software Foundation (https://fsf.org) Internet Hall-of-Famer (https://internethalloffame.org) ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: combining cond and let, to replace pcase. 2023-11-23 2:58 ` Richard Stallman 2023-11-23 7:02 ` Tomas Hlavaty 2023-11-23 8:58 ` Manuel Giraud via Emacs development discussions. @ 2023-11-24 3:08 ` Daniel Semyonov 2023-11-24 3:26 ` Daniel Semyonov 2023-11-25 2:59 ` Richard Stallman 2023-11-25 5:11 ` Stefan Monnier via Emacs development discussions. 3 siblings, 2 replies; 342+ messages in thread From: Daniel Semyonov @ 2023-11-24 3:08 UTC (permalink / raw) To: rms; +Cc: emacs-devel [-- Attachment #1: Type: text/plain, Size: 1820 bytes --] >>>>> Richard Stallman writes: > I've done more work on designing `cond*'; here is what I have now. > Please send me constructive suggestions, including for features you > suggest adding. I think either the name should be changed or the behavior of t as a condition should be the same as in 'cond', as IMO it could lead to confusion. Maybe ':always' or ':continue' could be used instead? Other than that this seems very simple and easy to understand, I would honestly much prefer this over 'pcase'. > Here are three macros that would be useful as conditions in `cond*' > but can also be used elsewhere. These also seem nice, but they make the ':match' condition almost pointless? AFAIU, the following should be equivalent: (cond* (:bind foo bar (x foobar)) ;; IMO changing t to ':always' would make it very clear what's ;; going on here. (t (match-set `(a ,foo ,bar) x)) ((match-set `(b ,foo ,bar) x) ;; do stuff and exit ) ;; more conditions... ) (cond* (:bind (x foobar)) (:match (`(a ,foo ,bar) x)) (:match (`(b ,foo ,bar) x) ;; do stuff and exit... ) ;; more conditions... ) The only usecase for ':match' (which can't really be fulfilled by the macros) is binding "new" variables (which haven't been bound using ':bind' beforehand), but I think requiring an explicit ':bind' is more clear, and would make it easier to quickly identify local variable names. It could also be better for people new to ELisp eventually, since these macros would be more likely familiar to them already (due to their potential usage outside of 'cond*') when compared to ':match'. And a minor nitpick, I think it would be better to rename 'match-bind' to 'match-let', to mirror other macros like 'if-let' (maybe even change ':bind' to ':let'). Regards, Daniel [-- Attachment #2: Type: text/html, Size: 2013 bytes --] ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: combining cond and let, to replace pcase. 2023-11-24 3:08 ` Daniel Semyonov @ 2023-11-24 3:26 ` Daniel Semyonov 2023-11-25 2:59 ` Richard Stallman 1 sibling, 0 replies; 342+ messages in thread From: Daniel Semyonov @ 2023-11-24 3:26 UTC (permalink / raw) To: emacs-devel, rms Sorry, I sent the last mail as HTML by accident, here's a more readable version of the code: (cond* (:bind foo bar (x foobar)) ;; IMO changing t to ':always' would make it very clear what's ;; going on here. (t (match-set `(a ,foo ,bar) x)) ((match-set `(b ,foo ,bar) x) ;; do stuff and exit ) ;; more conditions... ) (cond* (:bind (x foobar)) (:match (`(a ,foo ,bar) x)) (:match (`(b ,foo ,bar) x) ;; do stuff and exit... ) ;; more conditions... ) ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: combining cond and let, to replace pcase. 2023-11-24 3:08 ` Daniel Semyonov 2023-11-24 3:26 ` Daniel Semyonov @ 2023-11-25 2:59 ` Richard Stallman 1 sibling, 0 replies; 342+ messages in thread From: Richard Stallman @ 2023-11-25 2:59 UTC (permalink / raw) To: Daniel Semyonov; +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. ]]] > And a minor nitpick, I think it would be better to rename 'match-bind' > to 'match-let', to mirror other macros like 'if-let' (maybe even change > ':bind' to ':let'). I am not sure. `if-let' uses a list of variables, similar to (but not identical to) what `let*' uses. `match-bind' uses a patter to control which variables to bind. I think that dissimilar names will make this clearer than similar names would do. -- Dr Richard Stallman (https://stallman.org) Chief GNUisance of the GNU Project (https://gnu.org) Founder, Free Software Foundation (https://fsf.org) Internet Hall-of-Famer (https://internethalloffame.org) ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: combining cond and let, to replace pcase. 2023-11-23 2:58 ` Richard Stallman ` (2 preceding siblings ...) 2023-11-24 3:08 ` Daniel Semyonov @ 2023-11-25 5:11 ` Stefan Monnier via Emacs development discussions. 2023-11-27 3:11 ` Richard Stallman 2023-11-27 3:11 ` Richard Stallman 3 siblings, 2 replies; 342+ messages in thread From: Stefan Monnier via Emacs development discussions. @ 2023-11-25 5:11 UTC (permalink / raw) To: emacs-devel > (cond* [...] > ;; Extracts substructure and binds variables around the rest > ;; of the cond*. > (:match (`(expt ,foo ,bar) x) > do-this-if-it-matched-then-exit...) > ;; Bindings continue in effect. Which bindings? Presumably when we continue the match failed, so `foo` and `bar` don't have any meaningful value to take, AFAICT. IOW we're continuing with the bindings that existed *before* the `:match`, but not with the bindings introduced by the `:match`, right? > ;; Like above but always falls thru to next clause. > (:match (`(expt ,foo ,bar) x)) > ;; Bindings continue in effect. What happens if `(car x)` is not equal to `expt` or if `x` is a string? > (match PATTERN VALUE) > This is a macro. > PATTERN is a backquote form which specifies which parts of > VALUE should be fixed. For instance > (match `(+ (expt nil nil)) (get-complex-list)) > would decompose the result of (get-complex-list) and check > for `+' and `expt' in it. > > PATTERN will not be evaluated, just used as guidance when the > `match' form is macroexpanded. > > If PATTERN includes substitutions, it will virtually perform > those substitutions and compare parts of VALUE against them. > (match `(foo ,foo) x) compares (car x) with `foo' and > compares (cadr x) with the value of foo. > > `match' can also handle vectors and maybe some other kinds of > structures. Don't we have that under the name `equal`? I mean I understand you intend the above `match` to work without memory allocation, but it seems that it's just an optimization. Or am I missing something? > (match-set PATTERN VALUE) > This is a macro. > PATTERN is a backquote form which specifies which parts of > VALUE to match and parts to extract and store. For instance > (match-set `(+ ,y ,z) (get-complex-list)) > would decompose the result of (get-complex-list), verify the car, > and set y and z. > > PATTERN will not be evaluated, just used as guidance when the > `match-set' form is macroexpanded, producing code like this: (defalias 'match-set #'pcase-setq) 🙂 > (match-bind PATTERN VALUE BODY...) > Much like `match-set', except that instead of setting the > variables found in PATTERN, it let-binds them and runs BODY > with those bindings. This one is not a mere `defalias`: (defmacro match-bind (pattern value &rest body) `(pcase-let ((,pattern ,value)) ,@body)) There's a tradeoff here, indeed: sometimes I find the added ((...)) of `pcase-let` rather annoying, but other times the fact that it's a superset of `let` means I get to mix it with normal bindings without increasing the nesting depth, which improves readability. Stefn ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: combining cond and let, to replace pcase. 2023-11-25 5:11 ` Stefan Monnier via Emacs development discussions. @ 2023-11-27 3:11 ` Richard Stallman 2023-11-27 3:11 ` Richard Stallman 1 sibling, 0 replies; 342+ messages in thread From: Richard Stallman @ 2023-11-27 3:11 UTC (permalink / raw) To: Stefan Monnier; +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. ]]] > (defalias 'match-set #'pcase-setq) I'm not defining these constructs based on pcase. I'm defining them to be useful together with cond*. If one of them resembles a part of pcase, that is a coincidence even if not entirely surprising. Maybe we can copy parts of that pcase code with changes, smaller or larger. However, the definitions of these constructs will not depend on pcase. > There's a tradeoff here, indeed: sometimes I find the added ((...)) > of `pcase-let` rather annoying, but other times the fact that it's > a superset of `let` means I get to mix it with normal bindings without > increasing the nesting depth, What does that mean, concretely? I am not sure. I have (not coincidentally) little experience with reading code that uses pcase. -- Dr Richard Stallman (https://stallman.org) Chief GNUisance of the GNU Project (https://gnu.org) Founder, Free Software Foundation (https://fsf.org) Internet Hall-of-Famer (https://internethalloffame.org) ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: combining cond and let, to replace pcase. 2023-11-25 5:11 ` Stefan Monnier via Emacs development discussions. 2023-11-27 3:11 ` Richard Stallman @ 2023-11-27 3:11 ` Richard Stallman 2023-11-27 18:13 ` Manuel Giraud via Emacs development discussions. 1 sibling, 1 reply; 342+ messages in thread From: Richard Stallman @ 2023-11-27 3:11 UTC (permalink / raw) To: Stefan Monnier; +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. ]]] > > ;; Extracts substructure and binds variables around the rest > > ;; of the cond*. > > (:match (`(expt ,foo ,bar) x) > > do-this-if-it-matched-then-exit...) > > ;; Bindings continue in effect. > Which bindings? Presumably when we continue the match failed, so `foo` > and `bar` don't have any meaningful value to take, AFAICT. That is a good question. I've concluded that, for this form of the clause, which will exit if it executes the body of the clause, the bindings should be made only for that clause. > > ;; Like above but always falls thru to next clause. > > (:match (`(expt ,foo ,bar) x)) > > ;; Bindings continue in effect. > What happens if `(car x)` is not equal to `expt` or if `x` is a string? This form of clause should bind the variables unconditionally. If matching provides a value to give a certain variable, the variable should get that value. Otherwise it should be bound to nil. This way, which variablss are bound at any point will not depend on the valus of the data. -- Dr Richard Stallman (https://stallman.org) Chief GNUisance of the GNU Project (https://gnu.org) Founder, Free Software Foundation (https://fsf.org) Internet Hall-of-Famer (https://internethalloffame.org) ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: combining cond and let, to replace pcase. 2023-11-27 3:11 ` Richard Stallman @ 2023-11-27 18:13 ` Manuel Giraud via Emacs development discussions. 2023-11-27 18:49 ` Yuri Khan 2023-11-29 3:40 ` Richard Stallman 0 siblings, 2 replies; 342+ messages in thread From: Manuel Giraud via Emacs development discussions. @ 2023-11-27 18:13 UTC (permalink / raw) To: Richard Stallman; +Cc: Stefan Monnier, emacs-devel Richard Stallman <rms@gnu.org> writes: [...] > > > ;; Like above but always falls thru to next clause. > > > (:match (`(expt ,foo ,bar) x)) > > > ;; Bindings continue in effect. > > > What happens if `(car x)` is not equal to `expt` or if `x` is a string? > > This form of clause should bind the variables unconditionally. If > matching provides a value to give a certain variable, the variable > should get that value. Otherwise it should be bound to nil. So these form of :match clause would bind variables even though it did not match? That seems counter-intuitive to me. -- Manuel Giraud ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: combining cond and let, to replace pcase. 2023-11-27 18:13 ` Manuel Giraud via Emacs development discussions. @ 2023-11-27 18:49 ` Yuri Khan 2023-11-27 23:12 ` Stefan Monnier 2023-11-29 3:41 ` Richard Stallman 2023-11-29 3:40 ` Richard Stallman 1 sibling, 2 replies; 342+ messages in thread From: Yuri Khan @ 2023-11-27 18:49 UTC (permalink / raw) To: Manuel Giraud; +Cc: Richard Stallman, Stefan Monnier, emacs-devel On Tue, 28 Nov 2023 at 01:14, Manuel Giraud via Emacs development discussions. <emacs-devel@gnu.org> wrote: > > Richard Stallman <rms@gnu.org> writes: > > [...] > > > > > ;; Like above but always falls thru to next clause. > > > > (:match (`(expt ,foo ,bar) x)) > > > > ;; Bindings continue in effect. > > > > > What happens if `(car x)` is not equal to `expt` or if `x` is a string? > > > > This form of clause should bind the variables unconditionally. If > > matching provides a value to give a certain variable, the variable > > should get that value. Otherwise it should be bound to nil. > > So these form of :match clause would bind variables even though it did > not match? That seems counter-intuitive to me. Not only that, it’s just plain wrong. (pcase 42 (`(,x . ,y) (format "%s:%s" x y)) (_ "not a cons cell")) → not a cons cell If I understand Richard correctly, the corresponding :match will unconditionally attempt to bind x to (car 42) and y to (cdr 42), which results in a run-time error. The correct pattern matching behavior is to first check that the expression being matched is indeed a cons, and only if so, destructure it into its car and cdr. Similarly, attempting to match a two-element list (expt 2) with a three-element pattern (expt ,x ,y) is nonsensical and it’s not helpful to bind y to (caddr '(expt 2)) == nil. Same if the list and pattern have the same length but literal elements do not match, e.g. '(+ 42 73) against '(expt ,base ,exponent). ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: combining cond and let, to replace pcase. 2023-11-27 18:49 ` Yuri Khan @ 2023-11-27 23:12 ` Stefan Monnier 2023-11-29 3:41 ` Richard Stallman 1 sibling, 0 replies; 342+ messages in thread From: Stefan Monnier @ 2023-11-27 23:12 UTC (permalink / raw) To: Yuri Khan; +Cc: Manuel Giraud, Richard Stallman, emacs-devel >> > > > ;; Like above but always falls thru to next clause. >> > > > (:match (`(expt ,foo ,bar) x)) >> > > > ;; Bindings continue in effect. >> > >> > > What happens if `(car x)` is not equal to `expt` or if `x` is a string? >> > >> > This form of clause should bind the variables unconditionally. If >> > matching provides a value to give a certain variable, the variable >> > should get that value. Otherwise it should be bound to nil. >> >> So these form of :match clause would bind variables even though it did >> not match? That seems counter-intuitive to me. > > Not only that, it’s just plain wrong. > > (pcase 42 > (`(,x . ,y) (format "%s:%s" x y)) > (_ "not a cons cell")) > → not a cons cell But those above `:match` is not a test, it's a destructuring operation only, so it's more like (pcase-let ((`(,x . ,y) 42)) ...) > If I understand Richard correctly, the corresponding :match will > unconditionally attempt to bind x to (car 42) and y to (cdr 42), which > results in a run-time error. `pcase` uses `car-safe` and `cdr-safe` tho it was not to avoid such errors (it was to allow those operations to be optimized away if the result is not used). `:match` could similarly use `car-safe` and `cdr-safe`. Stefan ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: combining cond and let, to replace pcase. 2023-11-27 18:49 ` Yuri Khan 2023-11-27 23:12 ` Stefan Monnier @ 2023-11-29 3:41 ` Richard Stallman 1 sibling, 0 replies; 342+ messages in thread From: Richard Stallman @ 2023-11-29 3:41 UTC (permalink / raw) To: Yuri Khan; +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. ]]] > (pcase 42 > (`(,x . ,y) (format "%s:%s" x y)) > (_ "not a cons cell")) > → not a cons cell > If I understand Richard correctly, Alas I think we are miscommunicating. the corresponding :match will > unconditionally attempt to bind x to (car 42) and y to (cdr 42), which > results in a run-time error. pcase has one kind of matching clause. cond* has two kinds. It is possible that this distinction is not clear enough in the text I posted. In this version, each clause exits if it contains more than one element (after the possible keyword), and falls through unconditionally if it has only one element (after the possible keyword). For the second kind, I think this addresses your concern. (cond* ;; Same as a clause in `cond', (CONDITION DO-THIS-IF-TRUE-THEN-EXIT...) ;; Execute FORM and ignore its value. (FORM) ;; Variables to bind, as in let (:bind ((x foobar) y z (foo 5) a)) ;; Bindings continue in effect. ;; Extracts substructure and binds variables around the rest ;; of the cond*. (:match (`(expt ,foo ,bar) x) DO-THIS-IF-IT-MATCHED-THEN-EXIT...) ;; Bindings no longer in effect. ;; Like above but always falls thru to next clause. (:match (`(expt ,foo ,bar) x)) ;; Bindings continue in effect. ;; All the variables mentioned in the pattern ;; are bound whether match succeeds or not. ;; If a value can be determined from an incomplete match, ;; the variable gets that value. ) -- Dr Richard Stallman (https://stallman.org) Chief GNUisance of the GNU Project (https://gnu.org) Founder, Free Software Foundation (https://fsf.org) Internet Hall-of-Famer (https://internethalloffame.org) ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: combining cond and let, to replace pcase. 2023-11-27 18:13 ` Manuel Giraud via Emacs development discussions. 2023-11-27 18:49 ` Yuri Khan @ 2023-11-29 3:40 ` Richard Stallman 1 sibling, 0 replies; 342+ messages in thread From: Richard Stallman @ 2023-11-29 3:40 UTC (permalink / raw) To: Manuel Giraud; +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. ]]] > > This form of clause should bind the variables unconditionally. If > > matching provides a value to give a certain variable, the variable > > should get that value. Otherwise it should be bound to nil. > So these form of :match clause would bind variables even though it did > not match? That seems counter-intuitive to me. Since it makes the bindings unconditionally, it has to make the same bindings whether matching fully succeeds or not. I don't see any other alternative -- what could there be? -- Dr Richard Stallman (https://stallman.org) Chief GNUisance of the GNU Project (https://gnu.org) Founder, Free Software Foundation (https://fsf.org) Internet Hall-of-Famer (https://internethalloffame.org) ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-11-16 3:04 Instead of pcase Richard Stallman ` (2 preceding siblings ...) 2023-11-16 15:20 ` Spencer Baugh @ 2023-11-16 18:11 ` Emanuel Berg 2023-11-16 19:26 ` Eli Zaretskii 2023-11-16 18:22 ` Jim Porter 4 siblings, 1 reply; 342+ messages in thread From: Emanuel Berg @ 2023-11-16 18:11 UTC (permalink / raw) To: emacs-devel Richard Stallman wrote: > `pcase' is a big and unnecessary complication on Emacs Lisp. > I think its presence worse overall. > > One can easily think of `pcase' as "just another feature", > like each of the thousands of other predefined functions and > macros in Emacs Lisp. But that picture is incorrect for > `pcase', because it does not count the cost of `pcase' > in complexity. There are, according to the below code [last], 13 011 hits for cl-lib in the Emacs source. For pcase, there are 2168. So there is no kicking that out either. But regardless of whatever, here is the use of pcase, 1525 pcase 189 pcase-let 137 pcase-dolist 95 pcase-let* 43 pcase-lambda 35 pcase-exhaustive 27 pcase-defmacro 26 pcase-tests 20 pcase-setq 19 pcase-macroexpander 10 pcase-vars 7 pcase-patterns 6 pcase-expand 5 pcase-transform 5 pcase-mutually 4 pcase-bindings 3 pcase-memoize 3 pcase-compile 2 pcase-used 2 pcase-slot 2 pcase-map 1 pcase-matches 1 pcase-default 1 pcase-bug Total: 2168 > Those of you who are fans of `pcase' may not recognize the > cost it imposes on the Emacs Lisp language. You paid that > cost already, perhaps a few years ago, and perhaps you enjoy > each new language construct you learn. Perhaps, for you, the > more complexity of features to be learned, the better. Yes, I think a lot of people will say pcase is interesting. But a lot of people will say it is very useful as well, and they will disagree it places any kind of burden on anything. In the case of pcase actually, with its pattern matching feature, I think a lot of people will say, if anything, it makes the code more light. #! /bin/zsh # # this file: # https://dataswamp.org/~incal/conf/.zsh/emacs clp () { cd ~/src/emacs local re='pcase|pcase-[a-z0-9*]+' grep -E -h -o -w $re **/*.el | sort | uniq -c | sort -b -n -r echo 'Total:' $(grep -E -h -o -w $re **/*.el | wc -l) } cle () { cd ~/src/emacs local re='cl-[a-z0-9*]+' grep -E -h -o -w $re **/*.el | sort | uniq -c | sort -b -n -r | head -n 100 echo 'Total:' $(grep -E -h -o -w $re **/*.el | wc -l) } GNU Emacs 30.0.50 (build 1, x86_64-pc-linux-gnu, cairo version 1.16.0) of 2023-11-01 [commit 8eb9b82ce58a8323af21f52625a401e19e279a9c] -- underground experts united https://dataswamp.org/~incal ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-11-16 18:11 ` Instead of pcase Emanuel Berg @ 2023-11-16 19:26 ` Eli Zaretskii 2023-11-16 22:16 ` Emanuel Berg 0 siblings, 1 reply; 342+ messages in thread From: Eli Zaretskii @ 2023-11-16 19:26 UTC (permalink / raw) To: Emanuel Berg; +Cc: emacs-devel > From: Emanuel Berg <incal@dataswamp.org> > Date: Thu, 16 Nov 2023 19:11:52 +0100 > > There are, according to the below code [last], 13 011 hits for > cl-lib in the Emacs source. For pcase, there are 2168. > So there is no kicking that out either. Nonsense. We already had such large replacements, and did that without any trouble, though gradually. Cases in point: setq-local, defvar-keymap, and others. So if we have an alternative that we like and is easy to use, we can decide to replace pcase with it, and then do it, one case at a time. ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-11-16 19:26 ` Eli Zaretskii @ 2023-11-16 22:16 ` Emanuel Berg 2023-11-17 7:30 ` Eli Zaretskii 0 siblings, 1 reply; 342+ messages in thread From: Emanuel Berg @ 2023-11-16 22:16 UTC (permalink / raw) To: emacs-devel Eli Zaretskii wrote: >> There are, according to the below code [last], 13 011 hits >> for cl-lib in the Emacs source. For pcase, there are 2168. >> So there is no kicking that out either. > > Nonsense. We already had such large replacements, and did > that without any trouble, though gradually. Cases in point: > setq-local, defvar-keymap, and others. > > So if we have an alternative that we like and is easy to > use, we can decide to replace pcase with it, and then do it, > one case at a time. We don't have alternatives that are better than cl-lib and pcase, and their widespread use shows it. This whole discussion is just disrespectful, polarizing and alienating anti-cl-lib and now anti-pcase for no reason and with no alternatives. It is completely unrealistic to think anyone will write replacements for cl-lib and pcase that are so superior, yet do not contribute to complexity, that we can fully rely on them instead. But if that is what you are hoping for, why don't we revisit this discussion if and when that happens? -- underground experts united https://dataswamp.org/~incal ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-11-16 22:16 ` Emanuel Berg @ 2023-11-17 7:30 ` Eli Zaretskii 2023-11-17 8:09 ` Emanuel Berg 0 siblings, 1 reply; 342+ messages in thread From: Eli Zaretskii @ 2023-11-17 7:30 UTC (permalink / raw) To: Emanuel Berg; +Cc: emacs-devel > From: Emanuel Berg <incal@dataswamp.org> > Date: Thu, 16 Nov 2023 23:16:26 +0100 > > Eli Zaretskii wrote: > > >> There are, according to the below code [last], 13 011 hits > >> for cl-lib in the Emacs source. For pcase, there are 2168. > >> So there is no kicking that out either. > > > > Nonsense. We already had such large replacements, and did > > that without any trouble, though gradually. Cases in point: > > setq-local, defvar-keymap, and others. > > > > So if we have an alternative that we like and is easy to > > use, we can decide to replace pcase with it, and then do it, > > one case at a time. > > We don't have alternatives that are better than cl-lib and > pcase, and their widespread use shows it. First, I was talking about pcase, not the rest. Second, I said "IF we have an alternatives that we like". It goes without saying that we don't have such an alternative for pcase at this time, and maybe never will. My point was a simple one: IF we have an alternative that we like, THEN we can decide to make these replacements, and will have no problems whatsoever doing so, as we have done in other cases. IOW, I was only objecting to your claim that such a replacement is impossible due to the sheer quantity of pcase uses in the tree, not to any other arguments in this thread. > This whole discussion is just disrespectful, polarizing and > alienating anti-cl-lib and now anti-pcase for no reason and > with no alternatives. Nonsense. There's no disrespect in discussing the various advanced ELisp facilities and their impact on our coding conventions. > It is completely unrealistic to think anyone will write > replacements for cl-lib and pcase If so, you have nothing to worry about: the above is just an academic discussion that will never have any practical effect. So please relax and cool down. > But if that is what you are hoping for, why don't we revisit > this discussion if and when that happens? The only thing I'm hoping for is for Emacs to get better and continue its development. If that is wrong, maybe you want to step up and replace me as Emacs maintainer? ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-11-17 7:30 ` Eli Zaretskii @ 2023-11-17 8:09 ` Emanuel Berg 2023-11-17 12:16 ` Eli Zaretskii 0 siblings, 1 reply; 342+ messages in thread From: Emanuel Berg @ 2023-11-17 8:09 UTC (permalink / raw) To: emacs-devel Eli Zaretskii wrote: >> But if that is what you are hoping for, why don't we >> revisit this discussion if and when that happens? > > The only thing I'm hoping for is for Emacs to get better and > continue its development. If that is wrong, maybe you want > to step up and replace me as Emacs maintainer? Pro hint: Don't start this kind of campaigns against libraries your own software is relying on, only for vague reasons of style and complexity, and with no alternative in sight. No one is going to react positively to that and it won't help Emacs development, as it only creates bad blood in the community for no reason. -- underground experts united https://dataswamp.org/~incal ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-11-17 8:09 ` Emanuel Berg @ 2023-11-17 12:16 ` Eli Zaretskii 2023-11-18 6:26 ` Emanuel Berg 0 siblings, 1 reply; 342+ messages in thread From: Eli Zaretskii @ 2023-11-17 12:16 UTC (permalink / raw) To: Emanuel Berg; +Cc: emacs-devel > From: Emanuel Berg <incal@dataswamp.org> > Date: Fri, 17 Nov 2023 09:09:46 +0100 > > Eli Zaretskii wrote: > > >> But if that is what you are hoping for, why don't we > >> revisit this discussion if and when that happens? > > > > The only thing I'm hoping for is for Emacs to get better and > > continue its development. If that is wrong, maybe you want > > to step up and replace me as Emacs maintainer? > > Pro hint: Don't start this kind of campaigns against libraries > your own software is relying on, only for vague reasons of > style and complexity, and with no alternative in sight. Reality check: I didn't start this thread. My personal contributions to it are quite modest: mainly correcting inaccuracies and mistakes in messages posted to others, so as to avoid tricking people into incorrect conclusions due to these inaccuracies. > No one is going to react positively to that and it won't help Emacs > development, as it only creates bad blood in the community for no > reason. If you are actually reading the messages in this thread, you will realize that your assertions are false. Some people here actually agree that pcase presents a difficulty (others disagree), and I spotted no bad blood here from people who voiced their opinions. So I think you see problems where there are none. ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-11-17 12:16 ` Eli Zaretskii @ 2023-11-18 6:26 ` Emanuel Berg 2023-11-18 7:21 ` Po Lu 0 siblings, 1 reply; 342+ messages in thread From: Emanuel Berg @ 2023-11-18 6:26 UTC (permalink / raw) To: emacs-devel Eli Zaretskii wrote: > If you are actually reading the messages in this thread, you > will realize that your assertions are false. Some people > here actually agree that pcase presents a difficulty (others > disagree), and I spotted no bad blood here from people who > voiced their opinions. So I think you see problems where > there are none. Bottom line, not using advanced libraries and instead rely on some basic building block Elisp is a total bogus idea, sorry. -- underground experts united https://dataswamp.org/~incal ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-11-18 6:26 ` Emanuel Berg @ 2023-11-18 7:21 ` Po Lu 2023-11-18 7:41 ` Eli Zaretskii 0 siblings, 1 reply; 342+ messages in thread From: Po Lu @ 2023-11-18 7:21 UTC (permalink / raw) To: emacs-devel Emanuel Berg <incal@dataswamp.org> writes: > Bottom line, not using advanced libraries and instead rely on > some basic building block Elisp is a total bogus idea, sorry. That's merely your inference, so long as "advanced libraries" refers to pcase. I don't expect anything short of obstinately maintaining that it's true from you, but bear in mind that many others disagree, and, above all, the subject at hand is the design of a construct that enables pcase to be replaced without forsaking conciseness. A new construct. Not constraining ourselves to "some basic building block Elisp." With these conversations the game is frequently not worth the candle, because of bitter but inane comments like yours. ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-11-18 7:21 ` Po Lu @ 2023-11-18 7:41 ` Eli Zaretskii 0 siblings, 0 replies; 342+ messages in thread From: Eli Zaretskii @ 2023-11-18 7:41 UTC (permalink / raw) To: Po Lu; +Cc: emacs-devel > From: Po Lu <luangruo@yahoo.com> > Date: Sat, 18 Nov 2023 15:21:09 +0800 > > Emanuel Berg <incal@dataswamp.org> writes: > > > Bottom line, not using advanced libraries and instead rely on > > some basic building block Elisp is a total bogus idea, sorry. > > That's merely your inference, so long as "advanced libraries" refers to > pcase. I don't expect anything short of obstinately maintaining that > it's true from you, but bear in mind that many others disagree, and, > above all, the subject at hand is the design of a construct that enables > pcase to be replaced without forsaking conciseness. A new construct. > Not constraining ourselves to "some basic building block Elisp." > > With these conversations the game is frequently not worth the candle, > because of bitter but inane comments like yours. Po Lu, if you don't have anything constructive or useful to say about someone else's comments, except that you don't like them, please consider saying nothing at all. There's no need to rebuke each and every opinion contrary to yours, just to say once again that you disagree. Your opinions in this matter were voiced and noted, so no need to reiterate them, let alone in a rude way that includes personal attacks. Let's please try to lower the noise level here, not raise it. ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-11-16 3:04 Instead of pcase Richard Stallman ` (3 preceding siblings ...) 2023-11-16 18:11 ` Instead of pcase Emanuel Berg @ 2023-11-16 18:22 ` Jim Porter 2023-11-16 22:55 ` Emanuel Berg 2023-11-17 5:36 ` Po Lu 4 siblings, 2 replies; 342+ messages in thread From: Jim Porter @ 2023-11-16 18:22 UTC (permalink / raw) To: rms, emacs-devel On 11/15/2023 7:04 PM, Richard Stallman wrote: > Those of you who are fans of `pcase' may not recognize the cost it > imposes on the Emacs Lisp language. You paid that cost already, > perhaps a few years ago, and perhaps you enjoy each new language > construct you learn. Perhaps, for you, the more complexity of > features to be learned, the better. I'd like to offer a slightly different perspective here, as someone who only fairly recently became comfortable with Lisp (of any variety). I've used Emacs for a long time, but I found Lisp completely incomprehensible until just a couple of years ago. While getting started with Lisp isn't terribly complex, it's still quite a bit to learn, and it took a period where I was between jobs before I could dedicate the time I needed to get comfortable with writing Lisp. I encountered a lot of hurdles with Lisp along the way. The first one was extremely basic: I needed to get used to the style of indentation and develop an intuition for *reading* Lisp code, rather than slowly and laboriously translating it into a form I could understand more easily. The next hurdle was quoting. I still remember that one of my first patches to Emacs needed someone else to fix it in a followup because I messed up the quoting. The issues of quoting came up repeatedly for me as I encountered progressively more complex examples of quoting. This is where we get to 'pcase'. I'll agree that the upper limit on complex quoted forms in 'pcase' is very high. I've used 'pcase-defmacro' in one nontrivial case, and I found it very difficult to get right. *However*, 99% of the 'pcase' instances I've written or encountered are pretty simple for me to understand. Once I learned about 'pred' matcher and how to destructure via backquote patterns, it was mostly smooth sailing for me. Now, while I'd certainly say that I enjoy learning overall (or else I likely wouldn't have learned Lisp in the first place), I don't consider the complexity of a feature to be a positive. Instead, I prefer features that give me more power or better expressiveness. Often, that expressiveness comes at the cost of complexity under the hood (e.g. 'pcase-defmacro'), but that's not a positive to me in and of itself. Overall, 'pcase' is one of the parts of Elisp that I appreciate the most. Learning the basics of its mini-language took just a bit of reading. In addition to the docs, seeing examples helped: the first few times were a bit tricky to read, but I could usually understand what was happening, even if I couldn't (at the time) write my own 'pcase' code that worked. However, once I got the basics down, I quickly saw the benefits: I could combine a handful of basic tools to do bigger things, meaning I only need to know a small set of facts before I can tackle a complex task. This, to me, is the mark of a good language feature: I can compose it in ways that *multiply* the power of each (small, easy) bit. At a higher level, I'd say it's worth considering the audience we want to focus on. For veteran (Emacs) Lisp programmers, new additions like 'pcase' can increase the difficulty of reading new Elisp code: your prior mastery of the language isn't any good when you hit that "(pcase". However, many programmers today don't know Lisp, of any variety. For people like that, learning to contribute to Emacs means learning from the very beginning. Having gone through this, most of 'pcase' was very easy for me to pick up, and other parts of Elisp were much more challenging (it took me a long time to get comfortable with writing macros, which is also probably one of the reasons I found 'pcase-defmacro' to be so tricky). That said, it's true that every feature we add to Elisp increases the overall complexity because now there are more things to learn. However, in my opinion, the expressiveness of 'pcase' far outweighs this cost. ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-11-16 18:22 ` Jim Porter @ 2023-11-16 22:55 ` Emanuel Berg 2023-11-17 5:36 ` Po Lu 1 sibling, 0 replies; 342+ messages in thread From: Emanuel Berg @ 2023-11-16 22:55 UTC (permalink / raw) To: emacs-devel Jim Porter wrote: >> Those of you who are fans of `pcase' may not recognize the >> cost it imposes on the Emacs Lisp language. You paid that >> cost already, perhaps a few years ago, and perhaps you >> enjoy each new language construct you learn. Perhaps, for >> you, the more complexity of features to be learned, >> the better. > > I'd like to offer a slightly different perspective here, as > someone who only fairly recently became comfortable with > Lisp (of any variety). I've used Emacs for a long time, but > I found Lisp completely incomprehensible until just a couple > of years ago. While getting started with Lisp isn't terribly > complex, it's still quite a bit to learn, and it took > a period where I was between jobs before I could dedicate > the time I needed to get comfortable with writing Lisp. > > I encountered a lot of hurdles with Lisp along the way. > The first one was extremely basic: I needed to get used to > the style of indentation and develop an intuition for > *reading* Lisp code, rather than slowly and laboriously > translating it into a form I could understand more easily. > > The next hurdle was quoting. I still remember that one of my > first patches to Emacs needed someone else to fix it in > a followup because I messed up the quoting. The issues of > quoting came up repeatedly for me as I encountered > progressively more complex examples of quoting. > > This is where we get to 'pcase'. I'll agree that the upper > limit on complex quoted forms in 'pcase' is very high. > I've used 'pcase-defmacro' in one nontrivial case, and > I found it very difficult to get right. > > *However*, 99% of the 'pcase' instances I've written or > encountered are pretty simple for me to understand. > Once I learned about 'pred' matcher and how to destructure > via backquote patterns, it was mostly smooth sailing for me. > > Now, while I'd certainly say that I enjoy learning overall > (or else I likely wouldn't have learned Lisp in the first > place), I don't consider the complexity of a feature to be > a positive. Instead, I prefer features that give me more > power or better expressiveness. Often, that expressiveness > comes at the cost of complexity under the hood (e.g. > 'pcase-defmacro'), but that's not a positive to me in and > of itself. > > Overall, 'pcase' is one of the parts of Elisp that > I appreciate the most. Learning the basics of its > mini-language took just a bit of reading. In addition to the > docs, seeing examples helped: the first few times were a bit > tricky to read, but I could usually understand what was > happening, even if I couldn't (at the time) write my own > 'pcase' code that worked. However, once I got the basics > down, I quickly saw the benefits: I could combine a handful > of basic tools to do bigger things, meaning I only need to > know a small set of facts before I can tackle a complex > task. This, to me, is the mark of a good language feature: > I can compose it in ways that *multiply* the power of each > (small, easy) bit. > > At a higher level, I'd say it's worth considering the > audience we want to focus on. For veteran (Emacs) Lisp > programmers, new additions like 'pcase' can increase the > difficulty of reading new Elisp code: your prior mastery of > the language isn't any good when you hit that "(pcase". > However, many programmers today don't know Lisp, of any > variety. For people like that, learning to contribute to > Emacs means learning from the very beginning. Having gone > through this, most of 'pcase' was very easy for me to pick > up, and other parts of Elisp were much more challenging (it > took me a long time to get comfortable with writing macros, > which is also probably one of the reasons I found > 'pcase-defmacro' to be so tricky). > > That said, it's true that every feature we add to Elisp > increases the overall complexity because now there are more > things to learn. However, in my opinion, the expressiveness > of 'pcase' far outweighs this cost. Well said! Thank you for this post. I agree, and I enjoyed reading it. -- underground experts united https://dataswamp.org/~incal ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-11-16 18:22 ` Jim Porter 2023-11-16 22:55 ` Emanuel Berg @ 2023-11-17 5:36 ` Po Lu 2023-11-19 11:48 ` Michael Heerdegen 1 sibling, 1 reply; 342+ messages in thread From: Po Lu @ 2023-11-17 5:36 UTC (permalink / raw) To: Jim Porter; +Cc: rms, emacs-devel Jim Porter <jporterbugs@gmail.com> writes: > At a higher level, I'd say it's worth considering the audience we want > to focus on. For veteran (Emacs) Lisp programmers, new additions like > 'pcase' can increase the difficulty of reading new Elisp code: your > prior mastery of the language isn't any good when you hit that > "(pcase". However, many programmers today don't know Lisp, of any > variety. For people like that, learning to contribute to Emacs means > learning from the very beginning. That's as may be, but pcase remains a hurdle all Emacs Lisp programmers will have to surmount, if they are to understand a program which employs it. Much as the linguistically inclined enjoy acquiring an abstruse language, so certain programmers may relish the occasion to acquire a new and intricate construct. Nevertheless, and your singular experience notwithstanding, other programmers are loath to devote their time to such monotonous pursuits--whether they are learning the language from a blank slate or with a solid basis in the form of proficiency in other dialects of Lisp--and they are a sizable portion of our userbase as well. All these programmers share a common ground that excludes pcase and presently destructuring variable binding, so I don't think there are many who would gainsay that the introduction of a simpler construct to the same end is a win-win. Now for some quibbling: there is no "audience" for whom our design choices are made; rather a corpus of users who are enjoined to read and write the same language. It is to everyone's advantage if the users with such zeal as to memorize and enjoy these ivory tower delights exert themselves slightly, in order for others to read their code also. ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-11-17 5:36 ` Po Lu @ 2023-11-19 11:48 ` Michael Heerdegen 2023-11-19 12:50 ` Eli Zaretskii 2023-11-19 14:29 ` Po Lu 0 siblings, 2 replies; 342+ messages in thread From: Michael Heerdegen @ 2023-11-19 11:48 UTC (permalink / raw) To: Po Lu; +Cc: Jim Porter, rms, emacs-devel Po Lu <luangruo@yahoo.com> writes: > Much as the linguistically inclined enjoy acquiring an abstruse > language, so certain programmers may relish the occasion to acquire a > new and intricate construct. Nevertheless, and your singular > experience notwithstanding "abstruse language" - "singular experience" ...(?) - sorry, are we people having understood pcase in few minutes some kind of aliens, compared to the "normal people"? Do we not count? Because we are not loud and angry and outraged? For you it seems to be a fact that `pcase' is something complicated and most people don't like it. Eh - no? Pardon - but when I was able to learn `pcase' in one minute from a few lines of the original docstring, there must be something missing in that picture. I don't know why it is harder for you to learn it. But something is not a fact because you feel like it would be. What I don't like here in this discussion is that some people are not willing to accept that other people make different experiences with the same things. This is the death to any constructive discussion. It is impossible to find a good solution for everybody under such circumstances. And note that you are weakening your position when discussing like this. I can't take someone seriously when I see that s?he is not able to think along the viewpoints of others. Interesting would be to hear concrete arguments, but we heard nearly none. "I'm angry" is not an argument. Michael. ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-11-19 11:48 ` Michael Heerdegen @ 2023-11-19 12:50 ` Eli Zaretskii 2023-11-19 14:05 ` Dmitry Gutov 2023-11-19 14:14 ` Michael Heerdegen 2023-11-19 14:29 ` Po Lu 1 sibling, 2 replies; 342+ messages in thread From: Eli Zaretskii @ 2023-11-19 12:50 UTC (permalink / raw) To: Michael Heerdegen; +Cc: luangruo, jporterbugs, rms, emacs-devel > From: Michael Heerdegen <michael_heerdegen@web.de> > Cc: Jim Porter <jporterbugs@gmail.com>, rms@gnu.org, emacs-devel@gnu.org > Date: Sun, 19 Nov 2023 12:48:08 +0100 > > What I don't like here in this discussion is that some people are not > willing to accept that other people make different experiences with the > same things. This goes both ways, you know. ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-11-19 12:50 ` Eli Zaretskii @ 2023-11-19 14:05 ` Dmitry Gutov 2023-11-19 14:41 ` Po Lu 2023-11-19 14:52 ` Eli Zaretskii 2023-11-19 14:14 ` Michael Heerdegen 1 sibling, 2 replies; 342+ messages in thread From: Dmitry Gutov @ 2023-11-19 14:05 UTC (permalink / raw) To: Eli Zaretskii, Michael Heerdegen; +Cc: luangruo, jporterbugs, rms, emacs-devel On 19/11/2023 14:50, Eli Zaretskii wrote: >> From: Michael Heerdegen<michael_heerdegen@web.de> >> Cc: Jim Porter<jporterbugs@gmail.com>,rms@gnu.org,emacs-devel@gnu.org >> Date: Sun, 19 Nov 2023 12:48:08 +0100 >> >> What I don't like here in this discussion is that some people are not >> willing to accept that other people make different experiences with the >> same things. > This goes both ways, you know. The "other side" doesn't create threads with angry comments about the developers with opposing views writing lower-level verbose code (choo-choo trains, Joao called that), with calls to prohibit such practices. OTOH, enacting a ban on particular abstractions will just about guarantee that certain kinds of features will not be implemented. ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-11-19 14:05 ` Dmitry Gutov @ 2023-11-19 14:41 ` Po Lu 2023-11-19 14:44 ` Dmitry Gutov 2023-11-19 14:52 ` Eli Zaretskii 1 sibling, 1 reply; 342+ messages in thread From: Po Lu @ 2023-11-19 14:41 UTC (permalink / raw) To: Dmitry Gutov Cc: Eli Zaretskii, Michael Heerdegen, jporterbugs, rms, emacs-devel Dmitry Gutov <dmitry@gutov.dev> writes: > OTOH, enacting a ban on particular abstractions will just about > guarantee that certain kinds of features will not be implemented. Not true. Maybe some individuals will be thus disinclined to, but even that's up for debate. ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-11-19 14:41 ` Po Lu @ 2023-11-19 14:44 ` Dmitry Gutov 0 siblings, 0 replies; 342+ messages in thread From: Dmitry Gutov @ 2023-11-19 14:44 UTC (permalink / raw) To: Po Lu; +Cc: Eli Zaretskii, Michael Heerdegen, jporterbugs, rms, emacs-devel On 19/11/2023 16:41, Po Lu wrote: > Dmitry Gutov<dmitry@gutov.dev> writes: > >> OTOH, enacting a ban on particular abstractions will just about >> guarantee that certain kinds of features will not be implemented. > Not true. Maybe some individuals will be thus disinclined to, but even > that's up for debate. I'm speaking from experience. And it's not an accident that GUI code, for example, is abstraction-heavy pretty much everywhere. ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-11-19 14:05 ` Dmitry Gutov 2023-11-19 14:41 ` Po Lu @ 2023-11-19 14:52 ` Eli Zaretskii 2023-11-19 14:58 ` Dmitry Gutov 1 sibling, 1 reply; 342+ messages in thread From: Eli Zaretskii @ 2023-11-19 14:52 UTC (permalink / raw) To: Dmitry Gutov; +Cc: michael_heerdegen, luangruo, jporterbugs, rms, emacs-devel > Date: Sun, 19 Nov 2023 16:05:28 +0200 > Cc: luangruo@yahoo.com, jporterbugs@gmail.com, rms@gnu.org, > emacs-devel@gnu.org > From: Dmitry Gutov <dmitry@gutov.dev> > > On 19/11/2023 14:50, Eli Zaretskii wrote: > >> From: Michael Heerdegen<michael_heerdegen@web.de> > >> Cc: Jim Porter<jporterbugs@gmail.com>,rms@gnu.org,emacs-devel@gnu.org > >> Date: Sun, 19 Nov 2023 12:48:08 +0100 > >> > >> What I don't like here in this discussion is that some people are not > >> willing to accept that other people make different experiences with the > >> same things. > > This goes both ways, you know. > > The "other side" doesn't create threads with angry comments about the > developers with opposing views writing lower-level verbose code > (choo-choo trains, Joao called that), with calls to prohibit such practices. I meant this very thread. The very previous message, actually. > OTOH, enacting a ban on particular abstractions will just about > guarantee that certain kinds of features will not be implemented. That's a strawman: no one of those who set policies here suggested any bans. One should be able to post opinions for and against certain coding styles without being accuse in mortal sins. ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-11-19 14:52 ` Eli Zaretskii @ 2023-11-19 14:58 ` Dmitry Gutov 2023-11-19 15:14 ` Eli Zaretskii 2023-11-21 2:43 ` Richard Stallman 0 siblings, 2 replies; 342+ messages in thread From: Dmitry Gutov @ 2023-11-19 14:58 UTC (permalink / raw) To: Eli Zaretskii; +Cc: michael_heerdegen, luangruo, jporterbugs, rms, emacs-devel On 19/11/2023 16:52, Eli Zaretskii wrote: >> Date: Sun, 19 Nov 2023 16:05:28 +0200 >> Cc:luangruo@yahoo.com,jporterbugs@gmail.com,rms@gnu.org, >> emacs-devel@gnu.org >> From: Dmitry Gutov<dmitry@gutov.dev> >> >> On 19/11/2023 14:50, Eli Zaretskii wrote: >>>> From: Michael Heerdegen<michael_heerdegen@web.de> >>>> Cc: Jim Porter<jporterbugs@gmail.com>,rms@gnu.org,emacs-devel@gnu.org >>>> Date: Sun, 19 Nov 2023 12:48:08 +0100 >>>> >>>> What I don't like here in this discussion is that some people are not >>>> willing to accept that other people make different experiences with the >>>> same things. >>> This goes both ways, you know. >> The "other side" doesn't create threads with angry comments about the >> developers with opposing views writing lower-level verbose code >> (choo-choo trains, Joao called that), with calls to prohibit such practices. > I meant this very thread. The very previous message, actually. I don't see calls for prohibiting those implementation styles, in the previous messages, or anywhere. It would be impractical anyway. >> OTOH, enacting a ban on particular abstractions will just about >> guarantee that certain kinds of features will not be implemented. > That's a strawman: no one of those who set policies here suggested any > bans. One should be able to post opinions for and against certain > coding styles without being accuse in mortal sins. No one is arguing about whether people are allowed to post opinions. There have been a few calls for working toward dropping pcase or cl-lib from the Emacs core, however. ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-11-19 14:58 ` Dmitry Gutov @ 2023-11-19 15:14 ` Eli Zaretskii 2023-11-19 18:04 ` Dmitry Gutov 2023-11-21 2:43 ` Richard Stallman 1 sibling, 1 reply; 342+ messages in thread From: Eli Zaretskii @ 2023-11-19 15:14 UTC (permalink / raw) To: Dmitry Gutov; +Cc: michael_heerdegen, luangruo, jporterbugs, rms, emacs-devel > Date: Sun, 19 Nov 2023 16:58:39 +0200 > Cc: michael_heerdegen@web.de, luangruo@yahoo.com, jporterbugs@gmail.com, > rms@gnu.org, emacs-devel@gnu.org > From: Dmitry Gutov <dmitry@gutov.dev> > > On 19/11/2023 16:52, Eli Zaretskii wrote: > >>>> > >>>> What I don't like here in this discussion is that some people are not > >>>> willing to accept that other people make different experiences with the > >>>> same things. > >>> This goes both ways, you know. > >> The "other side" doesn't create threads with angry comments about the > >> developers with opposing views writing lower-level verbose code > >> (choo-choo trains, Joao called that), with calls to prohibit such practices. > > I meant this very thread. The very previous message, actually. > > I don't see calls for prohibiting those implementation styles, in the > previous messages, or anywhere. It would be impractical anyway. I wasn't talking about prohibiting, I was talking about accepting that both sides have a right to describe their experiences. > >> OTOH, enacting a ban on particular abstractions will just about > >> guarantee that certain kinds of features will not be implemented. > > That's a strawman: no one of those who set policies here suggested any > > bans. One should be able to post opinions for and against certain > > coding styles without being accuse in mortal sins. > > No one is arguing about whether people are allowed to post opinions. > > There have been a few calls for working toward dropping pcase or cl-lib > from the Emacs core, however. You need to know to whom you listen, before you make such far-reaching conclusions. ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-11-19 15:14 ` Eli Zaretskii @ 2023-11-19 18:04 ` Dmitry Gutov 2023-11-19 18:30 ` Eli Zaretskii 0 siblings, 1 reply; 342+ messages in thread From: Dmitry Gutov @ 2023-11-19 18:04 UTC (permalink / raw) To: Eli Zaretskii; +Cc: michael_heerdegen, luangruo, jporterbugs, rms, emacs-devel On 19/11/2023 17:14, Eli Zaretskii wrote: >> Date: Sun, 19 Nov 2023 16:58:39 +0200 >> Cc: michael_heerdegen@web.de, luangruo@yahoo.com, jporterbugs@gmail.com, >> rms@gnu.org, emacs-devel@gnu.org >> From: Dmitry Gutov <dmitry@gutov.dev> >> >> On 19/11/2023 16:52, Eli Zaretskii wrote: >>>>>> >>>>>> What I don't like here in this discussion is that some people are not >>>>>> willing to accept that other people make different experiences with the >>>>>> same things. >>>>> This goes both ways, you know. >>>> The "other side" doesn't create threads with angry comments about the >>>> developers with opposing views writing lower-level verbose code >>>> (choo-choo trains, Joao called that), with calls to prohibit such practices. >>> I meant this very thread. The very previous message, actually. >> >> I don't see calls for prohibiting those implementation styles, in the >> previous messages, or anywhere. It would be impractical anyway. > > I wasn't talking about prohibiting, I was talking about accepting that > both sides have a right to describe their experiences. Perhaps you'll consider posting a message supporting both positions, then. >>>> OTOH, enacting a ban on particular abstractions will just about >>>> guarantee that certain kinds of features will not be implemented. >>> That's a strawman: no one of those who set policies here suggested any >>> bans. One should be able to post opinions for and against certain >>> coding styles without being accuse in mortal sins. >> >> No one is arguing about whether people are allowed to post opinions. >> >> There have been a few calls for working toward dropping pcase or cl-lib >> from the Emacs core, however. > > You need to know to whom you listen, before you make such far-reaching > conclusions. I don't think I've made any specific conclusion (or any predictions). But when some prolific contributors make such statements, and RMS is noticeably on their side, that can't help but create a certain impression to the public (this list is read not just by the core contributors). ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-11-19 18:04 ` Dmitry Gutov @ 2023-11-19 18:30 ` Eli Zaretskii 2023-11-19 18:51 ` Dmitry Gutov 0 siblings, 1 reply; 342+ messages in thread From: Eli Zaretskii @ 2023-11-19 18:30 UTC (permalink / raw) To: Dmitry Gutov; +Cc: michael_heerdegen, luangruo, jporterbugs, rms, emacs-devel > Date: Sun, 19 Nov 2023 20:04:56 +0200 > Cc: michael_heerdegen@web.de, luangruo@yahoo.com, jporterbugs@gmail.com, > rms@gnu.org, emacs-devel@gnu.org > From: Dmitry Gutov <dmitry@gutov.dev> > > >> I don't see calls for prohibiting those implementation styles, in the > >> previous messages, or anywhere. It would be impractical anyway. > > > > I wasn't talking about prohibiting, I was talking about accepting that > > both sides have a right to describe their experiences. > > Perhaps you'll consider posting a message supporting both positions, then. I don't understand what you mean by "supporting both positions". How is it possible for a person to support two opposite positions? > >>>> OTOH, enacting a ban on particular abstractions will just about > >>>> guarantee that certain kinds of features will not be implemented. > >>> That's a strawman: no one of those who set policies here suggested any > >>> bans. One should be able to post opinions for and against certain > >>> coding styles without being accuse in mortal sins. > >> > >> No one is arguing about whether people are allowed to post opinions. > >> > >> There have been a few calls for working toward dropping pcase or cl-lib > >> from the Emacs core, however. > > > > You need to know to whom you listen, before you make such far-reaching > > conclusions. > > I don't think I've made any specific conclusion (or any predictions). So your reference to "enacting a ban" is not a conclusion? Then why are you condemning something about which you still didn't reach any specific conclusions? > But when some prolific contributors make such statements, and RMS is > noticeably on their side, that can't help but create a certain > impression to the public (this list is read not just by the core > contributors). That impression is unjustified, and acting on it raises the level of unnecessary flames, and is not otherwise useful in any way. ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-11-19 18:30 ` Eli Zaretskii @ 2023-11-19 18:51 ` Dmitry Gutov 2023-11-19 19:49 ` Eli Zaretskii 0 siblings, 1 reply; 342+ messages in thread From: Dmitry Gutov @ 2023-11-19 18:51 UTC (permalink / raw) To: Eli Zaretskii; +Cc: michael_heerdegen, luangruo, jporterbugs, rms, emacs-devel On 19/11/2023 20:30, Eli Zaretskii wrote: >> Date: Sun, 19 Nov 2023 20:04:56 +0200 >> Cc: michael_heerdegen@web.de, luangruo@yahoo.com, jporterbugs@gmail.com, >> rms@gnu.org, emacs-devel@gnu.org >> From: Dmitry Gutov <dmitry@gutov.dev> >> >>>> I don't see calls for prohibiting those implementation styles, in the >>>> previous messages, or anywhere. It would be impractical anyway. >>> >>> I wasn't talking about prohibiting, I was talking about accepting that >>> both sides have a right to describe their experiences. >> >> Perhaps you'll consider posting a message supporting both positions, then. > > I don't understand what you mean by "supporting both positions". How > is it possible for a person to support two opposite positions? For example: I understand you guys and you guys, but we're not going to do any major changes (for the usual compatibility reasons, for example), though we would consider some minor improvements if either of you can suggest any. >>>>>> OTOH, enacting a ban on particular abstractions will just about >>>>>> guarantee that certain kinds of features will not be implemented. >>>>> That's a strawman: no one of those who set policies here suggested any >>>>> bans. One should be able to post opinions for and against certain >>>>> coding styles without being accuse in mortal sins. >>>> >>>> No one is arguing about whether people are allowed to post opinions. >>>> >>>> There have been a few calls for working toward dropping pcase or cl-lib >>>> from the Emacs core, however. >>> >>> You need to know to whom you listen, before you make such far-reaching >>> conclusions. >> >> I don't think I've made any specific conclusion (or any predictions). > > So your reference to "enacting a ban" is not a conclusion? Then why > are you condemning something about which you still didn't reach any > specific conclusions? I haven't made any predictions or conclusions as to whether a ban is forthcoming. Sometimes it helps to anticipate any such action, though, for example because many leaders feel it difficult to change position once a public declaration has been made. >> But when some prolific contributors make such statements, and RMS is >> noticeably on their side, that can't help but create a certain >> impression to the public (this list is read not just by the core >> contributors). > > That impression is unjustified, and acting on it raises the level of > unnecessary flames, and is not otherwise useful in any way. I'd like to help avoid it being made, on various observers. ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-11-19 18:51 ` Dmitry Gutov @ 2023-11-19 19:49 ` Eli Zaretskii 0 siblings, 0 replies; 342+ messages in thread From: Eli Zaretskii @ 2023-11-19 19:49 UTC (permalink / raw) To: Dmitry Gutov; +Cc: michael_heerdegen, luangruo, jporterbugs, rms, emacs-devel > Date: Sun, 19 Nov 2023 20:51:37 +0200 > Cc: michael_heerdegen@web.de, luangruo@yahoo.com, jporterbugs@gmail.com, > rms@gnu.org, emacs-devel@gnu.org > From: Dmitry Gutov <dmitry@gutov.dev> > > >> Perhaps you'll consider posting a message supporting both positions, then. > > > > I don't understand what you mean by "supporting both positions". How > > is it possible for a person to support two opposite positions? > > For example: > > I understand you guys and you guys, but we're not going to do any > major changes (for the usual compatibility reasons, for example), > though we would consider some minor improvements if either of you > can suggest any. How is this "supporting both positions"? which "both positions"? Also, to which changes does the above allude? > >>>>>> OTOH, enacting a ban on particular abstractions will just about > >>>>>> guarantee that certain kinds of features will not be implemented. > >>>>> That's a strawman: no one of those who set policies here suggested any > >>>>> bans. One should be able to post opinions for and against certain > >>>>> coding styles without being accuse in mortal sins. > >>>> > >>>> No one is arguing about whether people are allowed to post opinions. > >>>> > >>>> There have been a few calls for working toward dropping pcase or cl-lib > >>>> from the Emacs core, however. > >>> > >>> You need to know to whom you listen, before you make such far-reaching > >>> conclusions. > >> > >> I don't think I've made any specific conclusion (or any predictions). > > > > So your reference to "enacting a ban" is not a conclusion? Then why > > are you condemning something about which you still didn't reach any > > specific conclusions? > > I haven't made any predictions or conclusions as to whether a ban is > forthcoming. That's not how the above reads. ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-11-19 14:58 ` Dmitry Gutov 2023-11-19 15:14 ` Eli Zaretskii @ 2023-11-21 2:43 ` Richard Stallman 1 sibling, 0 replies; 342+ messages in thread From: Richard Stallman @ 2023-11-21 2:43 UTC (permalink / raw) To: Dmitry Gutov; +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. ]]] > No one is arguing about whether people are allowed to post opinions. Some are doing something somewhat like that. I have criticized CL, and pcase, for bloating the complexity of Emacs Lisp as one needs to know it to work on the current code base. Others disagree and have defended those features. I think that the disagreement on these questions is based on differing ideas about about what makes a feature good or bad. However, there are people who have switched to an ad-hominem campaign. They are not attacking my views about CL and pcase; rather, they are attacking me personally. -- Dr Richard Stallman (https://stallman.org) Chief GNUisance of the GNU Project (https://gnu.org) Founder, Free Software Foundation (https://fsf.org) Internet Hall-of-Famer (https://internethalloffame.org) ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-11-19 12:50 ` Eli Zaretskii 2023-11-19 14:05 ` Dmitry Gutov @ 2023-11-19 14:14 ` Michael Heerdegen 2023-11-19 15:09 ` Eli Zaretskii 1 sibling, 1 reply; 342+ messages in thread From: Michael Heerdegen @ 2023-11-19 14:14 UTC (permalink / raw) To: emacs-devel Eli Zaretskii <eliz@gnu.org> writes: > > What I don't like here in this discussion is that some people are not > > willing to accept that other people make different experiences with the > > same things. > > This goes both ways, you know. Indeed. I'm curious how an alternative could look like, actually. But unless such an alternative exists or is completely designed, it is only a claim that it would lead to less mistakes and would be simpler. And I doubt it. It would have to implement the same set of features, so it would be quite as complex as `pcase'. You would have to remember or look up more or less the same things and details. Maybe in a different mood (some people less angry, others more). And here the `rx' example and `pcase' are very similar: what the programmer actually has to keep in mind is how the regexp matching algorithm or the pattern matching algorithm works. This part is still a black box, you must learn the specification, independently from the language used to specify the matchers. How the result is interpreted is always something you have to learn additionally. In your example, actually, string regexps are the primitive, low level language, `rx' is the higher level language, so it should lead to less mistakes (your argument). `pcase' is the extensible higher level language for pattern matching, specifically designed for this purpose, so it should be more suited and lead to less mistakes than more primitive tools. Has anyone counted how many mistakes were introduced by wrong pcase pattern specifications, compared to more verbose re-formulations using other tools? If we don't do that, the discussion is still selective, with other words, about preferences again. Michael. ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-11-19 14:14 ` Michael Heerdegen @ 2023-11-19 15:09 ` Eli Zaretskii 2023-11-20 14:52 ` Michael Heerdegen 0 siblings, 1 reply; 342+ messages in thread From: Eli Zaretskii @ 2023-11-19 15:09 UTC (permalink / raw) To: Michael Heerdegen; +Cc: emacs-devel > From: Michael Heerdegen <michael_heerdegen@web.de> > Date: Sun, 19 Nov 2023 15:14:58 +0100 > > I'm curious how an alternative could look like, actually. I don't know. So I withdraw my judgment until such an alternative is presented. I suggest that everyone do the same. > It would have to implement the same set of features, so it would be > quite as complex as `pcase'. Complexity doesn't necessarily mean cryptic syntax. Cf regexp strings vs Rx. Cryptic syntax raises the bar by adding one more obstacle: before you deal with semantic complexity, you need to fight the uphill battle of syntactic complexity and obscurity. > You would have to remember or look up more or less the same things > and details. But if "the same things" speak for themselves, because they are identified in more human-readable language, you have fewer things to look up. Again, cf. regexp strings vs Rx. > And here the `rx' example and `pcase' are very similar: what the > programmer actually has to keep in mind is how the regexp matching > algorithm or the pattern matching algorithm works. That's true, but before you consider the subtleties of matching, you need to understand what the regexp should match, and that is harder with regexp strings when advanced features are used. > In your example, actually, string regexps are the primitive, low level > language, `rx' is the higher level language, so it should lead to less > mistakes (your argument). `pcase' is the extensible higher level > language for pattern matching, specifically designed for this purpose, > so it should be more suited and lead to less mistakes than more > primitive tools. To me, whether stuff is lower or higher in level is less relevant here. For example, macros can be considered "higher-level" constructs than the underlying Lisp functions and primitives, but macros are harder to read due to the additional syntax: the backticks, the comma, the @, etc. I'd say that higher-level languages always make it easier to write programs, but don't necessarily make it easier to read them. As another data point, consider the C preprocessor macros and specifically their advanced features, like # and ##. I invite you to try reading what we have in src/conf_post.h and src/lisp.h, and make up your own mind. > Has anyone counted how many mistakes were introduced by wrong pcase > pattern specifications, compared to more verbose re-formulations using > other tools? If we don't do that, the discussion is still selective, > with other words, about preferences again. Should be good to do that, but please remember that pcase exists for less than a decade, so we are just starting to learn to use it. ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-11-19 15:09 ` Eli Zaretskii @ 2023-11-20 14:52 ` Michael Heerdegen 0 siblings, 0 replies; 342+ messages in thread From: Michael Heerdegen @ 2023-11-20 14:52 UTC (permalink / raw) To: emacs-devel Eli Zaretskii <eliz@gnu.org> writes: > > I'm curious how an alternative could look like, actually. > > I don't know. So I withdraw my judgment until such an alternative is > presented. I suggest that everyone do the same. > > > It would have to implement the same set of features, so it would be > > quite as complex as `pcase'. > > Complexity doesn't necessarily mean cryptic syntax. Cf regexp strings > vs Rx. If you meant to imply that pcase has a unnecessarily "cryptic syntax", this is a judgment. If you wish that the syntax should be more like human language, or more verbose, or less like a new mini-language, this is an opinion. Which is ok. But not as neutral as your first sentence suggests. Still fine by me. But when this is a opinion, and other people differ, we also should speak about the disadvantages of a different approach. For example, if we replace the backquote syntax with something that looks more like function calls, it would be less obvious at which depth and which position a subpattern is matched. Since pcase has been introduced to make specification of complex, nested patterns easier and more compact to read, we will lose this advantage. The syntax might be easier to learn, but code will be harder to maintain and tweak. At least for me. But I repeat myself. I guess it's clear to you what I want to say, so you don't need to waste your time to reply, unless you disagree or like to do so nonetheless of course. Michael. ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-11-19 11:48 ` Michael Heerdegen 2023-11-19 12:50 ` Eli Zaretskii @ 2023-11-19 14:29 ` Po Lu 2023-11-20 15:20 ` Michael Heerdegen 2023-11-20 15:29 ` Dmitry Gutov 1 sibling, 2 replies; 342+ messages in thread From: Po Lu @ 2023-11-19 14:29 UTC (permalink / raw) To: Michael Heerdegen; +Cc: Jim Porter, rms, emacs-devel Michael Heerdegen <michael_heerdegen@web.de> writes: > "abstruse language" - "singular experience" ...(?) - sorry, are we > people having understood pcase in few minutes some kind of aliens, > compared to the "normal people"? Do we not count? Because we are not > loud and angry and outraged? With all due respect, your experience is very singular. Don't assume that I haven't canvassed other people's experiences, both on the Internet and off-line, methodically and anecdotally. My organization largely comprises C programmers who use Emacs for programming, as a means to an end rather than an end in itself. Our two sites centrally provision their own Emacs configurations to all users, which incorporates a large corpus of code for editing and analyzing C programs in accord with local practice. Naturally, the existence of this corpus demands that programmers be charged with its upkeep, and as no position is set aside for such work, this responsibility devolves on individuals almost at random. This is a representative microcosm of the wider Emacs userbase, I think: for most are not hobbyists, or even employed programmers for whom programming is also an avocation, but men working for salaries, with bills to pay and families to... you can complete the rest of this trite description. And it is they whom I canvassed. I sent a poll to 34 individuals, all in some capacity involved in the maintenance of Emacs Lisp. Some of the questions asked were: - Have you previously read the documentation for pcase and cl-loop? - (If you haven't, read it now.) Is the documentation for the pcase feature easily grasped, from your perspective? - Is the documentation for cl-loop easily grasped, from your perspective? - Read the pcase form in completion-at-point at /usr/src/[...]/simple.el. Do you understand the variables that are bound, and the circumstances in which they are? - Read each cl-loop form in comp.el. Could you rewrite those you understand with other constructs? - Do you think liberal use of cl-lib and pcase hinders the understanding of Emacs's own source code? - Do you think Emacs Lisp, excluding cl-lib and pcase, is wanting in list iteration or destructing constructs? "Easily" refers also to whether you can learn the construct within an amount of time that does not impact your work, not just whether it is possible to learn with mechanical ease. 20 of the 34 answered yes to the first question, 5 of 34 to the second, 4 of 34 to the third, 12 of 34 to the fourth, 30 of 34 to the fifth, 30 to the sixth, and 6 to the seventh. So I'd say the results were a resounding vindication of all that I've maintained thus far. There were other items on the poll, but they related to our own policy for Emacs Lisp and are by the by. As regards experiences on the Internet, they are laid bare for all to see. In this thread, for starters. > Interesting would be to hear concrete arguments, but we heard nearly > none. "I'm angry" is not an argument. No one in this thread has been presenting indignation as an argument. ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-11-19 14:29 ` Po Lu @ 2023-11-20 15:20 ` Michael Heerdegen 2023-11-20 15:29 ` Dmitry Gutov 1 sibling, 0 replies; 342+ messages in thread From: Michael Heerdegen @ 2023-11-20 15:20 UTC (permalink / raw) To: emacs-devel Po Lu <luangruo@yahoo.com> writes: > This is a representative microcosm of the wider Emacs userbase, I > think: for most are not hobbyists, or even employed programmers for > whom programming is also an avocation, but men working for salaries, > with bills to pay and families to... you can complete the rest of this > trite description. It is not representative for the people working on Emacs. Even less representative for the people working on the more complicated parts of Emacs like the implementation of the completion mechanism. > And it is they whom I canvassed. > > I sent a poll to 34 individuals, all in some capacity involved in the > maintenance of Emacs Lisp. Some of the questions asked were: > [...] Interesting results, thanks. This proves that the learning curve for `pcase' is steep. As is for Emacs. This is not such a surprise. Your poll doesn't measure whether it pays off or not. > > Interesting would be to hear concrete arguments, but we heard nearly > > none. "I'm angry" is not an argument. > > No one in this thread has been presenting indignation as an argument. Not like "this is my argument: ...", no. I meant I heard a lot of emotion instead of arguments. Michael. ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-11-19 14:29 ` Po Lu 2023-11-20 15:20 ` Michael Heerdegen @ 2023-11-20 15:29 ` Dmitry Gutov 2023-11-20 23:43 ` Po Lu 2023-11-20 23:45 ` Jose E. Marchesi 1 sibling, 2 replies; 342+ messages in thread From: Dmitry Gutov @ 2023-11-20 15:29 UTC (permalink / raw) To: Po Lu, Michael Heerdegen; +Cc: Jim Porter, rms, emacs-devel On 19/11/2023 16:29, Po Lu wrote: > My organization largely comprises C programmers who use Emacs for > programming, as a means to an end rather than an end in itself. Our two > sites centrally provision their own Emacs configurations to all users, > which incorporates a large corpus of code for editing and analyzing C > programs in accord with local practice. Naturally, the existence of > this corpus demands that programmers be charged with its upkeep, and as > no position is set aside for such work, this responsibility devolves on > individuals almost at random. This is a representative microcosm of the > wider Emacs userbase, I think: for most are not hobbyists, or even > employed programmers for whom programming is also an avocation, but men > working for salaries, with bills to pay and families to... you can > complete the rest of this trite description. And it is they whom I > canvassed. Polling professional C developers on whether they are comfortable with advanced syntax inspired by high-level languages like ML or Haskell is pretty much a self-fulfilling prophecy. Ask a company of OCaml developers (we have at least one representative of such among active contributors), or even a corpus of experienced JavaScript developers, the results will be different. Anyway, the results confirm what we've been aware of for some time: that the documentation for pcase needs work. Jim Porter's list of steps should help a lot. ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-11-20 15:29 ` Dmitry Gutov @ 2023-11-20 23:43 ` Po Lu 2023-11-21 1:09 ` Dmitry Gutov 2023-11-20 23:45 ` Jose E. Marchesi 1 sibling, 1 reply; 342+ messages in thread From: Po Lu @ 2023-11-20 23:43 UTC (permalink / raw) To: Dmitry Gutov; +Cc: Michael Heerdegen, Jim Porter, rms, emacs-devel Dmitry Gutov <dmitry@gutov.dev> writes: > Polling professional C developers on whether they are comfortable with > advanced syntax inspired by high-level languages like ML or Haskell is > pretty much a self-fulfilling prophecy. > > Ask a company of OCaml developers (we have at least one representative > of such among active contributors), or even a corpus of experienced > JavaScript developers, the results will be different. How many O'Caml developers are there? It's not plausible that they number greater than C developers (for that matter I don't think there's any O'Caml software on my computer). > Anyway, the results confirm what we've been aware of for some time: > that the documentation for pcase needs work. Jim Porter's list of > steps should help a lot. They substantiate in equal measure that pcase itself is ungainly to some Emacs users--some people here are loath to accept that, but the facts are what they are. Whether other Emacs users relish it is beside the point. ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-11-20 23:43 ` Po Lu @ 2023-11-21 1:09 ` Dmitry Gutov 2023-11-21 1:49 ` Po Lu 0 siblings, 1 reply; 342+ messages in thread From: Dmitry Gutov @ 2023-11-21 1:09 UTC (permalink / raw) To: Po Lu; +Cc: Michael Heerdegen, Jim Porter, rms, emacs-devel On 21/11/2023 01:43, Po Lu wrote: > Dmitry Gutov <dmitry@gutov.dev> writes: > >> Polling professional C developers on whether they are comfortable with >> advanced syntax inspired by high-level languages like ML or Haskell is >> pretty much a self-fulfilling prophecy. >> >> Ask a company of OCaml developers (we have at least one representative >> of such among active contributors), or even a corpus of experienced >> JavaScript developers, the results will be different. > > How many O'Caml developers are there? It's not plausible that they > number greater than C developers (for that matter I don't think there's > any O'Caml software on my computer). OCaml -- maybe not that many. But the sum total of developers writing in high-level languages (JavaScript included) is quite high. Ruby and Python have pattern matching in that style. Rust and Swift do too. JS might be getting one in a few years: https://github.com/tc39/proposal-pattern-matching Java introduced limited/experimental support this year: https://openjdk.org/jeps/432 Even the C++ standard might get it one day: https://www.stroustrup.com/pattern-matching-November-2014.pdf (libraries already available) ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-11-21 1:09 ` Dmitry Gutov @ 2023-11-21 1:49 ` Po Lu 2023-11-21 1:59 ` Dmitry Gutov 0 siblings, 1 reply; 342+ messages in thread From: Po Lu @ 2023-11-21 1:49 UTC (permalink / raw) To: Dmitry Gutov; +Cc: Michael Heerdegen, Jim Porter, rms, emacs-devel Dmitry Gutov <dmitry@gutov.dev> writes: > OCaml -- maybe not that many. But the sum total of developers writing > in high-level languages (JavaScript included) is quite high. > > Ruby and Python have pattern matching in that style. Rust and Swift do > too. > > JS might be getting one in a few years: > https://github.com/tc39/proposal-pattern-matching > > Java introduced limited/experimental support this year: > https://openjdk.org/jeps/432 > > Even the C++ standard might get it one day: > https://www.stroustrup.com/pattern-matching-November-2014.pdf > (libraries already available) That's all well and good, but one of Richard's requests at the outset of this thread was: > It's just the opposite for `pcase' -- its specific purpose is a > low-level purpose, so it could appear in any part of the code of > Emacs, The burden of its complexity can fall on any or all of us. > Those of you who are fans of `pcase' may not recognize the cost it > imposes on the Emacs Lisp language. You paid that cost already, > perhaps a few years ago, and perhaps you enjoy each new language > construct you learn. Perhaps, for you, the more complexity of > features to be learned, the better. > But don't argue that this cost does not exist, simply because it > doesn't feel like a burden to you. And thus far this thread has been awash with denials of that burden, one which unequivocally exists. This I and others have demonstrated time and again. pcase is _not_ fine as-is, however many other languages might provide analogous constructs. One man's meat is another man's poison; and it is up to us to place before either neither his meat nor his poison. ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-11-21 1:49 ` Po Lu @ 2023-11-21 1:59 ` Dmitry Gutov 2023-11-21 4:04 ` Po Lu 0 siblings, 1 reply; 342+ messages in thread From: Dmitry Gutov @ 2023-11-21 1:59 UTC (permalink / raw) To: Po Lu; +Cc: Michael Heerdegen, Jim Porter, rms, emacs-devel On 21/11/2023 03:49, Po Lu wrote: >> It's just the opposite for `pcase' -- its specific purpose is a >> low-level purpose, so it could appear in any part of the code of >> Emacs, The burden of its complexity can fall on any or all of us. That's not accurate: its purpose is a high-level one. Even though it can be used as a replacement for 'cond' in simple case too. > But don't argue that this cost does not exist, simply because it > doesn't feel like a burden to you. Did I? ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-11-21 1:59 ` Dmitry Gutov @ 2023-11-21 4:04 ` Po Lu 2023-11-21 11:27 ` Dmitry Gutov 0 siblings, 1 reply; 342+ messages in thread From: Po Lu @ 2023-11-21 4:04 UTC (permalink / raw) To: Dmitry Gutov; +Cc: Michael Heerdegen, Jim Porter, rms, emacs-devel Dmitry Gutov <dmitry@gutov.dev> writes: > That's not accurate: its purpose is a high-level one. Even though it > can be used as a replacement for 'cond' in simple case too. Destructuring variable binding is not a high-level use case. As Richard mentioned, such a definition is subject to the amount of Lisp there is possibly a role for it in. And needless to say, this amount is significant in the case of pcase, and is small in that of quail. >> But don't argue that this cost does not exist, simply because it >> doesn't feel like a burden to you. > > Did I? That's how it came across to me. "The burden is immaterial since many categories of programmers do not perceive it as such" is not much different from "the burden does not exist," when the inferences drawn from both are identical, to wit: that pcase is fine as it is. ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-11-21 4:04 ` Po Lu @ 2023-11-21 11:27 ` Dmitry Gutov 2023-11-21 11:49 ` Po Lu 0 siblings, 1 reply; 342+ messages in thread From: Dmitry Gutov @ 2023-11-21 11:27 UTC (permalink / raw) To: Po Lu; +Cc: Michael Heerdegen, Jim Porter, rms, emacs-devel On 21/11/2023 06:04, Po Lu wrote: >>> But don't argue that this cost does not exist, simply because it >>> doesn't feel like a burden to you. >> Did I? > That's how it came across to me. "The burden is immaterial since many > categories of programmers do not perceive it as such" is not much > different from "the burden does not exist," when the inferences drawn > from both are identical, to wit: that pcase is fine as it is. I never said that the cost doesn't exist. But one could ask whether it is a useful cost, overall, one that helps reduce the complexity of the code around it (one pays the cost when reading verbose code, too). Which might depend on how much one would have to work to understand to construct. You provided statistics about your coworkers who are all used to working with low-level code, and then claimed that those should be representative of the Emacs userbase as a whole. I countered that. ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-11-21 11:27 ` Dmitry Gutov @ 2023-11-21 11:49 ` Po Lu 0 siblings, 0 replies; 342+ messages in thread From: Po Lu @ 2023-11-21 11:49 UTC (permalink / raw) To: Dmitry Gutov; +Cc: Michael Heerdegen, Jim Porter, rms, emacs-devel Dmitry Gutov <dmitry@gutov.dev> writes: > I never said that the cost doesn't exist. But one could ask whether it > is a useful cost, overall, one that helps reduce the complexity of the > code around it (one pays the cost when reading verbose code, > too). Which might depend on how much one would have to work to > understand to construct. > > You provided statistics about your coworkers who are all used to > working with low-level code, and then claimed that those should be > representative of the Emacs userbase as a whole. I countered that. And I continue to disagree, because you never did cite any evidence to the contrary. It is very difficult to disabuse someone of a conviction formed through observations of his surroundings without objective evidence contradicting them, all the more so when others online also concur. Besides, IMHO exclusively linguistic goals are never worth their while in Emacs Lisp. It is an extension language, designed to be useful and comprehensible to users without their setting themselves to its study. ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-11-20 15:29 ` Dmitry Gutov 2023-11-20 23:43 ` Po Lu @ 2023-11-20 23:45 ` Jose E. Marchesi 2023-11-20 23:54 ` Emanuel Berg 2023-11-21 2:01 ` Dmitry Gutov 1 sibling, 2 replies; 342+ messages in thread From: Jose E. Marchesi @ 2023-11-20 23:45 UTC (permalink / raw) To: Dmitry Gutov; +Cc: Po Lu, Michael Heerdegen, Jim Porter, rms, emacs-devel > On 19/11/2023 16:29, Po Lu wrote: >> My organization largely comprises C programmers who use Emacs for >> programming, as a means to an end rather than an end in itself. Our two >> sites centrally provision their own Emacs configurations to all users, >> which incorporates a large corpus of code for editing and analyzing C >> programs in accord with local practice. Naturally, the existence of >> this corpus demands that programmers be charged with its upkeep, and as >> no position is set aside for such work, this responsibility devolves on >> individuals almost at random. This is a representative microcosm of the >> wider Emacs userbase, I think: for most are not hobbyists, or even >> employed programmers for whom programming is also an avocation, but men >> working for salaries, with bills to pay and families to... you can >> complete the rest of this trite description. And it is they whom I >> canvassed. > > Polling professional C developers on whether they are comfortable with > advanced syntax inspired by high-level languages like ML or Haskell is > pretty much a self-fulfilling prophecy. > > Ask a company of OCaml developers (we have at least one representative > of such among active contributors), or even a corpus of experienced > JavaScript developers, the results will be different. Following your own reasoning, wouldn't it be also reasonable to expect that the vast majority of Lisp developers won't be comfortable with such an "advanced syntax", considering that Lisp (unlike C) has basically no syntax? > Anyway, the results confirm what we've been aware of for some time: > that the documentation for pcase needs work. Jim Porter's list of > steps should help a lot. ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-11-20 23:45 ` Jose E. Marchesi @ 2023-11-20 23:54 ` Emanuel Berg 2023-11-21 2:01 ` Dmitry Gutov 1 sibling, 0 replies; 342+ messages in thread From: Emanuel Berg @ 2023-11-20 23:54 UTC (permalink / raw) To: emacs-devel Jose E. Marchesi wrote: >>> My organization largely comprises C programmers who use >>> Emacs for programming, as a means to an end rather than an >>> end in itself. Our two sites centrally provision their own >>> Emacs configurations to all users, which incorporates >>> a large corpus of code for editing and analyzing >>> C programs in accord with local practice. Naturally, the >>> existence of this corpus demands that programmers be >>> charged with its upkeep, and as no position is set aside >>> for such work, this responsibility devolves on individuals >>> almost at random. This is a representative microcosm of >>> the wider Emacs userbase, I think: for most are not >>> hobbyists, or even employed programmers for whom >>> programming is also an avocation, but men working for >>> salaries, with bills to pay and families to... you can >>> complete the rest of this trite description. And it is >>> they whom I canvassed. >> >> Polling professional C developers on whether they are >> comfortable with advanced syntax inspired by high-level >> languages like ML or Haskell is pretty much >> a self-fulfilling prophecy. >> >> Ask a company of OCaml developers (we have at least one >> representative of such among active contributors), or even >> a corpus of experienced JavaScript developers, the results >> will be different. > > Following your own reasoning, wouldn't it be also reasonable > to expect that the vast majority of Lisp developers won't be > comfortable with such an "advanced syntax", considering that > Lisp (unlike C) has basically no syntax? Maybe we should add some parenthesis to pcase, if that will make the Lisp programmers more comfortable using it? -- underground experts united https://dataswamp.org/~incal ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-11-20 23:45 ` Jose E. Marchesi 2023-11-20 23:54 ` Emanuel Berg @ 2023-11-21 2:01 ` Dmitry Gutov 2023-11-22 2:59 ` Richard Stallman 1 sibling, 1 reply; 342+ messages in thread From: Dmitry Gutov @ 2023-11-21 2:01 UTC (permalink / raw) To: Jose E. Marchesi; +Cc: Po Lu, Michael Heerdegen, Jim Porter, rms, emacs-devel On 21/11/2023 01:45, Jose E. Marchesi wrote: > Following your own reasoning, wouldn't it be also reasonable to expect > that the vast majority of Lisp developers won't be comfortable with such > an "advanced syntax", considering that Lisp (unlike C) has basically no > syntax? In Lisps, most of the complexity simply moved to standard library (and/or other libraries as well). Look at Common Lisp (cl-lib derived from it is bemoaned in a nearby thread) or Clojure. ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-11-21 2:01 ` Dmitry Gutov @ 2023-11-22 2:59 ` Richard Stallman 2023-11-22 3:29 ` Emanuel Berg 2023-11-22 11:58 ` Dmitry Gutov 0 siblings, 2 replies; 342+ messages in thread From: Richard Stallman @ 2023-11-22 2:59 UTC (permalink / raw) To: Dmitry Gutov; +Cc: jemarch, 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 Lisps, most of the complexity simply moved to standard library > (and/or other libraries as well). This seems to presume a principle of "conservation of complexity", but that is not so. Complexity doesn't simply "move". For example, pcase replicates (with differences) complexity that already existed in various Lisp functions and constructs. -- Dr Richard Stallman (https://stallman.org) Chief GNUisance of the GNU Project (https://gnu.org) Founder, Free Software Foundation (https://fsf.org) Internet Hall-of-Famer (https://internethalloffame.org) ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-11-22 2:59 ` Richard Stallman @ 2023-11-22 3:29 ` Emanuel Berg 2023-11-22 11:58 ` Dmitry Gutov 1 sibling, 0 replies; 342+ messages in thread From: Emanuel Berg @ 2023-11-22 3:29 UTC (permalink / raw) To: emacs-devel Richard Stallman wrote: >> In Lisps, most of the complexity simply moved to standard >> library (and/or other libraries as well). > > This seems to presume a principle of "conservation of > complexity", but that is not so. Complexity doesn't simply > "move". I think what he means is, without libraries the complexity is repeated in every file and in different ways with different solutions often for the same situation. With a library - the complexity is in one place alone, and all the files using it conforms to the same interface. -- underground experts united https://dataswamp.org/~incal ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-11-22 2:59 ` Richard Stallman 2023-11-22 3:29 ` Emanuel Berg @ 2023-11-22 11:58 ` Dmitry Gutov 2023-11-24 3:38 ` Richard Stallman 1 sibling, 1 reply; 342+ messages in thread From: Dmitry Gutov @ 2023-11-22 11:58 UTC (permalink / raw) To: rms; +Cc: jemarch, emacs-devel On 22/11/2023 04:59, 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 Lisps, most of the complexity simply moved to standard library > > (and/or other libraries as well). > > This seems to presume a principle of "conservation of complexity", but > that is not so. Not exactly. I just tried to explain that the notion of Lisp having "simple" syntax doesn't mean that everything about it can or should be just as simple. > Complexity doesn't simply "move". For example, pcase > replicates (with differences) complexity that already existed in > various Lisp functions and constructs. Indeed. The goal there (and in such cases in general) is to concentrate specific bits of complexity inside advanced named constructs (functions or macros) that are designed in a way that reduces the total complexity in the code which uses them. Then you (roughly) only need to understand the construct (which is a fixed amount of complexity) and then every piece of code using it (as long as it's used appropriately) will incur lower mental overhead than if it were implemented using just the basic primitives. Reducing the total effort required to understand a series of such programs. ^ permalink raw reply [flat|nested] 342+ messages in thread
* Re: Instead of pcase 2023-11-22 11:58 ` Dmitry Gutov @ 2023-11-24 3:38 ` Richard Stallman 0 siblings, 0 replies; 342+ messages in thread From: Richard Stallman @ 2023-11-24 3:38 UTC (permalink / raw) To: Dmitry Gutov; +Cc: jemarch, 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. ]]] > Indeed. The goal there (and in such cases in general) is to concentrate > specific bits of complexity inside advanced named constructs (functions > or macros) that are designed in a way that reduces the total complexity > in the code which uses them. I think you and I mean different things when we say "complexity". In this conversation, we are miscommunicating. To replace a pcase call with direct use of old Emacs Lisp constructs would make code that is more verbose. That could be considered a kind of complexity. But I'm talking about the complexity of the language that the code is written in. pcase code is written in a separate "domain-specific language", and the complexity of that language adds to the complexity of the Emacs Lisp language. But it still contains all those same old Emacs Lisp constructs. pcase does not replace any of that complexity; it adds additional complexity to the language. I hope that cond* will do the same kind of code-simplification that pcase does, while adding much less to the complexity of the lsnguage that the code is written in. -- Dr Richard Stallman (https://stallman.org) Chief GNUisance of the GNU Project (https://gnu.org) Founder, Free Software Foundation (https://fsf.org) Internet Hall-of-Famer (https://internethalloffame.org) ^ permalink raw reply [flat|nested] 342+ messages in thread
end of thread, other threads:[~2024-02-03 16:52 UTC | newest] Thread overview: 342+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2023-11-16 3:04 Instead of pcase Richard Stallman 2023-11-16 7:37 ` Philip Kaludercic 2023-11-16 17:18 ` T.V Raman 2023-11-16 17:44 ` Michael Heerdegen 2023-11-16 18:16 ` Philip Kaludercic 2023-11-17 8:54 ` Complex SPEC for variables/customization like font-lock-keywords/org-capture-templates/etc (was: Instead of pcase) Ihor Radchenko 2023-11-25 4:03 ` Complex SPEC for variables/customization like font-lock-keywords/org-capture-templates/etc Stefan Monnier 2023-11-16 19:19 ` Instead of pcase Eli Zaretskii 2023-11-17 8:02 ` Michael Heerdegen 2023-11-16 18:21 ` Dmitry Gutov 2023-11-16 18:39 ` T.V Raman 2023-11-16 18:47 ` Philip Kaludercic 2023-11-16 18:51 ` T.V Raman 2023-11-18 3:04 ` Richard Stallman 2023-11-19 12:23 ` Michael Heerdegen 2023-11-19 16:02 ` Barry Fishman 2023-11-19 17:59 ` Dmitry Gutov 2023-11-19 19:31 ` Eric Abrahamsen 2023-11-25 4:23 ` Stefan Monnier via Emacs development discussions. 2023-11-27 3:12 ` Richard Stallman 2023-11-19 21:15 ` Barry Fishman 2023-11-20 1:15 ` Dmitry Gutov 2023-11-20 15:32 ` Michael Heerdegen 2023-11-23 2:57 ` Richard Stallman 2023-11-24 17:14 ` Dmitry Gutov 2023-11-27 3:09 ` Richard Stallman 2023-11-27 12:21 ` Dmitry Gutov 2023-11-29 3:42 ` Richard Stallman 2023-11-29 12:56 ` Dmitry Gutov 2023-12-01 3:17 ` Richard Stallman 2023-11-28 2:44 ` Richard Stallman 2023-11-28 12:39 ` Dmitry Gutov 2023-11-30 3:37 ` Richard Stallman 2023-12-01 0:18 ` Dmitry Gutov 2023-12-01 5:51 ` Emanuel Berg 2023-12-10 8:34 ` Alfred M. Szmidt 2023-12-10 9:35 ` Eli Zaretskii 2023-12-10 9:53 ` Alfred M. Szmidt 2023-12-10 10:35 ` Eli Zaretskii 2023-12-10 11:05 ` Alfred M. Szmidt 2023-12-01 7:21 ` Eli Zaretskii 2023-12-01 8:03 ` Manuel Giraud via Emacs development discussions. 2023-12-02 3:21 ` Richard Stallman 2023-11-24 18:14 ` Michael Heerdegen 2023-11-24 18:35 ` Dmitry Gutov 2023-11-27 3:14 ` Richard Stallman 2023-11-28 2:46 ` Richard Stallman 2023-11-28 6:35 ` Nikita Domnitskii 2023-11-30 3:37 ` Richard Stallman 2023-12-02 21:37 ` Lynn Winebarger 2023-12-10 15:14 ` Richard Stallman 2023-12-10 16:27 ` Lynn Winebarger 2023-12-10 20:28 ` Michael Heerdegen via Emacs development discussions. 2023-12-10 21:13 ` Lynn Winebarger 2023-12-12 3:43 ` Richard Stallman 2023-12-12 6:46 ` Tomas Hlavaty 2023-12-12 15:18 ` [External] : " Drew Adams 2023-12-14 3:24 ` Richard Stallman 2023-12-14 16:52 ` Drew Adams 2023-12-16 4:24 ` Richard Stallman 2023-12-16 5:04 ` Drew Adams 2023-12-16 18:30 ` Bob Rogers 2023-12-18 4:13 ` Richard Stallman 2023-12-12 19:24 ` Tomas Hlavaty 2023-12-12 21:36 ` [External] : " Drew Adams 2023-12-12 22:25 ` Michael Heerdegen via Emacs development discussions. 2023-12-13 1:32 ` Adam Porter 2023-12-14 3:23 ` Richard Stallman 2023-12-16 4:23 ` Richard Stallman 2023-12-18 4:09 ` cond* Richard Stallman 2023-12-18 10:08 ` cond* João Távora 2023-12-21 4:20 ` cond* Richard Stallman 2023-12-21 9:50 ` cond* João Távora 2023-12-21 16:01 ` [External] : cond* Drew Adams 2023-12-21 16:20 ` João Távora 2023-12-24 3:56 ` Richard Stallman 2023-12-24 3:57 ` cond* Richard Stallman 2023-12-21 14:10 ` cond* Ihor Radchenko 2023-12-24 3:57 ` cond* Richard Stallman 2023-12-25 14:14 ` cond* Ihor Radchenko 2023-12-19 3:49 ` cond* Richard Stallman 2023-12-19 12:13 ` cond* João Távora 2023-12-22 3:14 ` cond* Richard Stallman 2023-12-22 7:27 ` cond* Philip Kaludercic 2023-12-25 3:41 ` cond* Richard Stallman 2023-12-25 12:32 ` cond* Philip Kaludercic 2023-12-27 4:54 ` cond* Richard Stallman 2023-12-27 14:34 ` cond* Philip Kaludercic 2023-12-29 3:52 ` cond* Richard Stallman 2024-01-01 14:49 ` cond* Ihor Radchenko 2024-01-03 4:13 ` cond* Richard Stallman 2024-01-03 15:57 ` cond* Ihor Radchenko 2024-01-05 4:23 ` cond* Richard Stallman 2024-01-06 14:33 ` cond* Ihor Radchenko 2024-01-06 22:25 ` [External] : cond* Drew Adams 2024-01-08 3:45 ` Richard Stallman 2024-01-08 15:20 ` Drew Adams 2024-01-09 2:53 ` map seq and radix-tree-leaf, in pcase Richard Stallman 2024-01-08 3:47 ` cond* Richard Stallman 2024-01-10 13:03 ` cond* Ihor Radchenko 2024-01-13 3:50 ` cond* Richard Stallman 2024-01-13 6:32 ` cond* Adam Porter 2024-01-16 3:31 ` cond* Richard Stallman 2024-01-13 19:47 ` cond* Ihor Radchenko 2024-01-15 3:13 ` cond* Richard Stallman 2024-01-08 3:47 ` cond* Richard Stallman 2024-01-08 15:13 ` cond* Ihor Radchenko 2024-01-27 3:37 ` cond* Richard Stallman 2024-02-01 16:26 ` cond* Ihor Radchenko 2024-02-03 3:36 ` cond* Richard Stallman 2024-02-03 16:52 ` cond* Ihor Radchenko 2024-01-03 4:13 ` cond* Richard Stallman 2024-01-03 15:48 ` cond* Ihor Radchenko 2024-01-06 4:31 ` cond* Richard Stallman 2024-01-06 13:09 ` cond* Ihor Radchenko 2024-01-08 3:47 ` cond* Richard Stallman 2024-01-08 15:26 ` cond* Ihor Radchenko 2024-01-27 3:37 ` cond* Richard Stallman 2024-01-03 4:13 ` cond* Richard Stallman 2024-01-03 15:50 ` cond* Ihor Radchenko 2024-01-06 4:31 ` cond* Richard Stallman 2024-01-06 13:13 ` cond* Ihor Radchenko 2024-01-08 3:47 ` cond* Richard Stallman 2024-01-08 15:35 ` cond* Ihor Radchenko 2023-12-19 15:53 ` [External] : cond* Drew Adams 2023-12-21 4:22 ` Richard Stallman 2023-12-21 4:22 ` Richard Stallman 2023-12-18 4:09 ` cond* Richard Stallman 2023-12-18 5:41 ` cond* Adam Porter 2023-12-21 4:20 ` cond* Richard Stallman 2023-12-16 4:23 ` Instead of pcase Richard Stallman 2023-12-16 4:23 ` Richard Stallman 2023-12-16 6:57 ` Adam Porter 2023-12-20 3:28 ` Richard Stallman 2023-12-20 10:52 ` Adam Porter 2023-12-23 2:53 ` Richard Stallman 2023-12-23 2:53 ` Richard Stallman 2023-12-25 14:26 ` Ihor Radchenko 2023-12-27 4:54 ` Richard Stallman 2023-12-28 13:05 ` Ihor Radchenko 2023-12-30 3:20 ` Richard Stallman 2024-01-01 14:33 ` Ihor Radchenko 2024-01-03 4:13 ` Richard Stallman 2024-01-03 4:13 ` Richard Stallman 2024-01-03 16:08 ` Ihor Radchenko 2024-01-05 4:23 ` Richard Stallman 2024-01-06 13:04 ` Ihor Radchenko 2024-01-08 3:47 ` Richard Stallman 2024-01-08 15:42 ` Ihor Radchenko 2024-01-27 3:37 ` Richard Stallman 2023-12-13 4:58 ` Richard Stallman 2023-12-11 3:31 ` Richard Stallman 2023-11-19 13:49 ` Dmitry Gutov 2023-11-21 2:42 ` Richard Stallman 2023-11-21 5:14 ` Jim Porter 2023-11-21 5:34 ` Yuri Khan 2023-11-21 11:11 ` Dmitry Gutov 2023-11-21 15:38 ` Michael Heerdegen 2023-11-23 3:00 ` Richard Stallman 2023-11-24 3:34 ` Richard Stallman 2023-11-24 4:30 ` Jim Porter 2023-11-24 7:45 ` Eli Zaretskii 2023-11-25 3:08 ` Emanuel Berg 2023-11-24 17:01 ` Dmitry Gutov 2023-11-24 17:29 ` Lynn Winebarger 2023-11-28 2:44 ` Richard Stallman 2023-11-30 19:14 ` Lynn Winebarger 2023-11-30 19:26 ` Eli Zaretskii 2023-11-30 20:30 ` Michael Heerdegen via Emacs development discussions. 2023-12-01 6:24 ` Eli Zaretskii 2023-12-01 15:47 ` Michael Heerdegen via Emacs development discussions. 2023-12-01 16:07 ` Eli Zaretskii 2023-12-01 20:27 ` Alan Mackenzie 2023-12-02 13:24 ` Michael Heerdegen via Emacs development discussions. 2023-12-02 13:51 ` Emanuel Berg 2023-12-04 3:11 ` Richard Stallman 2023-12-03 3:28 ` Richard Stallman 2023-11-30 20:47 ` João Távora 2023-12-01 6:31 ` Eli Zaretskii 2023-12-01 7:07 ` Yuri Khan 2023-12-01 8:10 ` Eli Zaretskii 2023-12-01 9:04 ` Andreas Schwab 2023-12-04 3:08 ` Richard Stallman 2023-12-04 11:58 ` Eli Zaretskii 2023-12-04 12:35 ` Lynn Winebarger 2023-12-04 13:20 ` Eli Zaretskii 2023-12-04 17:46 ` Andreas Schwab 2023-12-07 2:48 ` Richard Stallman 2023-12-07 17:42 ` Andreas Schwab 2023-12-09 4:02 ` Richard Stallman 2023-12-04 18:17 ` Lynn Winebarger 2023-12-04 12:37 ` Dmitry Gutov 2023-12-08 3:54 ` Richard Stallman 2023-12-01 10:13 ` João Távora 2023-12-01 8:35 ` Andreas Schwab 2023-12-01 10:02 ` João Távora 2023-12-01 11:52 ` Eli Zaretskii 2023-12-01 12:48 ` Dmitry Gutov 2023-12-01 14:44 ` Eli Zaretskii 2023-12-01 18:28 ` Dmitry Gutov 2023-12-01 18:40 ` Eli Zaretskii 2023-12-01 18:45 ` João Távora 2024-01-09 5:36 ` Stefan Kangas 2023-12-01 13:28 ` João Távora 2023-12-01 16:25 ` Andreas Schwab 2024-01-09 5:33 ` Stefan Kangas 2024-01-09 10:43 ` João Távora 2023-12-01 16:04 ` Michael Heerdegen via Emacs development discussions. 2023-12-01 16:33 ` Eli Zaretskii 2023-12-02 3:20 ` Richard Stallman 2023-12-02 8:41 ` Andreas Schwab 2023-12-02 9:02 ` Philip Kaludercic 2023-12-02 10:14 ` Emanuel Berg 2023-12-02 17:02 ` Barry Fishman 2023-12-02 20:25 ` Michael Heerdegen via Emacs development discussions. 2023-12-03 4:30 ` Emanuel Berg 2023-12-05 2:58 ` Richard Stallman 2023-12-05 3:36 ` chad 2023-12-08 3:53 ` Richard Stallman 2023-12-02 14:33 ` Michael Heerdegen via Emacs development discussions. 2023-12-04 3:11 ` Richard Stallman 2023-12-02 18:01 ` Lynn Winebarger 2023-12-04 3:11 ` Richard Stallman 2023-12-04 12:27 ` Lynn Winebarger 2023-12-03 3:27 ` Richard Stallman 2023-11-25 4:15 ` Stefan Monnier 2023-11-27 3:12 ` Richard Stallman 2023-11-30 18:06 ` Michael Heerdegen 2023-11-16 18:49 ` Dmitry Gutov 2023-11-16 23:41 ` Emanuel Berg 2023-11-17 7:34 ` Eli Zaretskii 2023-11-26 3:17 ` Richard Stallman 2023-11-16 15:06 ` Michael Heerdegen 2023-11-16 17:31 ` T.V Raman 2023-11-16 18:26 ` Jim Porter 2023-11-16 18:40 ` T.V Raman 2023-11-16 19:13 ` Jim Porter 2023-11-20 3:06 ` Richard Stallman 2023-11-20 14:35 ` Michael Heerdegen 2023-11-23 2:57 ` Richard Stallman 2023-11-16 15:20 ` Spencer Baugh 2023-11-16 20:16 ` Tomas Hlavaty 2023-11-16 21:37 ` [External] : " Drew Adams 2023-11-25 4:34 ` Stefan Monnier via Emacs development discussions. 2023-11-25 8:53 ` Eli Zaretskii 2023-11-18 3:03 ` combining cond and let, to replace pcase Richard Stallman 2023-11-19 11:20 ` Michael Heerdegen 2023-11-19 11:43 ` Eli Zaretskii 2023-11-19 12:16 ` Gerd Möllmann 2023-11-19 13:21 ` Eli Zaretskii 2023-11-19 13:32 ` Gerd Möllmann 2023-11-19 14:41 ` Eli Zaretskii 2023-11-19 15:27 ` Gerd Möllmann 2023-11-19 15:29 ` Eli Zaretskii 2023-11-19 16:03 ` Joost Kremers 2023-11-19 16:59 ` Eli Zaretskii 2023-11-19 18:29 ` Joost Kremers 2023-11-19 18:35 ` Eli Zaretskii 2023-11-19 12:50 ` Michael Heerdegen 2023-11-19 13:08 ` Eli Zaretskii 2023-11-19 13:52 ` Michael Heerdegen 2023-11-19 14:45 ` Eli Zaretskii 2023-11-20 15:35 ` Michael Heerdegen 2023-11-20 16:37 ` Eli Zaretskii 2023-11-21 8:33 ` Michael Heerdegen 2023-11-21 8:39 ` Michael Heerdegen 2023-11-19 13:59 ` Dmitry Gutov 2023-11-19 14:49 ` Eli Zaretskii 2023-11-19 14:53 ` Dmitry Gutov 2023-11-19 12:04 ` Gerd Möllmann 2023-11-19 18:10 ` Tomas Hlavaty 2023-11-25 4:45 ` Stefan Monnier via Emacs development discussions. 2023-11-28 15:31 ` João Távora 2023-11-28 15:55 ` Stefan Monnier 2023-11-19 21:36 ` Alan Mackenzie 2023-11-21 16:14 ` Michael Heerdegen 2023-11-19 16:08 ` Axel Forsman 2023-11-21 15:53 ` Michael Heerdegen 2023-11-23 2:58 ` Richard Stallman 2023-11-23 7:02 ` Tomas Hlavaty 2023-11-26 3:14 ` Richard Stallman 2023-11-27 17:07 ` Tomas Hlavaty 2023-11-27 17:59 ` Yuri Khan 2023-11-28 14:25 ` Tomas Hlavaty 2023-11-23 8:58 ` Manuel Giraud via Emacs development discussions. 2023-11-26 3:14 ` Richard Stallman 2023-11-24 3:08 ` Daniel Semyonov 2023-11-24 3:26 ` Daniel Semyonov 2023-11-25 2:59 ` Richard Stallman 2023-11-25 5:11 ` Stefan Monnier via Emacs development discussions. 2023-11-27 3:11 ` Richard Stallman 2023-11-27 3:11 ` Richard Stallman 2023-11-27 18:13 ` Manuel Giraud via Emacs development discussions. 2023-11-27 18:49 ` Yuri Khan 2023-11-27 23:12 ` Stefan Monnier 2023-11-29 3:41 ` Richard Stallman 2023-11-29 3:40 ` Richard Stallman 2023-11-16 18:11 ` Instead of pcase Emanuel Berg 2023-11-16 19:26 ` Eli Zaretskii 2023-11-16 22:16 ` Emanuel Berg 2023-11-17 7:30 ` Eli Zaretskii 2023-11-17 8:09 ` Emanuel Berg 2023-11-17 12:16 ` Eli Zaretskii 2023-11-18 6:26 ` Emanuel Berg 2023-11-18 7:21 ` Po Lu 2023-11-18 7:41 ` Eli Zaretskii 2023-11-16 18:22 ` Jim Porter 2023-11-16 22:55 ` Emanuel Berg 2023-11-17 5:36 ` Po Lu 2023-11-19 11:48 ` Michael Heerdegen 2023-11-19 12:50 ` Eli Zaretskii 2023-11-19 14:05 ` Dmitry Gutov 2023-11-19 14:41 ` Po Lu 2023-11-19 14:44 ` Dmitry Gutov 2023-11-19 14:52 ` Eli Zaretskii 2023-11-19 14:58 ` Dmitry Gutov 2023-11-19 15:14 ` Eli Zaretskii 2023-11-19 18:04 ` Dmitry Gutov 2023-11-19 18:30 ` Eli Zaretskii 2023-11-19 18:51 ` Dmitry Gutov 2023-11-19 19:49 ` Eli Zaretskii 2023-11-21 2:43 ` Richard Stallman 2023-11-19 14:14 ` Michael Heerdegen 2023-11-19 15:09 ` Eli Zaretskii 2023-11-20 14:52 ` Michael Heerdegen 2023-11-19 14:29 ` Po Lu 2023-11-20 15:20 ` Michael Heerdegen 2023-11-20 15:29 ` Dmitry Gutov 2023-11-20 23:43 ` Po Lu 2023-11-21 1:09 ` Dmitry Gutov 2023-11-21 1:49 ` Po Lu 2023-11-21 1:59 ` Dmitry Gutov 2023-11-21 4:04 ` Po Lu 2023-11-21 11:27 ` Dmitry Gutov 2023-11-21 11:49 ` Po Lu 2023-11-20 23:45 ` Jose E. Marchesi 2023-11-20 23:54 ` Emanuel Berg 2023-11-21 2:01 ` Dmitry Gutov 2023-11-22 2:59 ` Richard Stallman 2023-11-22 3:29 ` Emanuel Berg 2023-11-22 11:58 ` Dmitry Gutov 2023-11-24 3:38 ` Richard Stallman
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).