* Emacs 30.0 warning from `cl-pushnew' and `memql' @ 2022-12-26 20:38 Emanuel Berg 2022-12-27 6:56 ` Jean Louis 2022-12-27 10:28 ` Michael Heerdegen 0 siblings, 2 replies; 61+ messages in thread From: Emanuel Berg @ 2022-12-26 20:38 UTC (permalink / raw) To: help-gnu-emacs After the last powerup I see this, it refers to a use of `cl-pushnew'. Warning: `memql' called with literal string that may never match (arg 1) GNU Emacs 30.0.50 (build 1, x86_64-pc-linux-gnu, cairo version 1.16.0) of 2022-12-26 [commit 2ffe1494e16381cfc7fec95a6a0879f268df3e95] https://dataswamp.org/~incal/conf/.zsh/install-emacs There were a bunch of other warnings, during installation as well as during native compilation, next time I'll see if I can fetch those and get back to you on those as well ... -- underground experts united https://dataswamp.org/~incal ^ permalink raw reply [flat|nested] 61+ messages in thread
* Re: Emacs 30.0 warning from `cl-pushnew' and `memql' 2022-12-26 20:38 Emacs 30.0 warning from `cl-pushnew' and `memql' Emanuel Berg @ 2022-12-27 6:56 ` Jean Louis 2022-12-27 10:28 ` Michael Heerdegen 1 sibling, 0 replies; 61+ messages in thread From: Jean Louis @ 2022-12-27 6:56 UTC (permalink / raw) To: help-gnu-emacs * Emanuel Berg <incal@dataswamp.org> [2022-12-27 00:37]: > After the last powerup I see this, it refers to a use of `cl-pushnew'. > > Warning: `memql' called with literal string that may never match > (arg 1) I just guess that may be some of new warnings, which is good to have as it helps in improving the code. -- Jean Take action in Free Software Foundation campaigns: https://www.fsf.org/campaigns In support of Richard M. Stallman https://stallmansupport.org/ ^ permalink raw reply [flat|nested] 61+ messages in thread
* Re: Emacs 30.0 warning from `cl-pushnew' and `memql' 2022-12-26 20:38 Emacs 30.0 warning from `cl-pushnew' and `memql' Emanuel Berg 2022-12-27 6:56 ` Jean Louis @ 2022-12-27 10:28 ` Michael Heerdegen 2022-12-27 11:33 ` Emanuel Berg 2022-12-27 11:39 ` Emanuel Berg 1 sibling, 2 replies; 61+ messages in thread From: Michael Heerdegen @ 2022-12-27 10:28 UTC (permalink / raw) To: help-gnu-emacs Emanuel Berg <incal@dataswamp.org> writes: > After the last powerup I see this, it refers to a use of `cl-pushnew'. > > Warning: `memql' called with literal string that may never match > (arg 1) Yes, these new warnings hint at problematic calls. In case of cl-pushnew you want to specify a :test function to avoid comparing strings with an inappropriate test function like the default memql. Michael. ^ permalink raw reply [flat|nested] 61+ messages in thread
* Re: Emacs 30.0 warning from `cl-pushnew' and `memql' 2022-12-27 10:28 ` Michael Heerdegen @ 2022-12-27 11:33 ` Emanuel Berg 2022-12-27 11:39 ` Emanuel Berg 1 sibling, 0 replies; 61+ messages in thread From: Emanuel Berg @ 2022-12-27 11:33 UTC (permalink / raw) To: help-gnu-emacs Michael Heerdegen wrote: >> After the last powerup I see this, it refers to a use of `cl-pushnew'. >> >> Warning: `memql' called with literal string that may never match >> (arg 1) > > Yes, these new warnings hint at problematic calls. In case of > cl-pushnew you want to specify a :test function to avoid comparing > strings with an inappropriate test function like the > default memql. But that's up to `cl-pushnew' to do, and if it can't/don't, it shouldn't accept strings as indata ... -- underground experts united https://dataswamp.org/~incal ^ permalink raw reply [flat|nested] 61+ messages in thread
* Re: Emacs 30.0 warning from `cl-pushnew' and `memql' 2022-12-27 10:28 ` Michael Heerdegen 2022-12-27 11:33 ` Emanuel Berg @ 2022-12-27 11:39 ` Emanuel Berg 2022-12-28 3:23 ` [External] : " Drew Adams 2022-12-28 6:25 ` tomas 1 sibling, 2 replies; 61+ messages in thread From: Emanuel Berg @ 2022-12-27 11:39 UTC (permalink / raw) To: help-gnu-emacs Michael Heerdegen wrote: >> After the last powerup I see this, it refers to a use of >> `cl-pushnew'. >> >> Warning: `memql' called with literal string that may never match >> (arg 1) > > Yes, these new warnings hint at problematic calls. In case of > cl-pushnew you want to specify a :test function to avoid comparing > strings with an inappropriate test function like the > default memql. This does not render the warning (cl-pushnew "/usr/share/emacs/site-lisp/elpa-src/slime-2.26.1" load-path :test #'string=) but this is not a model I can endorse, this is why you have that level of abstraction to begin with, i.e., not to be bothered all the time with implementation details. Might as well to provide :loop #'cl-dolist how to iterate the list as well ... And after that ... is there anything else to specify before we can get rid of `cl-pushnew' altogether since it amounts to doing everything manually anyway? -- underground experts united https://dataswamp.org/~incal ^ permalink raw reply [flat|nested] 61+ messages in thread
* RE: [External] : Re: Emacs 30.0 warning from `cl-pushnew' and `memql' 2022-12-27 11:39 ` Emanuel Berg @ 2022-12-28 3:23 ` Drew Adams 2022-12-28 4:23 ` Emanuel Berg 2022-12-28 6:25 ` tomas 1 sibling, 1 reply; 61+ messages in thread From: Drew Adams @ 2022-12-28 3:23 UTC (permalink / raw) To: Emanuel Berg, help-gnu-emacs@gnu.org > (cl-pushnew "/usr/share/emacs/site-lisp/elpa-src/slime-2.26.1" > load-path > :test #'string=) > > but this is not a model I can endorse, this is why you have that > level of abstraction to begin with, i.e., not to be bothered all the > time with implementation details. > > Might as well to provide :loop #'cl-dolist how to iterate the > list as well ... > > And after that ... is there anything else to specify before we can > get rid of `cl-pushnew' altogether since it amounts to doing > everything manually anyway? `cl-pushnew' should be an emulation of Common Lisp `pushnew' - neither more nor less. I'm not sure what your point is, but `pushnew' defaults to using `eql', not `equal' (or `string='). So if you want `pushnew' to compare strings then yes, you should pass a predicate such as `string=' (or `equal'). https://www.cs.cmu.edu/Groups/AI/html/cltl/clm/node149.html ___ IMHO, it should be the case for _all_ things that `cl-lib' tries to support. We shouldn't (IMO) be in the business of adding stuff to `cl-lib' that has nothing to do with CL. But that's happened. On the other hand, there's no reason (IMO) that Elisp can't have its own functions that have the same name as CL functions (sans `cl-'). In that case the Elisp functions need not behave the same as the CL ones. IOW, `cl-lib', and the `cl-' prefix, should be reserved for CL emulation. Elisp has `push', for example. It need not be the same as CL `push' (but I believe it pretty much is). Emacs could just as well have a `case' macro, and not require you to load `cl-lib'. Similarly for other commonly useful macros. Why does Elisp have one CL thing (without `cl-') and not another? You might well ask. ^ permalink raw reply [flat|nested] 61+ messages in thread
* Re: [External] : Re: Emacs 30.0 warning from `cl-pushnew' and `memql' 2022-12-28 3:23 ` [External] : " Drew Adams @ 2022-12-28 4:23 ` Emanuel Berg 2022-12-29 22:27 ` Drew Adams 2022-12-30 6:30 ` tomas 0 siblings, 2 replies; 61+ messages in thread From: Emanuel Berg @ 2022-12-28 4:23 UTC (permalink / raw) To: help-gnu-emacs Drew Adams wrote: > `cl-pushnew' should be an emulation of Common Lisp `pushnew' - > neither more nor less. > > I'm not sure what your point is, but `pushnew' defaults to using > `eql', not `equal' (or `string='). So if you want `pushnew' to > compare strings then yes, you should pass a predicate such as > `string=' (or `equal'). It's much better if the function itself checks what type the value is of and pick a suitable function to compare from that, then the user don't have to think about that at all. -- underground experts united https://dataswamp.org/~incal ^ permalink raw reply [flat|nested] 61+ messages in thread
* RE: [External] : Re: Emacs 30.0 warning from `cl-pushnew' and `memql' 2022-12-28 4:23 ` Emanuel Berg @ 2022-12-29 22:27 ` Drew Adams 2022-12-30 22:27 ` Emanuel Berg 2022-12-30 6:30 ` tomas 1 sibling, 1 reply; 61+ messages in thread From: Drew Adams @ 2022-12-29 22:27 UTC (permalink / raw) To: Emanuel Berg, help-gnu-emacs@gnu.org > > `cl-pushnew' should be an emulation of Common Lisp `pushnew' - > > neither more nor less. > > > > I'm not sure what your point is, but `pushnew' defaults to using > > `eql', not `equal' (or `string='). So if you want `pushnew' to > > compare strings then yes, you should pass a predicate such as > > `string=' (or `equal'). > > It's much better if the function itself checks what type the value > is of and pick a suitable function to compare from that, then the > user don't have to think about that at all. Again, `cl-case` came from CL `case' (and that came from other Lisps). Elisp is of course free to do whatever it wants. It could add an optional TEST predicate arg etc. Checking the "type the value is of" is problematic. For one thing, you might well want to control the type of the arg so that it just fit the predicate you want used (e.g. `eql' in the current case). And some values are of multiple types. E.g., nil's a symbol and a list. And some types are subtypes of other types. E.g. lists are sequences. ^ permalink raw reply [flat|nested] 61+ messages in thread
* Re: [External] : Re: Emacs 30.0 warning from `cl-pushnew' and `memql' 2022-12-29 22:27 ` Drew Adams @ 2022-12-30 22:27 ` Emanuel Berg 0 siblings, 0 replies; 61+ messages in thread From: Emanuel Berg @ 2022-12-30 22:27 UTC (permalink / raw) To: help-gnu-emacs Drew Adams wrote: >>> `cl-pushnew' should be an emulation of Common Lisp >>> `pushnew' - neither more nor less. >>> >>> I'm not sure what your point is, but `pushnew' defaults to >>> using `eql', not `equal' (or `string='). So if you want >>> `pushnew' to compare strings then yes, you should pass >>> a predicate such as `string=' (or `equal'). >> >> It's much better if the function itself checks what type >> the value is of and pick a suitable function to compare >> from that, then the user don't have to think about that >> at all. > > Again, `cl-case` came from CL `case' (and that came from > other Lisps). Yes, but I say that with respect to that particular function, if it isn't to be modified for whatever external reasons that's another discussion you of course are free to carry on with ... > Checking the "type the value is of" is problematic. For one > thing, you might well want to control the type The function, rather than you, can do this - and pretty easily so: (when (stringp arg) (setq pred #'string=) ) > And some values are of multiple types. E.g., nil's a symbol > and a list. And some types are subtypes of other types. E.g. > lists are sequences. All types that are comparable have a function to do that, that function is the one to be used. If they haven't, how are we to determine if they are "new" at all? Types whose values cannot be compared even to themself to determine equality - if such types exist - I don't see how they can be supported by a 'pushnew' function, really? -- underground experts united https://dataswamp.org/~incal ^ permalink raw reply [flat|nested] 61+ messages in thread
* Re: [External] : Re: Emacs 30.0 warning from `cl-pushnew' and `memql' 2022-12-28 4:23 ` Emanuel Berg 2022-12-29 22:27 ` Drew Adams @ 2022-12-30 6:30 ` tomas 1 sibling, 0 replies; 61+ messages in thread From: tomas @ 2022-12-30 6:30 UTC (permalink / raw) To: help-gnu-emacs [-- Attachment #1: Type: text/plain, Size: 655 bytes --] On Wed, Dec 28, 2022 at 05:23:16AM +0100, Emanuel Berg wrote: [...] > It's much better if the function itself checks what type the value > is of and pick a suitable function to compare from that, then the > user don't have to think about that at all. Alas, the types don't always carry enough info to know what comparison that squishy human behind the glass wants. I guess if they did, they'd be boring to the point of being obnoxious (perhaps a corollary of Rice's [1] theorem?). This was the dream of object oriented programming ("Kids, go compare yourselves"). Cheers [1] https://en.wikipedia.org/wiki/Rice%27s_theorem -- t [-- Attachment #2: signature.asc --] [-- Type: application/pgp-signature, Size: 195 bytes --] ^ permalink raw reply [flat|nested] 61+ messages in thread
* Re: Emacs 30.0 warning from `cl-pushnew' and `memql' 2022-12-27 11:39 ` Emanuel Berg 2022-12-28 3:23 ` [External] : " Drew Adams @ 2022-12-28 6:25 ` tomas 2022-12-28 11:59 ` Michael Heerdegen 2022-12-28 12:44 ` Emanuel Berg 1 sibling, 2 replies; 61+ messages in thread From: tomas @ 2022-12-28 6:25 UTC (permalink / raw) To: help-gnu-emacs [-- Attachment #1: Type: text/plain, Size: 1002 bytes --] On Tue, Dec 27, 2022 at 12:39:15PM +0100, Emanuel Berg wrote: > Michael Heerdegen wrote: > > >> After the last powerup I see this, it refers to a use of > >> `cl-pushnew'. > >> > >> Warning: `memql' called with literal string that may never match > >> (arg 1) > > > > Yes, these new warnings hint at problematic calls. In case of > > cl-pushnew you want to specify a :test function to avoid comparing > > strings with an inappropriate test function like the > > default memql. > > This does not render the warning > > (cl-pushnew "/usr/share/emacs/site-lisp/elpa-src/slime-2.26.1" > load-path > :test #'string=) > > but this is not a model I can endorse, this is why you have that > level of abstraction to begin with, i.e., not to be bothered all the > time with implementation details. I don't understand you. That function is most useful if you can pass it a custom comparison function. I'd say it's fine as it is. Cheers -- t [-- Attachment #2: signature.asc --] [-- Type: application/pgp-signature, Size: 195 bytes --] ^ permalink raw reply [flat|nested] 61+ messages in thread
* Re: Emacs 30.0 warning from `cl-pushnew' and `memql' 2022-12-28 6:25 ` tomas @ 2022-12-28 11:59 ` Michael Heerdegen 2022-12-28 12:41 ` tomas ` (2 more replies) 2022-12-28 12:44 ` Emanuel Berg 1 sibling, 3 replies; 61+ messages in thread From: Michael Heerdegen @ 2022-12-28 11:59 UTC (permalink / raw) To: help-gnu-emacs <tomas@tuxteam.de> writes: > I don't understand you. That function is most useful if you can > pass it a custom comparison function. I'd say it's fine as it > is. I think the interpretation of the question "Could there be a better default comparison function?", in the sense that `eql' is a bit nicer than `eq' for specific value types, is valid, especially when considering that `cl-pushnew' is often used for configuration stuff or other purposes where speed is not crucial. Michael. ^ permalink raw reply [flat|nested] 61+ messages in thread
* Re: Emacs 30.0 warning from `cl-pushnew' and `memql' 2022-12-28 11:59 ` Michael Heerdegen @ 2022-12-28 12:41 ` tomas 2022-12-28 12:45 ` Emanuel Berg ` (3 more replies) 2022-12-28 17:54 ` Drew Adams 2022-12-28 20:24 ` Jean Louis 2 siblings, 4 replies; 61+ messages in thread From: tomas @ 2022-12-28 12:41 UTC (permalink / raw) To: help-gnu-emacs [-- Attachment #1: Type: text/plain, Size: 713 bytes --] On Wed, Dec 28, 2022 at 12:59:23PM +0100, Michael Heerdegen wrote: > <tomas@tuxteam.de> writes: > > > I don't understand you. That function is most useful if you can > > pass it a custom comparison function. I'd say it's fine as it > > is. > > I think the interpretation of the question "Could there be a better > default comparison function?", in the sense that `eql' is a bit nicer > than `eq' for specific value types, is valid, especially when > considering that `cl-pushnew' is often used for configuration stuff or > other purposes where speed is not crucial. I see. Well, that train has sailed (or something). Backward compat (especially with user's brains) and things. Cheers -- t [-- Attachment #2: signature.asc --] [-- Type: application/pgp-signature, Size: 195 bytes --] ^ permalink raw reply [flat|nested] 61+ messages in thread
* Re: Emacs 30.0 warning from `cl-pushnew' and `memql' 2022-12-28 12:41 ` tomas @ 2022-12-28 12:45 ` Emanuel Berg 2022-12-28 13:19 ` Emanuel Berg ` (2 subsequent siblings) 3 siblings, 0 replies; 61+ messages in thread From: Emanuel Berg @ 2022-12-28 12:45 UTC (permalink / raw) To: help-gnu-emacs tomas wrote: > I see. Well, that train has sailed (or something). > Backward compat (especially with user's brains) and things. It's more intuitive that it uses a function that doesn't work for the argument just provided so the byte compiler has to warn about it? -- underground experts united https://dataswamp.org/~incal ^ permalink raw reply [flat|nested] 61+ messages in thread
* Re: Emacs 30.0 warning from `cl-pushnew' and `memql' 2022-12-28 12:41 ` tomas 2022-12-28 12:45 ` Emanuel Berg @ 2022-12-28 13:19 ` Emanuel Berg 2022-12-28 14:54 ` Emanuel Berg 2022-12-28 17:57 ` [External] : " Drew Adams 3 siblings, 0 replies; 61+ messages in thread From: Emanuel Berg @ 2022-12-28 13:19 UTC (permalink / raw) To: help-gnu-emacs tomas wrote: > I see. Well, that train has sailed (or something). > Backward compat (especially with user's brains) and things. One can also think of `equal' for lists, instead of `eql', as, as you know (equal '(1 2 3) '(1 2 3)) ; t (eql '(1 2 3) '(1 2 3)) ; nil Here is one example of that. ;;; -*- lexical-binding: t -*- ;; ;; this file: ;; https://dataswamp.org/~incal/emacs-init/psea.el (require 'cl-lib) (require 'math) (defun string-distance-percentage (str1 str2 &optional str-out) (let*((len1 (length str1)) (len2 (length str2)) (long (max len1 len2)) (dist (string-distance str1 str2)) ) (percent (- long dist) long str-out) )) (defun pattern-search (str &optional beg end) (interactive `(,(read-string "search: ") ,@(when (use-region-p) (list (region-beginning) (region-end)) ))) (or beg (setq beg (point-min))) (or end (setq end (point-max))) (cl-loop with len = (length str) for c from beg to (- end len) with hit with fallout do (setq hit (buffer-substring-no-properties c (+ c len))) (cl-pushnew (list hit (string-distance hit str) (string-distance-percentage str hit t) ) fallout :test #'equal) finally return (message "%s" (seq-take (sort fallout (lambda (a b) (< (cadr a) (cadr b)))) 5) ))) (defalias 'psea #'pattern-search) ;; (psea "history" (point-min) (+ 100 (point-min))) ;; ;; his fil 4 42.9% ;; amp.org 5 28.6% ;; this fi 5 28.6% ;; /psea.e 6 14.3% ;; nit/pse 6 14.3% -- underground experts united https://dataswamp.org/~incal ^ permalink raw reply [flat|nested] 61+ messages in thread
* Re: Emacs 30.0 warning from `cl-pushnew' and `memql' 2022-12-28 12:41 ` tomas 2022-12-28 12:45 ` Emanuel Berg 2022-12-28 13:19 ` Emanuel Berg @ 2022-12-28 14:54 ` Emanuel Berg 2022-12-29 22:31 ` Stefan Monnier via Users list for the GNU Emacs text editor 2022-12-28 17:57 ` [External] : " Drew Adams 3 siblings, 1 reply; 61+ messages in thread From: Emanuel Berg @ 2022-12-28 14:54 UTC (permalink / raw) To: help-gnu-emacs tomas wrote: >> I think the interpretation of the question "Could there be >> a better default comparison function?", in the sense that >> `eql' is a bit nicer than `eq' for specific value types, is >> valid, especially when considering that `cl-pushnew' is >> often used for configuration stuff or other purposes where >> speed is not crucial. > > I see. Well, that train has sailed (or something). > Backward compat (especially with user's brains) and things. But in a way it makes sense since if you write the code the right way for the same data, it works ... (require 'cl-lib) (let ((lst '()) (str "a") ) (cl-pushnew str lst) (cl-pushnew str lst) lst) ; ("a") (let ((lst '())) (cl-pushnew "a" lst) (cl-pushnew "a" lst) lst) ; ("a" "a") -- underground experts united https://dataswamp.org/~incal ^ permalink raw reply [flat|nested] 61+ messages in thread
* Re: Emacs 30.0 warning from `cl-pushnew' and `memql' 2022-12-28 14:54 ` Emanuel Berg @ 2022-12-29 22:31 ` Stefan Monnier via Users list for the GNU Emacs text editor 2023-01-08 4:18 ` Emanuel Berg 0 siblings, 1 reply; 61+ messages in thread From: Stefan Monnier via Users list for the GNU Emacs text editor @ 2022-12-29 22:31 UTC (permalink / raw) To: help-gnu-emacs > (let ((lst '())) > (cl-pushnew "a" lst) > (cl-pushnew "a" lst) > lst) ; ("a" "a") It may sometimes return ("a" "a") but it may also return ("a"). Case in point, I think it will do the first when interpreted and the second when compiled. Stefan ^ permalink raw reply [flat|nested] 61+ messages in thread
* Re: Emacs 30.0 warning from `cl-pushnew' and `memql' 2022-12-29 22:31 ` Stefan Monnier via Users list for the GNU Emacs text editor @ 2023-01-08 4:18 ` Emanuel Berg 2023-01-08 18:54 ` Andreas Eder 0 siblings, 1 reply; 61+ messages in thread From: Emanuel Berg @ 2023-01-08 4:18 UTC (permalink / raw) To: help-gnu-emacs Stefan Monnier via Users list for the GNU Emacs text editor wrote: >> (let ((lst '())) >> (cl-pushnew "a" lst) >> (cl-pushnew "a" lst) >> lst) ; ("a" "a") > > It may sometimes return ("a" "a") but it may also return > ("a"). Case in point, I think it will do the first when > interpreted and the second when compiled. What's the deal with all that, can it be explained easily? Why is it different? That's not a good thing, right? I always thought of compiled as just faster in execution, but computes faster ... The compiler has some optimization scheme with recurring data in space and time so the same data ends up at the same place so is just pushed once? -- underground experts united https://dataswamp.org/~incal ^ permalink raw reply [flat|nested] 61+ messages in thread
* Re: Emacs 30.0 warning from `cl-pushnew' and `memql' 2023-01-08 4:18 ` Emanuel Berg @ 2023-01-08 18:54 ` Andreas Eder 0 siblings, 0 replies; 61+ messages in thread From: Andreas Eder @ 2023-01-08 18:54 UTC (permalink / raw) To: help-gnu-emacs On So 08 Jan 2023 at 05:18, Emanuel Berg <incal@dataswamp.org> wrote: > Stefan Monnier via Users list for the GNU Emacs text editor wrote: > >>> (let ((lst '())) >>> (cl-pushnew "a" lst) >>> (cl-pushnew "a" lst) >>> lst) ; ("a" "a") >> >> It may sometimes return ("a" "a") but it may also return >> ("a"). Case in point, I think it will do the first when >> interpreted and the second when compiled. > > What's the deal with all that, can it be explained easily? > > Why is it different? > > That's not a good thing, right? I always thought of compiled > as just faster in execution, but computes faster ... > > The compiler has some optimization scheme with recurring data > in space and time so the same data ends up at the same place > so is just pushed once? I'm nit sure how it is specified to work in elisp. But for common lisp you are in undefined territory. Since '() is a constant, then after modifying lst y are generating undefined behaviour. 'Andreas ^ permalink raw reply [flat|nested] 61+ messages in thread
* RE: [External] : Re: Emacs 30.0 warning from `cl-pushnew' and `memql' 2022-12-28 12:41 ` tomas ` (2 preceding siblings ...) 2022-12-28 14:54 ` Emanuel Berg @ 2022-12-28 17:57 ` Drew Adams 2022-12-28 18:10 ` Stefan Monnier via Users list for the GNU Emacs text editor 2022-12-28 19:24 ` Emanuel Berg 3 siblings, 2 replies; 61+ messages in thread From: Drew Adams @ 2022-12-28 17:57 UTC (permalink / raw) To: tomas@tuxteam.de, help-gnu-emacs@gnu.org > > I think the interpretation of the question "Could there be a better > > default comparison function?", in the sense that `eql' is a bit nicer > > than `eq' for specific value types, is valid, especially when > > considering that `cl-pushnew' is often used for configuration stuff or > > other purposes where speed is not crucial. > > I see. Well, that train has sailed (or something). Backward compat > (especially with user's brains) and things. I think that's the wrong way to think about this. The default for `cl-pushnew' should be `eql' because the default for CL `pushnew' is `eql'. End of story. If a better default predicate exists for Elisp then Elisp should add its own `pushnew', using that better predicate as default. It shouldn't substitute that predicate as the default of `cl-pushnew'. ^ permalink raw reply [flat|nested] 61+ messages in thread
* Re: [External] : Re: Emacs 30.0 warning from `cl-pushnew' and `memql' 2022-12-28 17:57 ` [External] : " Drew Adams @ 2022-12-28 18:10 ` Stefan Monnier via Users list for the GNU Emacs text editor 2022-12-28 19:29 ` Emanuel Berg ` (2 more replies) 2022-12-28 19:24 ` Emanuel Berg 1 sibling, 3 replies; 61+ messages in thread From: Stefan Monnier via Users list for the GNU Emacs text editor @ 2022-12-28 18:10 UTC (permalink / raw) To: help-gnu-emacs > If a better default predicate exists for Elisp > then Elisp should add its own `pushnew', using > that better predicate as default. It shouldn't > substitute that predicate as the default of > `cl-pushnew'. Won't happen: - it would break compatibility with packages still using cl.el's `pushnew`. - when ELisp uses the same name as Common Lisp, there's a lot of human pressure to preserve as much as possible of the semantics. So, if we want something with a different default, we'll probably want to give it another name. Stefan ^ permalink raw reply [flat|nested] 61+ messages in thread
* Re: [External] : Re: Emacs 30.0 warning from `cl-pushnew' and `memql' 2022-12-28 18:10 ` Stefan Monnier via Users list for the GNU Emacs text editor @ 2022-12-28 19:29 ` Emanuel Berg 2022-12-28 19:35 ` Drew Adams 2022-12-28 19:36 ` tomas 2 siblings, 0 replies; 61+ messages in thread From: Emanuel Berg @ 2022-12-28 19:29 UTC (permalink / raw) To: help-gnu-emacs Stefan Monnier via Users list for the GNU Emacs text editor wrote: >> If a better default predicate exists for Elisp then Elisp >> should add its own `pushnew', using that better predicate >> as default. It shouldn't substitute that predicate as the >> default of `cl-pushnew'. > > Won't happen: > - it would break compatibility with packages still using > cl.el's `pushnew`. > - when ELisp uses the same name as Common Lisp, there's > a lot of human pressure to preserve as much as possible of > the semantics. > > So, if we want something with a different default, we'll > probably want to give it another name. `1+' -- underground experts united https://dataswamp.org/~incal ^ permalink raw reply [flat|nested] 61+ messages in thread
* RE: [External] : Re: Emacs 30.0 warning from `cl-pushnew' and `memql' 2022-12-28 18:10 ` Stefan Monnier via Users list for the GNU Emacs text editor 2022-12-28 19:29 ` Emanuel Berg @ 2022-12-28 19:35 ` Drew Adams 2022-12-28 19:36 ` tomas 2 siblings, 0 replies; 61+ messages in thread From: Drew Adams @ 2022-12-28 19:35 UTC (permalink / raw) To: Stefan Monnier, 'Help-Gnu-Emacs (help-gnu-emacs@gnu.org)' [-- Attachment #1: Type: text/plain, Size: 400 bytes --] > > If a better default predicate exists for Elisp... > So, if we want something with a different default, > we'll probably want to give it another name. Agree. I don't see the need for a different default. It's not hard to add a predicate arg. To me it makes sense to just include `pushnew' as it is (with `eql' and without `cl-'), just as was done for `push' in Emacs 22 (or 21?). [-- Attachment #2: winmail.dat --] [-- Type: application/ms-tnef, Size: 13814 bytes --] ^ permalink raw reply [flat|nested] 61+ messages in thread
* Re: [External] : Re: Emacs 30.0 warning from `cl-pushnew' and `memql' 2022-12-28 18:10 ` Stefan Monnier via Users list for the GNU Emacs text editor 2022-12-28 19:29 ` Emanuel Berg 2022-12-28 19:35 ` Drew Adams @ 2022-12-28 19:36 ` tomas 2 siblings, 0 replies; 61+ messages in thread From: tomas @ 2022-12-28 19:36 UTC (permalink / raw) To: help-gnu-emacs [-- Attachment #1: Type: text/plain, Size: 287 bytes --] On Wed, Dec 28, 2022 at 01:10:07PM -0500, Stefan Monnier via Users list for the GNU Emacs text editor wrote: [...] > So, if we want something with a different default, we'll probably want > to give it another name. cl-cl-pushnew? (no, I'm not serious ;-) Cheers -- t [-- Attachment #2: signature.asc --] [-- Type: application/pgp-signature, Size: 195 bytes --] ^ permalink raw reply [flat|nested] 61+ messages in thread
* Re: [External] : Re: Emacs 30.0 warning from `cl-pushnew' and `memql' 2022-12-28 17:57 ` [External] : " Drew Adams 2022-12-28 18:10 ` Stefan Monnier via Users list for the GNU Emacs text editor @ 2022-12-28 19:24 ` Emanuel Berg 1 sibling, 0 replies; 61+ messages in thread From: Emanuel Berg @ 2022-12-28 19:24 UTC (permalink / raw) To: help-gnu-emacs Drew Adams wrote: >> I see. Well, that train has sailed (or something). >> Backward compat (especially with user's brains) and things. > > I think that's the wrong way to think about this. > The default for `cl-pushnew' should be `eql' because the > default for CL `pushnew' is `eql'. End of story. Yeah, it gets easier that way, for sure. > If a better default predicate exists for Elisp then Elisp > should add its own `pushnew', using that better predicate > as default. Indeed, note that it doesn't have to be a matter of a single function being the one default, it can be many defaults depending on the type of the argument value. -- underground experts united https://dataswamp.org/~incal ^ permalink raw reply [flat|nested] 61+ messages in thread
* RE: [External] : Re: Emacs 30.0 warning from `cl-pushnew' and `memql' 2022-12-28 11:59 ` Michael Heerdegen 2022-12-28 12:41 ` tomas @ 2022-12-28 17:54 ` Drew Adams 2022-12-28 18:05 ` Stefan Monnier via Users list for the GNU Emacs text editor 2022-12-28 19:21 ` Emanuel Berg 2022-12-28 20:24 ` Jean Louis 2 siblings, 2 replies; 61+ messages in thread From: Drew Adams @ 2022-12-28 17:54 UTC (permalink / raw) To: Michael Heerdegen, help-gnu-emacs@gnu.org > I think the interpretation of the question "Could there be a better > default comparison function?", in the sense that `eql' is a bit nicer > than `eq' for specific value types, is valid, especially when > considering that `cl-pushnew' is often used for configuration stuff or > other purposes where speed is not crucial. If Emacs wants to have its own `pushnew' macro then its definition can and should do whatever is best for Emacs. But if Emacs wants to have a macro that emulates CL's `pushnew', and thus call it `cl-pushnew', then it should behave as much as possible like CL's `pushnew'. And that includes defaulting to using `eql'. IOW, don't think about what default predicate would be best for Elisp, for `cl-pushnew'. Think instead about what default predicate CL uses for `pushnew'. That's what emulation is about. BTW, this isn't a guideline to "protect CL" or something. It's a guideline for the benefit of Elisp: clearly identify what's CL emulation and what's not. And yes, Elisp can and perhaps should directly include some more CL macros as its own (doing whatever's best for Elisp, and not bothering to best emulate the CL version). This could apply to `pushnew'. ___ And it applies to `case', IMHO. Encouraging or coercing folks to use `pcase' or `cond' just to handle the simple and common case of `case' is overkill. ^ permalink raw reply [flat|nested] 61+ messages in thread
* Re: [External] : Re: Emacs 30.0 warning from `cl-pushnew' and `memql' 2022-12-28 17:54 ` Drew Adams @ 2022-12-28 18:05 ` Stefan Monnier via Users list for the GNU Emacs text editor 2022-12-28 19:35 ` Drew Adams 2022-12-28 19:21 ` Emanuel Berg 1 sibling, 1 reply; 61+ messages in thread From: Stefan Monnier via Users list for the GNU Emacs text editor @ 2022-12-28 18:05 UTC (permalink / raw) To: help-gnu-emacs > And it applies to `case', IMHO. Encouraging or > coercing folks to use `pcase' or `cond' just to > handle the simple and common case of `case' is > overkill. For those cases handled by `(cl-)case`, `pcase` is just as easy to use [ apparently even easier for some people who otherwise write (case FOO ('a (do-a)) ('b (do-b) ...)) ], so I don't see what's overkill about it. Stefan ^ permalink raw reply [flat|nested] 61+ messages in thread
* RE: [External] : Re: Emacs 30.0 warning from `cl-pushnew' and `memql' 2022-12-28 18:05 ` Stefan Monnier via Users list for the GNU Emacs text editor @ 2022-12-28 19:35 ` Drew Adams 2022-12-29 3:34 ` Stefan Monnier via Users list for the GNU Emacs text editor 0 siblings, 1 reply; 61+ messages in thread From: Drew Adams @ 2022-12-28 19:35 UTC (permalink / raw) To: Stefan Monnier, 'Help-Gnu-Emacs (help-gnu-emacs@gnu.org)' [-- Attachment #1: Type: text/plain, Size: 1160 bytes --] > > And it applies to `case', IMHO. Encouraging or > > coercing folks to use `pcase' or `cond' just to > > handle the simple and common case of `case' is > > overkill. > > For those cases handled by `(cl-)case`, `pcase` is just as easy to use > [ apparently even easier for some people who otherwise write (case FOO > ('a (do-a)) ('b (do-b) ...)) ], so I don't see what's overkill about it. Did you mean (case FOO (a (do-a)) (b (do-b) ...))? ^ ^ No need to quote. And no need to use `or' to match a set of values: (case FOO ((a b) (do ab)) ((c d e) (do-cde))...) And no need to fathom all the rest of pcase's complicated syntax. Complicated syntax is good when you need to do something complex. And yes, it's good to have something that handles lots of cases, even if that makes understanding the syntax complicated. But that's not a reason not to _also_ have a simple syntax for a common, simple use case. `pcase' provides the former; `case' provides the latter. IOW, I don't argue that we shouldn't have `pcase'. I don't see why we shouldn't also have `case' (sans `cl-'), that's all. [-- Attachment #2: winmail.dat --] [-- Type: application/ms-tnef, Size: 14170 bytes --] ^ permalink raw reply [flat|nested] 61+ messages in thread
* Re: [External] : Re: Emacs 30.0 warning from `cl-pushnew' and `memql' 2022-12-28 19:35 ` Drew Adams @ 2022-12-29 3:34 ` Stefan Monnier via Users list for the GNU Emacs text editor 2022-12-29 19:06 ` Drew Adams 0 siblings, 1 reply; 61+ messages in thread From: Stefan Monnier via Users list for the GNU Emacs text editor @ 2022-12-29 3:34 UTC (permalink / raw) To: help-gnu-emacs >> > And it applies to `case', IMHO. Encouraging or >> > coercing folks to use `pcase' or `cond' just to >> > handle the simple and common case of `case' is >> > overkill. >> >> For those cases handled by `(cl-)case`, `pcase` is just as easy to use >> [ apparently even easier for some people who otherwise write (case FOO >> ('a (do-a)) ('b (do-b) ...)) ], so I don't see what's overkill about it. > > Did you mean (case FOO (a (do-a)) (b (do-b) ...))? No, I did mean exactly what I wrote. > No need to quote. I know. But lots of users don't and they so quote, hence using the syntax that would be correct with `pcase` but that has a "subtly" different meaning for `cl-case`. That's what I meant by "even easier for some people". > IOW, I don't argue that we shouldn't have `pcase'. > I don't see why we shouldn't also have `case' > (sans `cl-'), that's all. What's the benefit (other than having to learn 2 subtly different things instead of just one)? Stefan ^ permalink raw reply [flat|nested] 61+ messages in thread
* RE: [External] : Re: Emacs 30.0 warning from `cl-pushnew' and `memql' 2022-12-29 3:34 ` Stefan Monnier via Users list for the GNU Emacs text editor @ 2022-12-29 19:06 ` Drew Adams 2022-12-29 19:45 ` Stefan Monnier via Users list for the GNU Emacs text editor 0 siblings, 1 reply; 61+ messages in thread From: Drew Adams @ 2022-12-29 19:06 UTC (permalink / raw) To: Stefan Monnier, 'Help-Gnu-Emacs (help-gnu-emacs@gnu.org)' [-- Attachment #1: Type: text/plain, Size: 2459 bytes --] > >> > And it applies to `case', IMHO. Encouraging or > >> > coercing folks to use `pcase' or `cond' just to > >> > handle the simple and common case of `case' is > >> > overkill. > >> > >> For those cases handled by `(cl-)case`, `pcase` > >> is just as easy to use [ apparently even easier > >> for some people who otherwise write (case FOO > >> ('a (do-a)) ('b (do-b) ...)) ], so I don't see > >> what's overkill about it. > > > > Did you mean (case FOO (a (do-a)) (b (do-b) ...))? > No, I did mean exactly what I wrote. > > No need to quote. > I know. But lots of users don't and they so quote, > hence using the syntax that would be correct with > `pcase` but that has a "subtly" different meaning > for `cl-case`. That's what I meant by "even easier > for some people". Oh, you meant that the simpler `case' syntax might be harder for some of the people who are used to the more complex syntax of `pcase', where you need to quote symbols as values to be compared. Sure, maybe so. That goes without saying. Simple can surprise if you're expecting difficult. `pcase' has to have complicated syntax because it's, well, complicated - it does much more than simply test a symbol's value with `eql'. Likewise, `cond' needs more complex syntax. That's why Lisp has `if' AND `case' AND `when' AND `or'... Shades of cl-loop-is-all-you-need-so-use-only-loop discussion. > > IOW, I don't argue that we shouldn't have `pcase'. > > I don't see why we shouldn't also have `case' > > (sans `cl-'), that's all. > > What's the benefit (other than having to learn 2 > subtly different things instead of just one)? Simpler, for simple cases. What's the benefit of having both `if' and `cond' in the language? Or both `pcase' and `cond'? Or...? Why not just learn one, and not bother with the others? **`pcase' Cider-House rules!** I can hardly believe you're asking this. `pcase' is a useful multi-tool. But sometimes you just need a tiny pen knife. You can do everything with just `if', or just `cond', or just... But why have to? No one's _obliged_ to learn `case' in addition to `pcase' (or `cond' or...). Anyone can stick with just `pcase' (or...). That you might need to learn the syntax of some language construct _IF_ you want to use it, seems obvious. And how hard is it to learn the syntax of `case' (or even of `cond') compared to that of `pcase'? Mole hill / mountain. [-- Attachment #2: winmail.dat --] [-- Type: application/ms-tnef, Size: 15222 bytes --] ^ permalink raw reply [flat|nested] 61+ messages in thread
* Re: [External] : Re: Emacs 30.0 warning from `cl-pushnew' and `memql' 2022-12-29 19:06 ` Drew Adams @ 2022-12-29 19:45 ` Stefan Monnier via Users list for the GNU Emacs text editor 2022-12-29 22:00 ` Drew Adams 0 siblings, 1 reply; 61+ messages in thread From: Stefan Monnier via Users list for the GNU Emacs text editor @ 2022-12-29 19:45 UTC (permalink / raw) To: help-gnu-emacs > Oh, you meant that the simpler `case' syntax might > be harder for some of the people who are used to > the more complex syntax of `pcase', where you need > to quote symbols as values to be compared. No, I mean that even for some people unfamiliar with `pcase` syntax, the `pcase` syntax is simpler (more natural?) than the cl-`case` syntax: the incorrect use of `quote` in `cl-case` predates the invention of `pcase` :-) >> > IOW, I don't argue that we shouldn't have `pcase'. >> > I don't see why we shouldn't also have `case' >> > (sans `cl-'), that's all. >> What's the benefit (other than having to learn 2 >> subtly different things instead of just one)? > Simpler, for simple cases. I don't think `case` is objectively simpler. More specifically, I believe that if you're familiar with neither `cl-case` nor `pcase` syntax, it's not easier to learn the `case` syntax than the subset of `pcase` syntax which covers the functionality of `cl-case`. It may even be objectively easier to learn the `pcase` syntax since it doesn't suffer from special cases like when you want to distinguish one of the `nil`, `t`, or `otherwise` values. Stefan ^ permalink raw reply [flat|nested] 61+ messages in thread
* RE: [External] : Re: Emacs 30.0 warning from `cl-pushnew' and `memql' 2022-12-29 19:45 ` Stefan Monnier via Users list for the GNU Emacs text editor @ 2022-12-29 22:00 ` Drew Adams 2022-12-29 22:25 ` Stefan Monnier via Users list for the GNU Emacs text editor 0 siblings, 1 reply; 61+ messages in thread From: Drew Adams @ 2022-12-29 22:00 UTC (permalink / raw) To: Stefan Monnier; +Cc: 'Help-Gnu-Emacs (help-gnu-emacs@gnu.org)' [-- Attachment #1: Type: text/plain, Size: 4615 bytes --] > > Oh, you meant that the simpler `case' syntax might > > be harder for some of the people who are used to > > the more complex syntax of `pcase', where you need > > to quote symbols as values to be compared. > > No, I mean that even for some people unfamiliar with `pcase` syntax, the > `pcase` syntax is simpler (more natural?) than the cl-`case` syntax: the > incorrect use of `quote` in `cl-case` predates the invention of `pcase` > :-) I think you'll need to explain your "incorrect use of `quote' in `cl-case'". There's no particular use of `quote' or quoting in `case'. Are you saying you think `case' should require users to quote symbols to test for eqlity, i.e., that CL should have defined `case' so that you need to use (case FOO ('a "AAA") (42 (value-for-42)) ; Or maybe use '42? (('c 'd 'e) (value-for-C-D-or-E)) (('f 'quote) (value-for-F-or-QUOTE)) ...) instead of this? (case FOO (a "AAA") (42 (value-for-42)) ((c d e) (value-for-C-D-or-E)) ((f quote) (value-for-F-or-QUOTE)) ...) If so, why? > >> > IOW, I don't argue that we shouldn't have `pcase'. > >> > I don't see why we shouldn't also have `case' > >> > (sans `cl-'), that's all. > >> What's the benefit (other than having to learn 2 > >> subtly different things instead of just one)? > > Simpler, for simple cases. > > I don't think `case` is objectively simpler. Please show us an example where `pcase' does only what `case' does, but with simpler syntax. > More specifically, I believe that if you're familiar > with neither `cl-case` nor `pcase` syntax, it's not > easier to learn the `case` syntax than the subset of > `pcase` syntax which covers the functionality of `cl-case`. 1. It's easier to learn, if only because you don't have to ALSO learn the non-`case' cases that `pcase' syntax covers - including patterns that both bind and match, etc. You need to at least learn enough of that other stuff to be able to _not_ fall into it when you're trying to do just what simple `case' does: test a value against some atomic values. 2. It's easier to use, for the same reason. > It may even be objectively easier to learn the > `pcase` syntax since it doesn't suffer from > special cases like when you want to distinguish > one of the `nil`, `t`, or `otherwise` values. You pepper repeat "objectively", but isn't that gratuitous? Saying it's so doesn't make it so. Show da codes, please. `t' means the same thing as in `cond'. Is it really hard to grasp? And to be "nicer", `case' also gives you the synonym `otherwise', which SHOUTS its meaning of "default", no? And you can always just use a list for the test values, including a singleton list. Nothing obliges one to take advantage of the shorthand of using just b instead of (b). KISS: always a list of things to match, or else `otherwise' for no matches: (case FOO ((a) "AAA") ((nil) "NIL") ((t) "T") ((otherwise) "Symbol `otherwise'") ((c d e) "C, D, or E") ((f quote) "F-or-QUOTE") (otherwise "Anything else (default)")) Sure, the simple, general syntax of using a list of things to match means that () or nil as the _list_ of values to match can never match (no list elements to match). Is that too complex? It's something Lisp users are used to, no? Even novice Lisp users learn early on that nil/() is both a list and a symbol. `case' isn't the only place where this needs to be understood. It's common in Lisp programs to distinguish an empty list of values from a single nil value (whether viewed as symbol or empty list), by wrapping the latter in a cons: (nil). And always using an explicit list of things to match (or else the atom `otherwise') makes it very clear that () or nil as that list is useless - no thing matches nothing. If you really think some users have trouble with the `case' syntax then just tell 'em to always use a list of things to match. Which (`case' or `pcase') seems simpler might be just a personal preference on each of our parts. Lisp provides many ways to do the same thing, including multiple control constructs (as I mentioned, and about which you apparently had nothing to say). That `pcase' can do what `case' does isn't an argument for not including `case' in Elisp. Look at all of the `*-let' stuff that's been added to Elisp over the last few years. Really needed? Clearly someone thought that was all useful for some users... [-- Attachment #2: winmail.dat --] [-- Type: application/ms-tnef, Size: 16458 bytes --] ^ permalink raw reply [flat|nested] 61+ messages in thread
* Re: [External] : Re: Emacs 30.0 warning from `cl-pushnew' and `memql' 2022-12-29 22:00 ` Drew Adams @ 2022-12-29 22:25 ` Stefan Monnier via Users list for the GNU Emacs text editor 2022-12-30 7:29 ` Drew Adams 0 siblings, 1 reply; 61+ messages in thread From: Stefan Monnier via Users list for the GNU Emacs text editor @ 2022-12-29 22:25 UTC (permalink / raw) To: help-gnu-emacs > I think you'll need to explain your "incorrect use of > `quote' in `cl-case'". I did at the very beginning: (case FOO ('a (do-a)) ('b (do-b) ...)) that's an incorrect use of quote, and such incorrect uses of quote in `cl-case` are very frequent and have been since long before `pcase` existed. Stefan ^ permalink raw reply [flat|nested] 61+ messages in thread
* RE: [External] : Re: Emacs 30.0 warning from `cl-pushnew' and `memql' 2022-12-29 22:25 ` Stefan Monnier via Users list for the GNU Emacs text editor @ 2022-12-30 7:29 ` Drew Adams 2022-12-30 18:55 ` Stefan Monnier via Users list for the GNU Emacs text editor 0 siblings, 1 reply; 61+ messages in thread From: Drew Adams @ 2022-12-30 7:29 UTC (permalink / raw) To: Stefan Monnier; +Cc: 'Help-Gnu-Emacs (help-gnu-emacs@gnu.org)' [-- Attachment #1: Type: text/plain, Size: 8371 bytes --] > > I think you'll need to explain your "incorrect > > use of `quote' in `cl-case'". > > I did at the very beginning: > (case FOO ('a (do-a)) ('b (do-b) ...)) > that's an incorrect use of quote, and such incorrect uses of quote in > `cl-case` are very frequent and have been since long before `pcase` > existed. Oh, so it's not that `case' somehow uses `quote' incorrectly. It's that some users use `case' incorrectly. I thought you were trying to say something else, sorry. I've never seen anyone misuse the `case' syntax that way, but I'm sure it's possible. But "very frequent", really? Any evidence that that's been the case for the many users of CL `case' since the mid-80s? How about comparing that user mistake with user confusion about `pcase'? Including its use to handle the simple `case' use case. [BTW, you still haven't shown the simple `case' case for `pcase', i.e., correspondences to `case' examples - e.g., those shown here so far. Weren't you planning to show how much simpler it is to use `pcase' for that use case than it is to use `case'? Let's see apples-to-apples.] But assuming you're right, do you see only Elisp users having this misunderstanding, or have you seen CL users also confused this way? Maybe it's just that the Emacs description has some room for improvement. Seems like it should be clear enough to say that you give it lists of values and `case' tries to match, using `eql', the values in those lists against the result of evaluating its first arg. The point of `case' is to (1) evaluate a sexp only once and (2) compare that value against other values, in a certain order, using `eql'. (With `cond' you need to (1) use `let' to bind the result of the sexp evaluation and (2) use `eql' or `memql' explicitly over and over.) And maybe it should say that each such list, and the values in it, are presented _as such_ in the syntax - not evaluated. E.g., not '(X Y Z), ('X 'Y 'Z), or '('X 'Y 'Z) - just plain (X Y Z). IOW, as simple as it gets. And that, for any literal values X, Y, and Z, including, yes, the symbols nil and t, and nil's synonym (). (Of course, since the predicate is `eql' it generally doesn't make much sense to use conses or atoms such as strings and vectors as the list elements - they won't be matched. But symbols, numbers, chars - such atoms like `eql' well enough. They're the use case for `case'.) The Emacs doc string for `cl-case' talks about evaluating and evaluating and evaluating... But it doesn't ever say that the values in KEYLIST are _NOT_ evaluated. Without that, I can see how someone reading that doc string might not get that that's the case. `C-h f cl-case': "Eval EXPR and choose among clauses on that value. [Clauses on a value? (Maybe it means choose "based" on that value.)] "Each clause looks like (KEYLIST BODY...). EXPR is evaluated and compared against each key in each KEYLIST; the corresponding BODY is evaluated. [Where "corresponding" means corresponding to a clause with a key that is actually `eql'...] "If no clause succeeds, cl-case returns nil. A single non-nil atom may be used in place of a KEYLIST of one atom. A KEYLIST of t or `otherwise' is allowed only in the final clause, and matches if no other keys match. Key values are compared by `eql'." [It should say that any clauses after the use of KEYLIST `t' or `otherwise' are just ignored. If they were really "allowed only in the final clause" then any clause after them would raise an error instead of being ignored.] [And actually, what about just (KEYLIST)? Does that fit the template (KEYLIST BODY...)? (KEYLIST) acts the same as (KEYLIST nil) - it returns nil if one of its keys matches. But does "BODY..." mean that BODY can be missing altogether? I can never remember the Emacs doc convention for this.] Anyway... . Eval EXPR. - check! . EXPR is evaluated. - check! . The value of EXPR is compared against each key in each KEYLIST. - Whoa! What's a key? Just what are those things in KEYLIST? Is each one a sexp that gets _evaluated_? No say nada. Bzzzzt! . The corresponding BODY is evaluated. - check! . Key matching - Whoa! What's that? . Key values are compared with `eql'. Hm, that might be understandable, if we knew what "key values" were. Does it mean the result of evaluating a key, i.e., a list element? Or does it just mean a key - a list element? The thing that seems to be missing might well be at the root of the "very frequent" mistake you report, no? What's missing here? Keys are _literal values_ to be compared ("matched") using `eql'. They are not sexps to be evaluated. Seems pretty important to point that out. Now what about the Emacs CL manual (node Conditionals) - is it any better? "This macro evaluates KEYFORM, then compares it with the key values listed in the various CLAUSEs." [It doesn't compare KEYFORM with the values. It compares the result of evaluating KEYFORM with the values. But maybe that's a nit.] "Whichever clause matches the key is executed; comparison is done by 'eql'." What does it mean for a _clause_ to match a key (a value in the KEYLIST of the clause)? "The clauses are of the form (KEYLIST BODY-FORMS...) where KEYLIST is a list of key values." A bit better than the doc string. KEYLIST "is" a list of values, not sexps to be evaluated. And KEYLIST is a (literal) list, not a sexp to be evaluated to a list. Maybe users getting confused would be better off reading the CL manual than the doc string? ___ Now let's see. What does CLTL2 tell us? https://www.cs.cmu.edu/Groups/AI/html/cltl/clm/node84.html "If KEY is in the KEYLIST (that is, is `eql' to any item in the KEYLIST)..." So KEY is something in KEYLIST (which is a list presumably). So it's a list element. "The keys in the keylists are _not_ evaluated; literal key values must appear in the keylists." Emphasis on "not". Literal values. Bingo - pretty clear! (It might also have said that KEYLIST is a literal list, not a sexp that's evaluated to give a list.) BTW, there's also this bit: "It is an error for the same key to appear in more than one clause; a consequence is that the order of the clauses does not affect the behavior of the case construct." Apparently Emacs's `cl-case' doesn't raise such an error. (To emulate CL `case' it should.) To me, the CLTL2 doc is pretty clear about the keys and the keylists not being evaluated. This gives me the idea that maybe Elisp users get confused about this and CLTL2 readers don't get confused in the way you reported. A hypothesis. ___ Coming back to the Elisp manual, `cl-case' seems to be mentioned only in the doc about `pcase'. (BTW, `cl-case' isn't in the Index, alas.) There we also say this, which I don't understand, in the section where it compares `pcase' with `cl-case'. Dunno whether it's that (1) I don't understand the English or (2) what it says is wrong. It shows a `pcase' example which starts with this: (pcase (get-return-code x) ... "With 'cl-case', you would need to explicitly declare a local variable 'code' to hold the return value of 'get-return-code'." Huh? Does that mean you need to use a variable as the first arg to `cl-case'? If so, that's not right. (defun get-return-code (arg) (if (< arg 42) 'success 'failure)) (let ((x 13)) (cl-case (get-return-code x) (success (message "Done!")) (t (message "Unknown!")))) ==> Done! And with x bound to 56, ==> Unknown! We didn't "declare a local variable ... to hold the return value of `get-return-code'." Dunno what it means to "declare" a variable in Elisp (except a vacuous defvar: (defvar x)), but a guess is that it's trying to say you need to _bind_ a local var to the value returned by (get-return-code x), and then use that variable as the first arg to `cl-case'. If so, that's not true. It's the value returned from evaluating the sexp (get-return-code x) that `cl-case' tries to match (using `eql') against symbol `success'. `cl-case' doesn't need its first arg to be a "local variable". Let me know what I'm missing here. [-- Attachment #2: winmail.dat --] [-- Type: application/ms-tnef, Size: 18670 bytes --] ^ permalink raw reply [flat|nested] 61+ messages in thread
* Re: [External] : Re: Emacs 30.0 warning from `cl-pushnew' and `memql' 2022-12-30 7:29 ` Drew Adams @ 2022-12-30 18:55 ` Stefan Monnier via Users list for the GNU Emacs text editor 2022-12-30 22:55 ` Drew Adams 0 siblings, 1 reply; 61+ messages in thread From: Stefan Monnier via Users list for the GNU Emacs text editor @ 2022-12-30 18:55 UTC (permalink / raw) To: help-gnu-emacs > But "very frequent", really? Any evidence that > that's been the case for the many users of CL > `case' since the mid-80s? The only "evidence" I have the number of such errors I've fixed over the years in other people's ELisp code. Stefan ^ permalink raw reply [flat|nested] 61+ messages in thread
* RE: [External] : Re: Emacs 30.0 warning from `cl-pushnew' and `memql' 2022-12-30 18:55 ` Stefan Monnier via Users list for the GNU Emacs text editor @ 2022-12-30 22:55 ` Drew Adams 2022-12-31 0:08 ` Stefan Monnier via Users list for the GNU Emacs text editor 0 siblings, 1 reply; 61+ messages in thread From: Drew Adams @ 2022-12-30 22:55 UTC (permalink / raw) To: Stefan Monnier; +Cc: 'Help-Gnu-Emacs (help-gnu-emacs@gnu.org)' [-- Attachment #1: Type: text/plain, Size: 1756 bytes --] > > But "very frequent", really? Any evidence that > > that's been the case for the many users of CL ^^ Common Lisp > > `case' since the mid-80s? > > The only "evidence" I have the number of such errors > I've fixed over the years in other people's ELisp code. Which isn't an indication of such for _CL_ `case', i.e., in the code of _Common Lisp_ users. Beyond being perhaps an indication that the Emacs _doc_ for `cl-case' should be improved, it sounds like no Elisp problem with `case' has been found. (Well, I did mention a bug I noticed, of `cl-case' not raising an error when CL specifies it should.) And I guess you don't have an example of using `pcase' to do what `case' does but somehow "simpler". I doubt that Elisp coders are dumber than CL coders, in general. If the former are misunderstanding the no-quoting thing then my guess is that's due to the lack of doc saying that keylists and their entries aren't evaluated. The use case of `case' is simple, yet common. We should add it to Elisp (with no `cl-' prefix). ___ Note BTW that Common Lisp even adopted _exactly_ the same thing for `typecase' as for `case'. That wasn't something inherited from other Lisps AFAIK. They could have done something different, but they chose the `case' approach, including `otherwise', `t', and _no evaluation_ of keys: "The TYPE that appears in each clause is a type specifier; it is _not evaluated but is a literal_ type specifier." Clearly they didn't see a problem with not evaling keys, and opted for a simple syntax for a simple use case. https://www.cs.cmu.edu/Groups/AI/html/cltl/clm/node84.html [-- Attachment #2: winmail.dat --] [-- Type: application/ms-tnef, Size: 15662 bytes --] ^ permalink raw reply [flat|nested] 61+ messages in thread
* Re: [External] : Re: Emacs 30.0 warning from `cl-pushnew' and `memql' 2022-12-30 22:55 ` Drew Adams @ 2022-12-31 0:08 ` Stefan Monnier via Users list for the GNU Emacs text editor 2022-12-31 2:45 ` Drew Adams 0 siblings, 1 reply; 61+ messages in thread From: Stefan Monnier via Users list for the GNU Emacs text editor @ 2022-12-31 0:08 UTC (permalink / raw) To: help-gnu-emacs >> > But "very frequent", really? Any evidence that >> > that's been the case for the many users of CL > ^^ > Common Lisp >> > `case' since the mid-80s? >> >> The only "evidence" I have the number of such errors >> I've fixed over the years in other people's ELisp code. > > Which isn't an indication of such for _CL_ `case', > i.e., in the code of _Common Lisp_ users. AFAIK this is an Emacs discussion group, so yes, I'm talking about ELisp, and I used these errors I've corrected over the years as "objective evidence" that, at least for some coders, the `pcase` syntax is more intuitive than the `cl-case` syntax (which is also the syntax of `case` in Common Lisp). So far I haven't seen anyone show any kind of "objective evidence" that the `cl-case` syntax is easier to learn or use. Just unsubstantiated statements that it's simpler as if it were just obvious. Obviously it's objectively more concise. But the argument in favor of `cl-case` has never been about concision, AFAICT, always about some notion of being easier to use. AFAICT its "simplicity" is just the fact that it's a lot more restrictive, so you can get the same simplicity by resisting the urge to use the extra features of `pcase`, without having to learn another syntax. Stefan ^ permalink raw reply [flat|nested] 61+ messages in thread
* RE: [External] : Re: Emacs 30.0 warning from `cl-pushnew' and `memql' 2022-12-31 0:08 ` Stefan Monnier via Users list for the GNU Emacs text editor @ 2022-12-31 2:45 ` Drew Adams 2022-12-31 4:53 ` Stefan Monnier via Users list for the GNU Emacs text editor 0 siblings, 1 reply; 61+ messages in thread From: Drew Adams @ 2022-12-31 2:45 UTC (permalink / raw) To: Stefan Monnier; +Cc: 'Help-Gnu-Emacs (help-gnu-emacs@gnu.org)' [-- Attachment #1: Type: text/plain, Size: 3958 bytes --] > AFAICT [`case's] "simplicity" is just the fact > that it's a lot more restrictive, so you can > get the same simplicity by resisting the > urge to use the extra features of `pcase`, > without having to learn another syntax. That's what you've been claiming, and what I've been requesting examples of. Please show, for the "restrictive" use case that `case' fulfills, corresponding examples of `case' and `pcase' that demonstrate, in your eyes, that `pcase' is simpler (or even as simple). Examples head-to-head for that simple case will show the differences. So far, you've given only non-examples of non-`case' syntax, to show the misunderstanding you've encountered. I've shown some `case' examples. Please show equivalent, but in-your-eyes simpler, `pcase' ones. Or show other examples for the same simple use-case. It's not about comparing/contrasting `case' and `pcase' in general. It's about the particular use case that `case' was designed to address. How does `pcase' excel there by being simpler? I haven't argued that `pcase' should go away. I argue that `case' is better for what it does: that simple, common, "restrictive" use case. Please show us otherwise. But more generally, and perhaps less as a matter of preference or personal taste, I argue that it's good to offer _both_ `pcase' and `case' as part of Emacs, i.e., to treat `case' the way we treat `cond', `if', `when', ... and `pcase'. I'm not surprised that some Emacs users have incorrectly thought that the keylists and keys get evaluated, and so have mistakenly quoted them - because, as I just discovered and pointed out, the Emacs _doc doesn't say_ that they're not evaluated. How is a user to know whether something gets evaluated or not by a macro, if the doc doesn't speak to that? Do we expect a user discovering a control structure to immediately macroexpand guess uses to see what the expansions give? Or to analyze the macro's definition? It's perfectly understandable that someone might just assume evaluation everywhere, especially since the doc here keeps repeating "evaluates". The only parts for which it doesn't say anything about evaluation are the parts it really needs to say something about: keys aren't evaluated. On the other hand, the Common Lisp doc points out clearly (and even emphasizes) that keys aren't evaluated. That doc difference alone could explain why you've see some Elisp users confused and mistaken, and why I've never seen that among CL users (and you apparently haven't either). Maybe the problem you've noticed was just caused by our poor `cl-case' doc. How about we fix the doc and also raise `case' to first-class citizenship along with its compatriots? ___ You haven't responded to specific points I've made - that's your right. But could you at least please speak to this, which to me seems to be a bug in the `pcase' node in the Elisp manual, where it compares `pcase' and `cl-case': It shows a `pcase' example which starts with this: (pcase (get-return-code x) ... "With 'cl-case', you would need to explicitly declare a local variable 'code' to hold the return value of 'get-return-code'." Huh? Does that mean you need to use a variable as the first arg to `cl-case'? If so, that's not right. (defun get-return-code (arg) (if (< arg 42) 'success 'failure)) (let ((x 13)) (cl-case (get-return-code x) (success (message "Done!")) (t (message "Unknown!")))) ==> Done! And with x bound to 56, ==> Unknown! We didn't "declare a local variable ... to hold the return value of `get-return-code'." ... It's the value returned from evaluating the sexp (get-return-code x) that `cl-case' tries to match (using `eql') against symbol `success'. `cl-case' doesn't need its first arg to be a "local variable". Let me know what I'm missing here. [-- Attachment #2: winmail.dat --] [-- Type: application/ms-tnef, Size: 17074 bytes --] ^ permalink raw reply [flat|nested] 61+ messages in thread
* Re: [External] : Re: Emacs 30.0 warning from `cl-pushnew' and `memql' 2022-12-31 2:45 ` Drew Adams @ 2022-12-31 4:53 ` Stefan Monnier via Users list for the GNU Emacs text editor 0 siblings, 0 replies; 61+ messages in thread From: Stefan Monnier via Users list for the GNU Emacs text editor @ 2022-12-31 4:53 UTC (permalink / raw) To: help-gnu-emacs > That's what you've been claiming, and what I've > been requesting examples of. Please show, for > the "restrictive" use case that `case' fulfills, > corresponding examples of `case' and `pcase' > that demonstrate, in your eyes, that `pcase' is > simpler (or even as simple). You've got it backwards. The onus is on you to demonstrate that `cl-case` syntax is simpler. You're the one who advocates to have both `pcase` and `cl-case`, based on the unsubstantiated claim that `cl-case`s syntax is simpler: > And yes, it's good to have something that handles lots of cases, even > if that makes understanding the syntax complicated. But that's not > a reason not to _also_ have a simple syntax for a common, simple use > case. `pcase' provides the former; `case' provides the latter. Stefan ^ permalink raw reply [flat|nested] 61+ messages in thread
* Re: [External] : Re: Emacs 30.0 warning from `cl-pushnew' and `memql' 2022-12-28 17:54 ` Drew Adams 2022-12-28 18:05 ` Stefan Monnier via Users list for the GNU Emacs text editor @ 2022-12-28 19:21 ` Emanuel Berg 1 sibling, 0 replies; 61+ messages in thread From: Emanuel Berg @ 2022-12-28 19:21 UTC (permalink / raw) To: help-gnu-emacs Drew Adams wrote: > If Emacs wants to have its own `pushnew' macro then its > definition can and should do whatever is best for Emacs. > But if Emacs wants to have a macro that emulates CL's > `pushnew', and thus call it `cl-pushnew', then it should > behave as much as possible like CL's `pushnew'. And that > includes defaulting to using `eql' [...] In so many words, yes. > Encouraging or coercing folks to use `pcase' or `cond' just > to handle the simple and common case of `case' is overkill. Agreed, let's do it! Overkill is our middle name ... https://www.youtube.com/watch?v=pbWLvwE8zfw -- underground experts united https://dataswamp.org/~incal ^ permalink raw reply [flat|nested] 61+ messages in thread
* Re: Emacs 30.0 warning from `cl-pushnew' and `memql' 2022-12-28 11:59 ` Michael Heerdegen 2022-12-28 12:41 ` tomas 2022-12-28 17:54 ` Drew Adams @ 2022-12-28 20:24 ` Jean Louis 2022-12-28 20:56 ` Emanuel Berg ` (2 more replies) 2 siblings, 3 replies; 61+ messages in thread From: Jean Louis @ 2022-12-28 20:24 UTC (permalink / raw) To: Michael Heerdegen; +Cc: help-gnu-emacs * Michael Heerdegen <michael_heerdegen@web.de> [2022-12-28 15:01]: > I think the interpretation of the question "Could there be a better > default comparison function?", in the sense that `eql' is a bit nicer > than `eq' for specific value types, is valid, especially when > considering that `cl-pushnew' is often used for configuration stuff or > other purposes where speed is not crucial. Michael, what is the fastest way to add element on stack of the list elements? Let us say I am adding only strings, would this be faster than `push': (setq my-list '()) (setq my-list (cons (quote "Word") my-list)) By the way, how do I go to make this right? ------------------------------------------- (setq my-list '()) (benchmark 1000 (setq my-list (cons "My string" my-list))) as it gives error that "My string" is invalid function. Do I need to do something like: (benchmark 1000 (prog1 nil (setq my-list (cons (quote "Word") my-list)))) (benchmark 10000000 (prog1 nil (setq my-list (cons (quote "Word") my-list)))) ➜ "Elapsed time: 0.823678s" (benchmark 10000000 (prog1 nil (push "Word" my-list))) ➜ "Elapsed time: 0.824388s" So there is no much difference apparently. -- Jean Take action in Free Software Foundation campaigns: https://www.fsf.org/campaigns In support of Richard M. Stallman https://stallmansupport.org/ ^ permalink raw reply [flat|nested] 61+ messages in thread
* Re: Emacs 30.0 warning from `cl-pushnew' and `memql' 2022-12-28 20:24 ` Jean Louis @ 2022-12-28 20:56 ` Emanuel Berg 2022-12-28 21:24 ` [External] : " Drew Adams 2022-12-29 10:39 ` Michael Heerdegen 2 siblings, 0 replies; 61+ messages in thread From: Emanuel Berg @ 2022-12-28 20:56 UTC (permalink / raw) To: help-gnu-emacs Jean Louis wrote: > (benchmark 10000000 (prog1 nil > (setq my-list (cons (quote "Word") my-list)))) > → "Elapsed time: 0.823678s" > > (benchmark 10000000 (prog1 nil > (push "Word" my-list))) > → "Elapsed time: 0.824388s" Don't hard-code that (** 10 7) ... > So there is no much difference apparently. You can try with this as well ... (defmacro measure-time (&rest body) "Measure and return the running time of the code block. http://nullprogram.com/blog/2009/05/28/" (declare (indent defun)) (let ((start (make-symbol "start"))) `(let ((,start (float-time))) ,@body (- (float-time) ,start) ))) -- underground experts united https://dataswamp.org/~incal ^ permalink raw reply [flat|nested] 61+ messages in thread
* RE: [External] : Re: Emacs 30.0 warning from `cl-pushnew' and `memql' 2022-12-28 20:24 ` Jean Louis 2022-12-28 20:56 ` Emanuel Berg @ 2022-12-28 21:24 ` Drew Adams 2022-12-28 22:47 ` Jean Louis 2022-12-29 10:39 ` Michael Heerdegen 2 siblings, 1 reply; 61+ messages in thread From: Drew Adams @ 2022-12-28 21:24 UTC (permalink / raw) To: Jean Louis, Michael Heerdegen; +Cc: help-gnu-emacs@gnu.org > Michael, what is the fastest way to add element on stack of the list > elements? > > Let us say I am adding only strings, would this be faster than `push': > > (setq my-list '()) > (setq my-list (cons (quote "Word") my-list)) I'm not Michael, but (push "Word" my-list) expands to just that code. So no, neither is faster. (macroexpand-1 '(push "Word" mylist)) ;; ==> (setq mylist (cons "Word" mylist)) (And no reason to quote either () or a literal string.) ^ permalink raw reply [flat|nested] 61+ messages in thread
* Re: [External] : Re: Emacs 30.0 warning from `cl-pushnew' and `memql' 2022-12-28 21:24 ` [External] : " Drew Adams @ 2022-12-28 22:47 ` Jean Louis 2022-12-28 23:48 ` Emanuel Berg 2022-12-29 6:03 ` tomas 0 siblings, 2 replies; 61+ messages in thread From: Jean Louis @ 2022-12-28 22:47 UTC (permalink / raw) To: Drew Adams; +Cc: Michael Heerdegen, help-gnu-emacs@gnu.org * Drew Adams <drew.adams@oracle.com> [2022-12-29 00:24]: > > Michael, what is the fastest way to add element on stack of the list > > elements? > > > > Let us say I am adding only strings, would this be faster than `push': > > > > (setq my-list '()) > > (setq my-list (cons (quote "Word") my-list)) > > > I'm not Michael, but (push "Word" my-list) expands > to just that code. So no, neither is faster. > > (macroexpand-1 '(push "Word" mylist)) > > ;; ==> (setq mylist (cons "Word" mylist)) Thanks. > (And no reason to quote either () or a literal string.) There was reason. See here: (setq my-list '()) (benchmark 1000 (setq my-list (cons "Word" my-list))) Debugger entered--Lisp error: (invalid-function "Word") ("Word") (closure (t) nil ("Word"))() benchmark-call((closure (t) nil ("Word")) 1000) benchmark(1000 ("Word")) eval((benchmark 1000 (setq my-list (cons "Word" my-list))) nil) elisp--eval-last-sexp(nil) eval-last-sexp(nil) funcall-interactively(eval-last-sexp nil) call-interactively(eval-last-sexp nil nil) command-execute(eval-last-sexp) but then `benchmark` worked only first time, second time it gave error. -- Jean Take action in Free Software Foundation campaigns: https://www.fsf.org/campaigns In support of Richard M. Stallman https://stallmansupport.org/ ^ permalink raw reply [flat|nested] 61+ messages in thread
* Re: [External] : Re: Emacs 30.0 warning from `cl-pushnew' and `memql' 2022-12-28 22:47 ` Jean Louis @ 2022-12-28 23:48 ` Emanuel Berg 2022-12-29 6:03 ` tomas 1 sibling, 0 replies; 61+ messages in thread From: Emanuel Berg @ 2022-12-28 23:48 UTC (permalink / raw) To: help-gnu-emacs Jean Louis wrote: > (setq my-list '()) > (benchmark 1000 (setq my-list (cons "Word" my-list))) If you use `let' here one can `eval-last-sexp' (which I have M-9) right in the Gnus article buffer ... -- underground experts united https://dataswamp.org/~incal ^ permalink raw reply [flat|nested] 61+ messages in thread
* Re: [External] : Re: Emacs 30.0 warning from `cl-pushnew' and `memql' 2022-12-28 22:47 ` Jean Louis 2022-12-28 23:48 ` Emanuel Berg @ 2022-12-29 6:03 ` tomas 2022-12-29 6:59 ` Emanuel Berg ` (4 more replies) 1 sibling, 5 replies; 61+ messages in thread From: tomas @ 2022-12-29 6:03 UTC (permalink / raw) To: help-gnu-emacs; +Cc: Drew Adams, Michael Heerdegen [-- Attachment #1: Type: text/plain, Size: 1217 bytes --] On Thu, Dec 29, 2022 at 01:47:57AM +0300, Jean Louis wrote: [...] > > (And no reason to quote either () or a literal string.) > > There was reason. See here: > > (setq my-list '()) > (benchmark 1000 (setq my-list (cons "Word" my-list))) > > Debugger entered--Lisp error: (invalid-function "Word") > ("Word") > (closure (t) nil ("Word"))() [...] > but then `benchmark` worked only first time, second time it gave > error. Read benchmark's doc string carefully :-) Benchmark is a /function/, so its argument is evaluated first. By the Rule of Lisp [1], args are evaluated first... (benchmark (cons "Word" my-list)) => (benchmark ("Word")) => ; since list is empty ... and then it tries to evaluate the function application ("Word"), which explains your error message. If now you look again at the benchmark's docstring it says to provide a form. This means you have to quote the whole thing like so: (benchmark 1000 '(setq my-list (cons "word" my-list))) If you just quote "Word", you are benchmarking the wrong thing, anyway :) Cheers [1] aka "strict order evaluation" https://en.wikipedia.org/wiki/Evaluation_strategy#Strict_evaluation -- t [-- Attachment #2: signature.asc --] [-- Type: application/pgp-signature, Size: 195 bytes --] ^ permalink raw reply [flat|nested] 61+ messages in thread
* Re: [External] : Re: Emacs 30.0 warning from `cl-pushnew' and `memql' 2022-12-29 6:03 ` tomas @ 2022-12-29 6:59 ` Emanuel Berg 2022-12-29 7:08 ` Emanuel Berg ` (3 subsequent siblings) 4 siblings, 0 replies; 61+ messages in thread From: Emanuel Berg @ 2022-12-29 6:59 UTC (permalink / raw) To: help-gnu-emacs tomas wrote: > Benchmark is a /function/, so its argument is evaluated > first. By the Rule of Lisp args are evaluated first [...] > aka "strict order evaluation" > > https://en.wikipedia.org/wiki/Evaluation_strategy#Strict_evaluation Sure but ... how else would you do it? -- underground experts united https://dataswamp.org/~incal ^ permalink raw reply [flat|nested] 61+ messages in thread
* Re: [External] : Re: Emacs 30.0 warning from `cl-pushnew' and `memql' 2022-12-29 6:03 ` tomas 2022-12-29 6:59 ` Emanuel Berg @ 2022-12-29 7:08 ` Emanuel Berg 2022-12-29 7:19 ` Emanuel Berg ` (2 subsequent siblings) 4 siblings, 0 replies; 61+ messages in thread From: Emanuel Berg @ 2022-12-29 7:08 UTC (permalink / raw) To: help-gnu-emacs tomas wrote: > args are evaluated first And from left to right :) (defun dis () (let ((do-as "Disintegration as a Service")) do-as) ) (dis (message "Access to the Lisp planet") (/ 1 0)) (dis (/ 1 0) (message "bz-7z [static]")) -- underground experts united https://dataswamp.org/~incal ^ permalink raw reply [flat|nested] 61+ messages in thread
* Re: [External] : Re: Emacs 30.0 warning from `cl-pushnew' and `memql' 2022-12-29 6:03 ` tomas 2022-12-29 6:59 ` Emanuel Berg 2022-12-29 7:08 ` Emanuel Berg @ 2022-12-29 7:19 ` Emanuel Berg 2022-12-29 22:41 ` Drew Adams 2022-12-30 6:35 ` tomas 2022-12-29 9:18 ` Jean Louis 2022-12-29 14:47 ` Stefan Monnier via Users list for the GNU Emacs text editor 4 siblings, 2 replies; 61+ messages in thread From: Emanuel Berg @ 2022-12-29 7:19 UTC (permalink / raw) To: help-gnu-emacs tomas wrote: > Benchmark is a /function/, so its argument is evaluated > first. By the Rule of Lisp [1], args are evaluated first... Applicative order AKA strict evaluation: a function is undefined if any of its arguments are. So in practice, that means they are computed first. And that makes sense! Since a function f(x, y) is very much a function of x and y ... -- underground experts united https://dataswamp.org/~incal ^ permalink raw reply [flat|nested] 61+ messages in thread
* RE: [External] : Re: Emacs 30.0 warning from `cl-pushnew' and `memql' 2022-12-29 7:19 ` Emanuel Berg @ 2022-12-29 22:41 ` Drew Adams 2022-12-30 23:03 ` Emanuel Berg 2022-12-30 6:35 ` tomas 1 sibling, 1 reply; 61+ messages in thread From: Drew Adams @ 2022-12-29 22:41 UTC (permalink / raw) To: Emanuel Berg, help-gnu-emacs@gnu.org > Applicative order AKA strict evaluation: a function is > undefined if any of its arguments are. > > So in practice, that means they are computed first. > > And that makes sense! Since a function f(x, y) is very much > a function of x and y ... Uh, being a function of x and y doesn't imply that both x and y always need to be known (calculated). `if' is a function of all of its args, but in some cases it need not evaluate all of them. Same with `*': if one of the args is zero then no need to calculate the others. Etc. With normal order evaluation you can evaluate only the args that are needed, based on what those args are. For instance, with applicative order you can't define `if' as a function. With normal order you can. With applicative order some calculations never end (bottom), while the same function definition might end with normal order. And besides never ending, with appl. order you can do a lot of unnecessary calculation - for args that the function doesn't end up using. In general, applicative order is a kludge. But it's a simple one, and generally efficient. To make normal order etc. evaluation efficient you need to make it _fully_ lazy: don't copy or evaluate the same expression multiple times, but use graph reduction (sharing) instead. ^ permalink raw reply [flat|nested] 61+ messages in thread
* Re: [External] : Re: Emacs 30.0 warning from `cl-pushnew' and `memql' 2022-12-29 22:41 ` Drew Adams @ 2022-12-30 23:03 ` Emanuel Berg 0 siblings, 0 replies; 61+ messages in thread From: Emanuel Berg @ 2022-12-30 23:03 UTC (permalink / raw) To: help-gnu-emacs Drew Adams wrote: >> Applicative order AKA strict evaluation: a function is >> undefined if any of its arguments are. >> >> So in practice, that means they are computed first. >> >> And that makes sense! Since a function f(x, y) is very much >> a function of x and y ... > > Uh, being a function of x and y doesn't imply that both > x and y always need to be known (calculated). > > `if' is a function of all of its args, but in some cases it > need not evaluate all of them. Not unlike the Stanley Cup Playoffs - they are best-of-7, not first-to-4. Or wait ... should it be the other way around? > Same with `*': if one of the args is zero then no need to > calculate the others. Etc. `or' short-circuiting for that matter. > To make normal order etc. evaluation efficient you need to > make it _fully_ lazy: don't copy or evaluate the same > expression multiple times, but use graph reduction > (sharing) instead. Disintegrate everything to fragments. Filter out duplicates and compute. Put it back together, with copies for the blanks? -- underground experts united https://dataswamp.org/~incal ^ permalink raw reply [flat|nested] 61+ messages in thread
* Re: [External] : Re: Emacs 30.0 warning from `cl-pushnew' and `memql' 2022-12-29 7:19 ` Emanuel Berg 2022-12-29 22:41 ` Drew Adams @ 2022-12-30 6:35 ` tomas 1 sibling, 0 replies; 61+ messages in thread From: tomas @ 2022-12-30 6:35 UTC (permalink / raw) To: help-gnu-emacs [-- Attachment #1: Type: text/plain, Size: 560 bytes --] On Thu, Dec 29, 2022 at 08:19:06AM +0100, Emanuel Berg wrote: > tomas wrote: > > > Benchmark is a /function/, so its argument is evaluated > > first. By the Rule of Lisp [1], args are evaluated first... > > Applicative order AKA strict evaluation: a function is > undefined if any of its arguments are. > > So in practice, that means they are computed first. > > And that makes sense! Since a function f(x, y) is very much > a function of x and y ... Lazy evaluation makes sense, too. It's just not how Emacs Lisp works. Cheers -- t [-- Attachment #2: signature.asc --] [-- Type: application/pgp-signature, Size: 195 bytes --] ^ permalink raw reply [flat|nested] 61+ messages in thread
* Re: [External] : Re: Emacs 30.0 warning from `cl-pushnew' and `memql' 2022-12-29 6:03 ` tomas ` (2 preceding siblings ...) 2022-12-29 7:19 ` Emanuel Berg @ 2022-12-29 9:18 ` Jean Louis 2022-12-29 10:04 ` Emanuel Berg ` (2 more replies) 2022-12-29 14:47 ` Stefan Monnier via Users list for the GNU Emacs text editor 4 siblings, 3 replies; 61+ messages in thread From: Jean Louis @ 2022-12-29 9:18 UTC (permalink / raw) To: tomas; +Cc: help-gnu-emacs, Drew Adams, Michael Heerdegen Thanks Thomas, after following your corrections: (setq my-list '()) ➜ nil (benchmark 10000000 '(setq my-list (cons "Word" my-list))) ➜ "Elapsed time: 5.943843s (4.111302s in 3 GCs)" It works! > Read benchmark's doc string carefully :-) My misunderstanding is with FORM and BODY, when I read FORM, I understand it is same as BODY. Now I see the difference. I have found reference in Emacs Lisp manual, but I cannot find reference that FORM as argument means quoted sexp, if you have that reference, let me know -- Jean Take action in Free Software Foundation campaigns: https://www.fsf.org/campaigns In support of Richard M. Stallman https://stallmansupport.org/ ^ permalink raw reply [flat|nested] 61+ messages in thread
* Re: [External] : Re: Emacs 30.0 warning from `cl-pushnew' and `memql' 2022-12-29 9:18 ` Jean Louis @ 2022-12-29 10:04 ` Emanuel Berg 2022-12-29 10:12 ` tomas 2022-12-29 10:36 ` Michael Heerdegen 2 siblings, 0 replies; 61+ messages in thread From: Emanuel Berg @ 2022-12-29 10:04 UTC (permalink / raw) To: help-gnu-emacs Jean Louis wrote: >> Read benchmark's doc string carefully :-) > > My misunderstanding is with FORM and BODY, when I read FORM, > I understand it is same as BODY. Now I see the difference. > > I have found reference in Emacs Lisp manual, but I cannot > find reference that FORM as argument means quoted sexp Yeah, I've seen this mistake many times ... If it says it is a function the args are eval'd, if it is a macro they aren't. C-h f benchmark RET `benchmark' is an autoloaded interactive native-compiled Lisp function A bit further down it says also says For non-interactive use see also `benchmark-run' C-h f benchmark-run RET `benchmark-run' is an autoloaded Lisp macro Compare (let ((cnt 0)) (benchmark 5 (cl-incf cnt)) cnt) ; 1 (let ((cnt 0)) (benchmark-run 5 (cl-incf cnt)) cnt) ; 5 -- underground experts united https://dataswamp.org/~incal ^ permalink raw reply [flat|nested] 61+ messages in thread
* Re: [External] : Re: Emacs 30.0 warning from `cl-pushnew' and `memql' 2022-12-29 9:18 ` Jean Louis 2022-12-29 10:04 ` Emanuel Berg @ 2022-12-29 10:12 ` tomas 2022-12-29 10:20 ` Emanuel Berg 2022-12-29 10:26 ` Emanuel Berg 2022-12-29 10:36 ` Michael Heerdegen 2 siblings, 2 replies; 61+ messages in thread From: tomas @ 2022-12-29 10:12 UTC (permalink / raw) To: help-gnu-emacs, Drew Adams, Michael Heerdegen [-- Attachment #1: Type: text/plain, Size: 1267 bytes --] On Thu, Dec 29, 2022 at 12:18:01PM +0300, Jean Louis wrote: > Thanks Thomas, after following your corrections: > > (setq my-list '()) ➜ nil > (benchmark 10000000 '(setq my-list (cons "Word" my-list))) ➜ "Elapsed time: 5.943843s (4.111302s in 3 GCs)" > > It works! > > > Read benchmark's doc string carefully :-) > > My misunderstanding is with FORM and BODY, when I read FORM, I > understand it is same as BODY. Now I see the difference. > > I have found reference in Emacs Lisp manual, but I cannot find > reference that FORM as argument means quoted sexp, if you have that > reference, let me know It's a bit subtle, since the point is rather the intention than the data type itself (the result of an evaluation is itself a form after all -- that's the magic of Lisp). The next I came to it (I searched Elisp's manual with `i' then `form' is "10.1 Introduction to Evaluation": A Lisp object that is intended for evaluation is called a “form” or “expression”(1). The fact that forms are data objects and not merely text is one of the fundamental differences between Lisp-like languages and typical programming languages. Any object can be evaluated [...] Worth reading :) Cheers -- t [-- Attachment #2: signature.asc --] [-- Type: application/pgp-signature, Size: 195 bytes --] ^ permalink raw reply [flat|nested] 61+ messages in thread
* Re: [External] : Re: Emacs 30.0 warning from `cl-pushnew' and `memql' 2022-12-29 10:12 ` tomas @ 2022-12-29 10:20 ` Emanuel Berg 2022-12-29 10:26 ` Emanuel Berg 1 sibling, 0 replies; 61+ messages in thread From: Emanuel Berg @ 2022-12-29 10:20 UTC (permalink / raw) To: help-gnu-emacs tomas wrote: > It's a bit subtle, since the point is rather the intention > than the data type itself (the result of an evaluation is > itself a form after all -- that's the magic of Lisp). > > The next I came to it (I searched Elisp's manual with `i' > then `form' is "10.1 Introduction to Evaluation": > > A Lisp object that is intended for evaluation is called > a “form” or “expression”(1). The fact that forms are data > objects and not merely text is one of the fundamental > differences between Lisp-like languages and typical > programming languages. Any object can be evaluated [...] > > Worth reading :) I'd like to read every book on Lisp there is ... from where do I order them? I have read these two [last], and another one in Swedish (very short), and the Emacs 18 manual. Add to the Lisp book list! (Also add ambitious PDFs with URLs.) I can help add them, actually, just send the books or other documents here, no problem. Emanuel Berg Ekebyv 21 752 63 Uppsala Sweden %%%% Lisp @book{land-of-lisp, author = {Conrad Barski}, isbn = 1593272812, publisher = {No Starch}, title = {Land of Lisp}, year = {2010} } @book{lispcraft, author = {Robert Wilensky}, isbn = 0393954420, publisher = {Norton}, title = {LISPcraft}, year = {1984} } -- underground experts united https://dataswamp.org/~incal ^ permalink raw reply [flat|nested] 61+ messages in thread
* Re: [External] : Re: Emacs 30.0 warning from `cl-pushnew' and `memql' 2022-12-29 10:12 ` tomas 2022-12-29 10:20 ` Emanuel Berg @ 2022-12-29 10:26 ` Emanuel Berg 1 sibling, 0 replies; 61+ messages in thread From: Emanuel Berg @ 2022-12-29 10:26 UTC (permalink / raw) To: help-gnu-emacs Also, bold mathematician and contributor to gnu.emacs.help Marcin ‘mbork’ Borkowski has written a book on Emacs and Elisp ... B) https://mbork.pl/2022-08-01_Making_secrets_with_Emacs -- underground experts united https://dataswamp.org/~incal ^ permalink raw reply [flat|nested] 61+ messages in thread
* Re: [External] : Re: Emacs 30.0 warning from `cl-pushnew' and `memql' 2022-12-29 9:18 ` Jean Louis 2022-12-29 10:04 ` Emanuel Berg 2022-12-29 10:12 ` tomas @ 2022-12-29 10:36 ` Michael Heerdegen 2 siblings, 0 replies; 61+ messages in thread From: Michael Heerdegen @ 2022-12-29 10:36 UTC (permalink / raw) To: help-gnu-emacs Jean Louis <bugs@gnu.support> writes: > I have found reference in Emacs Lisp manual, but I cannot find > reference that FORM as argument means quoted sexp, if you have that > reference, let me know No. The crucial point has already been mentioned: `benchmark' is a function, so you specify an expression that evaluates to the form you want to benchmark. Function arguments are evaluated before being passed to the function. Michael. ^ permalink raw reply [flat|nested] 61+ messages in thread
* Re: [External] : Re: Emacs 30.0 warning from `cl-pushnew' and `memql' 2022-12-29 6:03 ` tomas ` (3 preceding siblings ...) 2022-12-29 9:18 ` Jean Louis @ 2022-12-29 14:47 ` Stefan Monnier via Users list for the GNU Emacs text editor 4 siblings, 0 replies; 61+ messages in thread From: Stefan Monnier via Users list for the GNU Emacs text editor @ 2022-12-29 14:47 UTC (permalink / raw) To: help-gnu-emacs >> but then `benchmark` worked only first time, second time it gave >> error. > > Read benchmark's doc string carefully :-) > > Benchmark is a /function/, so its argument is evaluated first. By > the Rule of Lisp [1], args are evaluated first... > > (benchmark (cons "Word" my-list)) => > (benchmark ("Word")) => ; since list is empty Indeed, it's a terrible interface, since it forces the use of quoted code, yuck! Stefan ^ permalink raw reply [flat|nested] 61+ messages in thread
* Re: Emacs 30.0 warning from `cl-pushnew' and `memql' 2022-12-28 20:24 ` Jean Louis 2022-12-28 20:56 ` Emanuel Berg 2022-12-28 21:24 ` [External] : " Drew Adams @ 2022-12-29 10:39 ` Michael Heerdegen 2 siblings, 0 replies; 61+ messages in thread From: Michael Heerdegen @ 2022-12-29 10:39 UTC (permalink / raw) To: help-gnu-emacs Jean Louis <bugs@gnu.support> writes: > Let us say I am adding only strings, would this be faster than `push': > > (setq my-list '()) > (setq my-list (cons (quote "Word") my-list)) `push' forms expand to code like this. `cl-pushnew' is slower because of the additional tests. Michael. ^ permalink raw reply [flat|nested] 61+ messages in thread
* Re: Emacs 30.0 warning from `cl-pushnew' and `memql' 2022-12-28 6:25 ` tomas 2022-12-28 11:59 ` Michael Heerdegen @ 2022-12-28 12:44 ` Emanuel Berg 1 sibling, 0 replies; 61+ messages in thread From: Emanuel Berg @ 2022-12-28 12:44 UTC (permalink / raw) To: help-gnu-emacs tomas wrote: >> This does not render the warning >> >> (cl-pushnew "/usr/share/emacs/site-lisp/elpa-src/slime-2.26.1" >> load-path >> :test #'string=) >> >> but this is not a model I can endorse, this is why you have that >> level of abstraction to begin with, i.e., not to be bothered all >> the time with implementation details. > > I don't understand you. That function is most useful if you can > pass it a custom comparison function. I'd say it's fine as it is. It's a useful thing to be able to do to but it could default to a comparison function that works for the data type of the submitted argument, in this case `string=' for the string. -- underground experts united https://dataswamp.org/~incal ^ permalink raw reply [flat|nested] 61+ messages in thread
end of thread, other threads:[~2023-01-08 18:54 UTC | newest] Thread overview: 61+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2022-12-26 20:38 Emacs 30.0 warning from `cl-pushnew' and `memql' Emanuel Berg 2022-12-27 6:56 ` Jean Louis 2022-12-27 10:28 ` Michael Heerdegen 2022-12-27 11:33 ` Emanuel Berg 2022-12-27 11:39 ` Emanuel Berg 2022-12-28 3:23 ` [External] : " Drew Adams 2022-12-28 4:23 ` Emanuel Berg 2022-12-29 22:27 ` Drew Adams 2022-12-30 22:27 ` Emanuel Berg 2022-12-30 6:30 ` tomas 2022-12-28 6:25 ` tomas 2022-12-28 11:59 ` Michael Heerdegen 2022-12-28 12:41 ` tomas 2022-12-28 12:45 ` Emanuel Berg 2022-12-28 13:19 ` Emanuel Berg 2022-12-28 14:54 ` Emanuel Berg 2022-12-29 22:31 ` Stefan Monnier via Users list for the GNU Emacs text editor 2023-01-08 4:18 ` Emanuel Berg 2023-01-08 18:54 ` Andreas Eder 2022-12-28 17:57 ` [External] : " Drew Adams 2022-12-28 18:10 ` Stefan Monnier via Users list for the GNU Emacs text editor 2022-12-28 19:29 ` Emanuel Berg 2022-12-28 19:35 ` Drew Adams 2022-12-28 19:36 ` tomas 2022-12-28 19:24 ` Emanuel Berg 2022-12-28 17:54 ` Drew Adams 2022-12-28 18:05 ` Stefan Monnier via Users list for the GNU Emacs text editor 2022-12-28 19:35 ` Drew Adams 2022-12-29 3:34 ` Stefan Monnier via Users list for the GNU Emacs text editor 2022-12-29 19:06 ` Drew Adams 2022-12-29 19:45 ` Stefan Monnier via Users list for the GNU Emacs text editor 2022-12-29 22:00 ` Drew Adams 2022-12-29 22:25 ` Stefan Monnier via Users list for the GNU Emacs text editor 2022-12-30 7:29 ` Drew Adams 2022-12-30 18:55 ` Stefan Monnier via Users list for the GNU Emacs text editor 2022-12-30 22:55 ` Drew Adams 2022-12-31 0:08 ` Stefan Monnier via Users list for the GNU Emacs text editor 2022-12-31 2:45 ` Drew Adams 2022-12-31 4:53 ` Stefan Monnier via Users list for the GNU Emacs text editor 2022-12-28 19:21 ` Emanuel Berg 2022-12-28 20:24 ` Jean Louis 2022-12-28 20:56 ` Emanuel Berg 2022-12-28 21:24 ` [External] : " Drew Adams 2022-12-28 22:47 ` Jean Louis 2022-12-28 23:48 ` Emanuel Berg 2022-12-29 6:03 ` tomas 2022-12-29 6:59 ` Emanuel Berg 2022-12-29 7:08 ` Emanuel Berg 2022-12-29 7:19 ` Emanuel Berg 2022-12-29 22:41 ` Drew Adams 2022-12-30 23:03 ` Emanuel Berg 2022-12-30 6:35 ` tomas 2022-12-29 9:18 ` Jean Louis 2022-12-29 10:04 ` Emanuel Berg 2022-12-29 10:12 ` tomas 2022-12-29 10:20 ` Emanuel Berg 2022-12-29 10:26 ` Emanuel Berg 2022-12-29 10:36 ` Michael Heerdegen 2022-12-29 14:47 ` Stefan Monnier via Users list for the GNU Emacs text editor 2022-12-29 10:39 ` Michael Heerdegen 2022-12-28 12:44 ` Emanuel Berg
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).