* bug#34852: 26.1; seq-intersection ignores nil as element @ 2019-03-14 2:16 Miguel V. S. Frasson 2019-03-14 12:07 ` Michael Heerdegen 2019-03-14 12:22 ` Basil L. Contovounesios 0 siblings, 2 replies; 43+ messages in thread From: Miguel V. S. Frasson @ 2019-03-14 2:16 UTC (permalink / raw) To: 34852 Hi. seq-intersection skips nil as common element, so returns wrong result. Reproducing from emacs -Q: In *scratch* buffer, eval the expressions (progn (require 'seq) (seq-intersection '(1 2 nil) '(1 nil) 'eq)) -> (1) (seq-intersection '(1 2 nil) '(1 nil) 'equal) -> (1) Expected result in both cases: (1 nil) Cheers Miguel Frasson -- In GNU Emacs 26.1 (build 1, i686-w64-mingw32) of 2018-05-30 built on CIRROCUMULUS Repository revision: 07f8f9bc5a51f5aa94eb099f3e15fbe0c20ea1ea Windowing system distributor 'Microsoft Corp.', version 10.0.17134 Recent messages: For information about GNU Emacs and the GNU system, type C-h C-a. seq Configured using: 'configure --without-dbus --host=i686-w64-mingw32 --without-compress-install 'CFLAGS=-O2 -static -g3'' Configured features: XPM JPEG TIFF GIF PNG RSVG SOUND NOTIFY ACL GNUTLS LIBXML2 ZLIB TOOLKIT_SCROLL_BARS THREADS LCMS2 Important settings: value of $LANG: PTB locale-coding-system: cp1252 Major mode: Lisp Interaction Minor modes in effect: tooltip-mode: t global-eldoc-mode: t eldoc-mode: t electric-indent-mode: t mouse-wheel-mode: t tool-bar-mode: t menu-bar-mode: t file-name-shadow-mode: t global-font-lock-mode: t font-lock-mode: t blink-cursor-mode: t auto-composition-mode: t auto-encryption-mode: t auto-compression-mode: t line-number-mode: t transient-mark-mode: t Load-path shadows: None found. Features: (shadow sort mail-extr emacsbug message rmc puny dired dired-loaddefs format-spec rfc822 mml easymenu mml-sec password-cache epa derived epg epg-config gnus-util rmail rmail-loaddefs mm-decode mm-bodies mm-encode mail-parse rfc2231 mailabbrev gmm-utils mailheader sendmail rfc2047 rfc2045 ietf-drums mm-util mail-prsvr mail-utils seq byte-opt gv bytecomp byte-compile cconv cl-loaddefs cl-lib elec-pair time-date mule-util tooltip eldoc electric uniquify ediff-hook vc-hooks lisp-float-type mwheel dos-w32 ls-lisp disp-table term/w32-win w32-win w32-vars term/common-win tool-bar dnd fontset image regexp-opt fringe tabulated-list replace newcomment text-mode elisp-mode lisp-mode prog-mode register page menu-bar rfn-eshadow isearch timer select scroll-bar mouse jit-lock font-lock syntax facemenu font-core term/tty-colors frame cl-generic cham georgian utf-8-lang misc-lang vietnamese tibetan thai tai-viet lao korean japanese eucjp-ms cp51932 hebrew greek romanian slovak czech european ethiopic indian cyrillic chinese composite charscript charprop case-table epa-hook jka-cmpr-hook help simple abbrev obarray minibuffer cl-preloaded nadvice loaddefs button faces cus-face macroexp files text-properties overlay sha1 md5 base64 format env code-pages mule custom widget hashtable-print-readable backquote w32notify w32 lcms2 multi-tty make-network-process emacs) Memory information: ((conses 8 96961 9032) (symbols 32 20186 1) (miscs 32 38 140) (strings 16 29656 2096) (string-bytes 1 766583) (vectors 12 14052) (vector-slots 4 507930 10192) (floats 8 52 289) (intervals 28 263 59) (buffers 536 12)) -- Miguel Vinicius Santini Frasson mvsfrasson@gmail.com ^ permalink raw reply [flat|nested] 43+ messages in thread
* bug#34852: 26.1; seq-intersection ignores nil as element 2019-03-14 2:16 bug#34852: 26.1; seq-intersection ignores nil as element Miguel V. S. Frasson @ 2019-03-14 12:07 ` Michael Heerdegen 2019-03-14 13:09 ` Nicolas Petton 2019-03-14 12:22 ` Basil L. Contovounesios 1 sibling, 1 reply; 43+ messages in thread From: Michael Heerdegen @ 2019-03-14 12:07 UTC (permalink / raw) To: Miguel V. S. Frasson; +Cc: 34852 "Miguel V. S. Frasson" <mvsfrasson@gmail.com> writes: > seq-intersection skips nil as common element, so returns wrong result. > > Reproducing from emacs -Q: > > In *scratch* buffer, eval the expressions > > (progn > (require 'seq) > (seq-intersection '(1 2 nil) '(1 nil) 'eq)) > > -> (1) > > (seq-intersection '(1 2 nil) '(1 nil) 'equal) > > -> (1) > > Expected result in both cases: (1 nil) Indeed. Nicolas, can you have a look? We probably can't use `seq-contains' in the implementation. Thanks, Michael. ^ permalink raw reply [flat|nested] 43+ messages in thread
* bug#34852: 26.1; seq-intersection ignores nil as element 2019-03-14 12:07 ` Michael Heerdegen @ 2019-03-14 13:09 ` Nicolas Petton 0 siblings, 0 replies; 43+ messages in thread From: Nicolas Petton @ 2019-03-14 13:09 UTC (permalink / raw) To: Michael Heerdegen, Miguel V. S. Frasson; +Cc: 34852 [-- Attachment #1: Type: text/plain, Size: 189 bytes --] Michael Heerdegen <michael_heerdegen@web.de> writes: > Indeed. > > Nicolas, can you have a look? We probably can't use `seq-contains' in > the implementation. Yes, I will. Cheers, Nico [-- Attachment #2: signature.asc --] [-- Type: application/pgp-signature, Size: 487 bytes --] ^ permalink raw reply [flat|nested] 43+ messages in thread
* bug#34852: 26.1; seq-intersection ignores nil as element 2019-03-14 2:16 bug#34852: 26.1; seq-intersection ignores nil as element Miguel V. S. Frasson 2019-03-14 12:07 ` Michael Heerdegen @ 2019-03-14 12:22 ` Basil L. Contovounesios 2019-03-14 12:52 ` Miguel V. S. Frasson 2019-03-14 13:09 ` Michael Heerdegen 1 sibling, 2 replies; 43+ messages in thread From: Basil L. Contovounesios @ 2019-03-14 12:22 UTC (permalink / raw) To: Miguel V. S. Frasson; +Cc: Nicolas Petton, 34852, Stefan Monnier [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #1: 0001-Do-not-use-seq-contains-as-a-predicate-bug-34852.patch --] [-- Type: text/x-diff, Size: 5920 bytes --] From afddf78a703b73729ec7b5562747ebeb5077966d Mon Sep 17 00:00:00 2001 From: "Basil L. Contovounesios" <contovob@tcd.ie> Date: Thu, 14 Mar 2019 12:10:28 +0000 Subject: [PATCH] Do not use seq-contains as a predicate (bug#34852) * doc/lispref/sequences.texi (Sequence Functions): * lisp/emacs-lisp/seq.el (seq-contains): Document unsuitability of seq-contains as a predicate. (seq-position): Document return value when needle not found. (seq-set-equal-p, seq-uniq, seq-intersection, seq-difference): Use seq-position instead of seq-contains as a predicate. * test/lisp/emacs-lisp/seq-tests.el (test-seq-contains-should-return-the-elt): (test-seq-position): Test case when needle is nil. --- doc/lispref/sequences.texi | 7 +++++++ lisp/emacs-lisp/seq.el | 21 ++++++++++++--------- test/lisp/emacs-lisp/seq-tests.el | 14 +++++++++----- 3 files changed, 28 insertions(+), 14 deletions(-) diff --git a/doc/lispref/sequences.texi b/doc/lispref/sequences.texi index 0c3c4e3b28..e33944a2dd 100644 --- a/doc/lispref/sequences.texi +++ b/doc/lispref/sequences.texi @@ -787,6 +787,9 @@ Sequence Functions @var{elt}. If the optional argument @var{function} is non-@code{nil}, it is a function of two arguments to use instead of the default @code{equal}. +Note that this function is not suitable as a predicate since its value +depends on that of @var{elt}, which may be @code{nil}. + @example @group (seq-contains '(symbol1 symbol2) 'symbol1) @@ -796,6 +799,10 @@ Sequence Functions (seq-contains '(symbol1 symbol2) 'symbol3) @result{} nil @end group +@group +(seq-contains '(symbol1 nil) nil) +@result{} nil +@end group @end example @end defun diff --git a/lisp/emacs-lisp/seq.el b/lisp/emacs-lisp/seq.el index 4a811d7895..de8456eb79 100644 --- a/lisp/emacs-lisp/seq.el +++ b/lisp/emacs-lisp/seq.el @@ -357,7 +357,9 @@ seq-sort-by (cl-defgeneric seq-contains (sequence elt &optional testfn) "Return the first element in SEQUENCE that is equal to ELT. -Equality is defined by TESTFN if non-nil or by `equal' if nil." +Equality is defined by TESTFN if non-nil or by `equal' if nil. +Note that this function is not suitable as a predicate since its +value depends on that of ELT, which may be nil." (seq-some (lambda (e) (when (funcall (or testfn #'equal) elt e) e)) @@ -366,12 +368,13 @@ seq-sort-by (cl-defgeneric seq-set-equal-p (sequence1 sequence2 &optional testfn) "Return non-nil if SEQUENCE1 and SEQUENCE2 contain the same elements, regardless of order. Equality is defined by TESTFN if non-nil or by `equal' if nil." - (and (seq-every-p (lambda (item1) (seq-contains sequence2 item1 testfn)) sequence1) - (seq-every-p (lambda (item2) (seq-contains sequence1 item2 testfn)) sequence2))) + (and (seq-every-p (lambda (item1) (seq-position sequence2 item1 testfn)) sequence1) + (seq-every-p (lambda (item2) (seq-position sequence1 item2 testfn)) sequence2))) (cl-defgeneric seq-position (sequence elt &optional testfn) "Return the index of the first element in SEQUENCE that is equal to ELT. -Equality is defined by TESTFN if non-nil or by `equal' if nil." +Return nil if no such element is found. Equality is defined by +TESTFN if non-nil or by `equal' if nil." (let ((index 0)) (catch 'seq--break (seq-doseq (e sequence) @@ -385,7 +388,7 @@ seq-sort-by TESTFN is used to compare elements, or `equal' if TESTFN is nil." (let ((result '())) (seq-doseq (elt sequence) - (unless (seq-contains result elt testfn) + (unless (seq-position result elt testfn) (setq result (cons elt result)))) (nreverse result))) @@ -410,7 +413,7 @@ seq-sort-by "Return a list of the elements that appear in both SEQUENCE1 and SEQUENCE2. Equality is defined by TESTFN if non-nil or by `equal' if nil." (seq-reduce (lambda (acc elt) - (if (seq-contains sequence2 elt testfn) + (if (seq-position sequence2 elt testfn) (cons elt acc) acc)) (seq-reverse sequence1) @@ -420,9 +423,9 @@ seq-sort-by "Return a list of the elements that appear in SEQUENCE1 but not in SEQUENCE2. Equality is defined by TESTFN if non-nil or by `equal' if nil." (seq-reduce (lambda (acc elt) - (if (not (seq-contains sequence2 elt testfn)) - (cons elt acc) - acc)) + (if (seq-position sequence2 elt testfn) + acc + (cons elt acc))) (seq-reverse sequence1) '())) diff --git a/test/lisp/emacs-lisp/seq-tests.el b/test/lisp/emacs-lisp/seq-tests.el index d8f00cfea4..417606d9d7 100644 --- a/test/lisp/emacs-lisp/seq-tests.el +++ b/test/lisp/emacs-lisp/seq-tests.el @@ -183,7 +183,9 @@ test-sequences-oddp (ert-deftest test-seq-contains-should-return-the-elt () (with-test-sequences (seq '(3 4 5 6)) - (should (= 5 (seq-contains seq 5))))) + (should (= 5 (seq-contains seq 5)))) + (should-not (seq-contains '(1 2 nil) nil)) + (should-not (seq-contains [1 2 nil] nil))) (ert-deftest test-seq-every-p () (with-test-sequences (seq '(43 54 22 1)) @@ -384,12 +386,14 @@ test-sequences-oddp (ert-deftest test-seq-position () (with-test-sequences (seq '(2 4 6)) - (should (null (seq-position seq 1))) + (should-not (seq-position seq 1)) + (should-not (seq-position seq nil)) (should (= (seq-position seq 4) 1))) - (let ((seq '(a b c))) - (should (null (seq-position seq 'd #'eq))) + (let ((seq '(a b c nil))) + (should-not (seq-position seq 'd #'eq)) (should (= (seq-position seq 'a #'eq) 0)) - (should (null (seq-position seq (make-symbol "a") #'eq))))) + (should (= (seq-position seq nil #'eq) 3)) + (should-not (seq-position seq (make-symbol "a") #'eq)))) (ert-deftest test-seq-sort-by () (let ((seq ["x" "xx" "xxx"])) -- 2.20.1 [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #2: 0001-Return-boolean-instead-of-element-in-seq-contains.patch --] [-- Type: text/x-diff, Size: 4103 bytes --] From 7b8d5672db306e3bb52196b04c74eb7098ec32a3 Mon Sep 17 00:00:00 2001 From: "Basil L. Contovounesios" <contovob@tcd.ie> Date: Thu, 14 Mar 2019 11:19:55 +0000 Subject: [PATCH] Return boolean instead of element in seq-contains * lisp/emacs-lisp/seq.el: Bump major version. (seq-contains): Return non-nil instead of needle if it is found in the sequence. (bug#34852) * test/lisp/emacs-lisp/seq-tests.el (test-seq-contains): Add check for nil as an element. (test-seq-contains-should-return-the-elt): Remove, replacing with... (test-seq-contains-return-non-nil): ...this new test. * doc/lispref/sequences.texi (Sequence Functions): * etc/NEWS: Document change to seq-contains. --- doc/lispref/sequences.texi | 9 +++++---- etc/NEWS | 3 +++ lisp/emacs-lisp/seq.el | 7 +++---- test/lisp/emacs-lisp/seq-tests.el | 9 +++++---- 4 files changed, 16 insertions(+), 12 deletions(-) diff --git a/doc/lispref/sequences.texi b/doc/lispref/sequences.texi index 0c3c4e3b28..b0c65fe526 100644 --- a/doc/lispref/sequences.texi +++ b/doc/lispref/sequences.texi @@ -783,14 +783,15 @@ Sequence Functions @defun seq-contains sequence elt &optional function - This function returns the first element in @var{sequence} that is equal to -@var{elt}. If the optional argument @var{function} is non-@code{nil}, -it is a function of two arguments to use instead of the default @code{equal}. + This function returns non-@code{nil} if an element in @var{sequence} +is equal to @var{elt}. If the optional argument @var{function} is +non-@code{nil}, it is a function of two arguments to use instead of +the default @code{equal}. @example @group (seq-contains '(symbol1 symbol2) 'symbol1) -@result{} symbol1 +@result{} t @end group @group (seq-contains '(symbol1 symbol2) 'symbol3) diff --git a/etc/NEWS b/etc/NEWS index 410c1821ae..b41ff89613 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -383,6 +383,9 @@ buffers. New convenience functions 'seq-first' and 'seq-rest' give easy access to respectively the first and all but the first elements of sequences. ++++ +*** 'seq-contains' now returns a boolean rather than the element found. + --- ** Follow mode In the current follow group of windows, "ghost" cursors are no longer diff --git a/lisp/emacs-lisp/seq.el b/lisp/emacs-lisp/seq.el index 4a811d7895..73cb985b85 100644 --- a/lisp/emacs-lisp/seq.el +++ b/lisp/emacs-lisp/seq.el @@ -4,7 +4,7 @@ ;; Author: Nicolas Petton <nicolas@petton.fr> ;; Keywords: sequences -;; Version: 2.21 +;; Version: 3.0 ;; Package: seq ;; Maintainer: emacs-devel@gnu.org @@ -356,11 +356,10 @@ seq-sort-by count)) (cl-defgeneric seq-contains (sequence elt &optional testfn) - "Return the first element in SEQUENCE that is equal to ELT. + "Return non-nil if an element in SEQUENCE is equal to ELT. Equality is defined by TESTFN if non-nil or by `equal' if nil." (seq-some (lambda (e) - (when (funcall (or testfn #'equal) elt e) - e)) + (funcall (or testfn #'equal) elt e)) sequence)) (cl-defgeneric seq-set-equal-p (sequence1 sequence2 &optional testfn) diff --git a/test/lisp/emacs-lisp/seq-tests.el b/test/lisp/emacs-lisp/seq-tests.el index d8f00cfea4..fee31e7f8f 100644 --- a/test/lisp/emacs-lisp/seq-tests.el +++ b/test/lisp/emacs-lisp/seq-tests.el @@ -176,14 +176,15 @@ test-sequences-oddp (ert-deftest test-seq-contains () (with-test-sequences (seq '(3 4 5 6)) (should (seq-contains seq 3)) - (should-not (seq-contains seq 7))) + (should-not (seq-contains seq 7)) + (should-not (seq-contains seq nil))) (with-test-sequences (seq '()) (should-not (seq-contains seq 3)) (should-not (seq-contains seq nil)))) -(ert-deftest test-seq-contains-should-return-the-elt () - (with-test-sequences (seq '(3 4 5 6)) - (should (= 5 (seq-contains seq 5))))) +(ert-deftest test-seq-contains-return-non-nil () + (should (seq-contains '(1 2 nil) nil)) + (should (seq-contains [1 2 nil] nil))) (ert-deftest test-seq-every-p () (with-test-sequences (seq '(43 54 22 1)) -- 2.20.1 [-- Attachment #3: Type: text/plain, Size: 1345 bytes --] "Miguel V. S. Frasson" <mvsfrasson@gmail.com> writes: > seq-intersection skips nil as common element, so returns wrong result. > > Reproducing from emacs -Q: > > In *scratch* buffer, eval the expressions > > (progn > (require 'seq) > (seq-intersection '(1 2 nil) '(1 nil) 'eq)) > > -> (1) > > (seq-intersection '(1 2 nil) '(1 nil) 'equal) > > -> (1) > > Expected result in both cases: (1 nil) This is actually due to seq-contains returning the element found, rather than a boolean indicating whether the element was found: (seq-contains '(nil) nil) ; => nil The nature of seq-contains as a predicate-ish has been discussed in the past[1], and Stefan recently fixed a similar problem with map-contains-key[2]. [1]: https://lists.gnu.org/archive/html/emacs-devel/2016-07/msg01256.html [2]: * lisp/emacs-lisp/map.el: Make the functions generic 2018-12-11 17:54:13 -0500 https://git.savannah.gnu.org/cgit/emacs.git/commit/?id=1691a51094d35ac4b2c311fa407c6b77eea7a105 One solution is to leave seq-contains as it is, and switch to using seq-position (or some new predicate) as a predicate instead. Another is to make seq-contains return a boolean instead of the needle found, which would be a backward-incompatible change similar to that for map-contains-key. I attach a patch for each of these respective solutions; WDYT? -- Basil ^ permalink raw reply related [flat|nested] 43+ messages in thread
* bug#34852: 26.1; seq-intersection ignores nil as element 2019-03-14 12:22 ` Basil L. Contovounesios @ 2019-03-14 12:52 ` Miguel V. S. Frasson 2019-03-14 16:16 ` Basil L. Contovounesios 2019-03-14 13:09 ` Michael Heerdegen 1 sibling, 1 reply; 43+ messages in thread From: Miguel V. S. Frasson @ 2019-03-14 12:52 UTC (permalink / raw) To: Basil L. Contovounesios; +Cc: Nicolas Petton, 34852, Stefan Monnier Hi. In https://lists.gnu.org/archive/html/emacs-devel/2016-07/msg01256.html it is mentioned that: > I believe `seq-contains' was introduced for convenience: > it is used elsewhere in seq.el and map.el. so there may be problems in map.el as well if it is used as a predicate there, or even in more files. Miguel. Em qui, 14 de mar de 2019 às 09:22, Basil L. Contovounesios <contovob@tcd.ie> escreveu: > > > "Miguel V. S. Frasson" <mvsfrasson@gmail.com> writes: > > > seq-intersection skips nil as common element, so returns wrong result. > > > > Reproducing from emacs -Q: > > > > In *scratch* buffer, eval the expressions > > > > (progn > > (require 'seq) > > (seq-intersection '(1 2 nil) '(1 nil) 'eq)) > > > > -> (1) > > > > (seq-intersection '(1 2 nil) '(1 nil) 'equal) > > > > -> (1) > > > > Expected result in both cases: (1 nil) > > This is actually due to seq-contains returning the element found, rather > than a boolean indicating whether the element was found: > > (seq-contains '(nil) nil) ; => nil > > The nature of seq-contains as a predicate-ish has been discussed in the > past[1], and Stefan recently fixed a similar problem with > map-contains-key[2]. > > [1]: https://lists.gnu.org/archive/html/emacs-devel/2016-07/msg01256.html > [2]: * lisp/emacs-lisp/map.el: Make the functions generic > 2018-12-11 17:54:13 -0500 > https://git.savannah.gnu.org/cgit/emacs.git/commit/?id=1691a51094d35ac4b2c311fa407c6b77eea7a105 > > One solution is to leave seq-contains as it is, and switch to using > seq-position (or some new predicate) as a predicate instead. Another is > to make seq-contains return a boolean instead of the needle found, which > would be a backward-incompatible change similar to that for > map-contains-key. I attach a patch for each of these respective > solutions; WDYT? > > -- > Basil -- Miguel Vinicius Santini Frasson mvsfrasson@gmail.com ^ permalink raw reply [flat|nested] 43+ messages in thread
* bug#34852: 26.1; seq-intersection ignores nil as element 2019-03-14 12:52 ` Miguel V. S. Frasson @ 2019-03-14 16:16 ` Basil L. Contovounesios 0 siblings, 0 replies; 43+ messages in thread From: Basil L. Contovounesios @ 2019-03-14 16:16 UTC (permalink / raw) To: Miguel V. S. Frasson; +Cc: Nicolas Petton, 34852, Stefan Monnier "Miguel V. S. Frasson" <mvsfrasson@gmail.com> writes: > In https://lists.gnu.org/archive/html/emacs-devel/2016-07/msg01256.html > it is mentioned that: > >> I believe `seq-contains' was introduced for convenience: >> it is used elsewhere in seq.el and map.el. > > so there may be problems in map.el as well if it is used as a > predicate there, or even in more files. All occurences of seq-contains I could find in emacs.git are addressed in the two patches. Thanks, -- Basil ^ permalink raw reply [flat|nested] 43+ messages in thread
* bug#34852: 26.1; seq-intersection ignores nil as element 2019-03-14 12:22 ` Basil L. Contovounesios 2019-03-14 12:52 ` Miguel V. S. Frasson @ 2019-03-14 13:09 ` Michael Heerdegen 2019-03-14 13:34 ` Stefan Monnier ` (2 more replies) 1 sibling, 3 replies; 43+ messages in thread From: Michael Heerdegen @ 2019-03-14 13:09 UTC (permalink / raw) To: Basil L. Contovounesios Cc: Nicolas Petton, Miguel V. S. Frasson, 34852, Stefan Monnier [-- Attachment #1: Type: text/plain, Size: 511 bytes --] "Basil L. Contovounesios" <contovob@tcd.ie> writes: > One solution is to leave seq-contains as it is, and switch to using > seq-position (or some new predicate) as a predicate instead. Another is > to make seq-contains return a boolean instead of the needle found, which > would be a backward-incompatible change similar to that for > map-contains-key. I attach a patch for each of these respective > solutions; WDYT? We also have `seq-some' which can be used as a contain predicate, e.g. to fix this bug: [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #2: 0001-Fix-seq-intersection-with-nil.patch --] [-- Type: text/x-diff, Size: 1397 bytes --] From c53a80c29e696ab64d4279ca6f495c8e0e1b16b4 Mon Sep 17 00:00:00 2001 From: Michael Heerdegen <michael_heerdegen@web.de> Date: Thu, 14 Mar 2019 13:55:41 +0100 Subject: [PATCH] Fix seq-intersection with nil --- lisp/emacs-lisp/seq.el | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/lisp/emacs-lisp/seq.el b/lisp/emacs-lisp/seq.el index 4a811d7895..5718343a8f 100644 --- a/lisp/emacs-lisp/seq.el +++ b/lisp/emacs-lisp/seq.el @@ -409,12 +409,13 @@ seq-sort-by (cl-defgeneric seq-intersection (sequence1 sequence2 &optional testfn) "Return a list of the elements that appear in both SEQUENCE1 and SEQUENCE2. Equality is defined by TESTFN if non-nil or by `equal' if nil." - (seq-reduce (lambda (acc elt) - (if (seq-contains sequence2 elt testfn) - (cons elt acc) - acc)) - (seq-reverse sequence1) - '())) + (let ((testfn (or testfn #'equal))) + (seq-reduce (lambda (acc elt) + (if (seq-some (apply-partially testfn elt) sequence2) + (cons elt acc) + acc)) + (seq-reverse sequence1) + '()))) (cl-defgeneric seq-difference (sequence1 sequence2 &optional testfn) "Return a list of the elements that appear in SEQUENCE1 but not in SEQUENCE2. -- 2.20.1 [-- Attachment #3: Type: text/plain, Size: 166 bytes --] (probably needed in more places as you did in one of your patches) So I think we don't necessarily need something new or a backward incompatible change. Michael. ^ permalink raw reply related [flat|nested] 43+ messages in thread
* bug#34852: 26.1; seq-intersection ignores nil as element 2019-03-14 13:09 ` Michael Heerdegen @ 2019-03-14 13:34 ` Stefan Monnier 2019-03-14 16:19 ` Basil L. Contovounesios 2019-03-14 19:08 ` Miguel V. S. Frasson 2019-03-14 16:17 ` Basil L. Contovounesios 2019-03-14 16:45 ` Nicolas Petton 2 siblings, 2 replies; 43+ messages in thread From: Stefan Monnier @ 2019-03-14 13:34 UTC (permalink / raw) To: Michael Heerdegen Cc: Basil L. Contovounesios, Nicolas Petton, 34852, Miguel V. S. Frasson Yet another approach might be to make an exception in seq-contains if the returned element is nil (and return something else in that case). E.g. diff --git a/lisp/emacs-lisp/seq.el b/lisp/emacs-lisp/seq.el index 4a811d7895..d2398eb588 100644 --- a/lisp/emacs-lisp/seq.el +++ b/lisp/emacs-lisp/seq.el @@ -360,7 +360,7 @@ seq-sort-by Equality is defined by TESTFN if non-nil or by `equal' if nil." (seq-some (lambda (e) (when (funcall (or testfn #'equal) elt e) - e)) + (or e t))) sequence)) (cl-defgeneric seq-set-equal-p (sequence1 sequence2 &optional testfn) -- Stefan ^ permalink raw reply [flat|nested] 43+ messages in thread
* bug#34852: 26.1; seq-intersection ignores nil as element 2019-03-14 13:34 ` Stefan Monnier @ 2019-03-14 16:19 ` Basil L. Contovounesios 2019-03-14 16:45 ` Michael Heerdegen 2019-03-14 19:08 ` Miguel V. S. Frasson 1 sibling, 1 reply; 43+ messages in thread From: Basil L. Contovounesios @ 2019-03-14 16:19 UTC (permalink / raw) To: Stefan Monnier Cc: Michael Heerdegen, Nicolas Petton, 34852, Miguel V. S. Frasson Stefan Monnier <monnier@IRO.UMontreal.CA> writes: > Yet another approach might be to make an exception in seq-contains if > the returned element is nil (and return something else in that case). > E.g. > > diff --git a/lisp/emacs-lisp/seq.el b/lisp/emacs-lisp/seq.el > index 4a811d7895..d2398eb588 100644 > --- a/lisp/emacs-lisp/seq.el > +++ b/lisp/emacs-lisp/seq.el > @@ -360,7 +360,7 @@ seq-sort-by > Equality is defined by TESTFN if non-nil or by `equal' if nil." > (seq-some (lambda (e) > (when (funcall (or testfn #'equal) elt e) > - e)) > + (or e t))) > sequence)) > > (cl-defgeneric seq-set-equal-p (sequence1 sequence2 &optional testfn) This is both backward-incompatible and inconsistent. If we agree to make a backward-incompatible change, I would rather turn seq-contains into a proper predicate, as per my second patch. Besides, returning the element found isn't particularly useful to begin with, as the caller already has access to that value. Either way, we can install the backward-compatible first patch (which uses seq-position in place of seq-contains) to fix this bug, and later discuss any backward-incompatible changes to seq-contains. Thanks, -- Basil ^ permalink raw reply [flat|nested] 43+ messages in thread
* bug#34852: 26.1; seq-intersection ignores nil as element 2019-03-14 16:19 ` Basil L. Contovounesios @ 2019-03-14 16:45 ` Michael Heerdegen 2019-03-14 17:14 ` Basil L. Contovounesios 0 siblings, 1 reply; 43+ messages in thread From: Michael Heerdegen @ 2019-03-14 16:45 UTC (permalink / raw) To: Basil L. Contovounesios Cc: Nicolas Petton, Miguel V. S. Frasson, 34852, Stefan Monnier "Basil L. Contovounesios" <contovob@tcd.ie> writes: > Besides, returning the element found isn't particularly useful to > begin with, as the caller already has access to that value. Depends on the TESTFN. You could use seq-contains as a replacement for alist-get, for example, when you make TESTFN look at the sequence's car's. This is more or less the same as using :key in cl-member, so people might be doing this and there is some change that we break existing code. Michael. ^ permalink raw reply [flat|nested] 43+ messages in thread
* bug#34852: 26.1; seq-intersection ignores nil as element 2019-03-14 16:45 ` Michael Heerdegen @ 2019-03-14 17:14 ` Basil L. Contovounesios 0 siblings, 0 replies; 43+ messages in thread From: Basil L. Contovounesios @ 2019-03-14 17:14 UTC (permalink / raw) To: Michael Heerdegen Cc: Nicolas Petton, Miguel V. S. Frasson, 34852, Stefan Monnier Michael Heerdegen <michael_heerdegen@web.de> writes: > "Basil L. Contovounesios" <contovob@tcd.ie> writes: > >> Besides, returning the element found isn't particularly useful to >> begin with, as the caller already has access to that value. > > Depends on the TESTFN. You could use seq-contains as a replacement for > alist-get, for example, when you make TESTFN look at the sequence's > car's. This is more or less the same as using :key in cl-member, so > people might be doing this and there is some change that we break > existing code. Fair enough, though I'd be interested to see an example of such logic that can't be written in a less contrived way. Thanks, -- Basil ^ permalink raw reply [flat|nested] 43+ messages in thread
* bug#34852: 26.1; seq-intersection ignores nil as element 2019-03-14 13:34 ` Stefan Monnier 2019-03-14 16:19 ` Basil L. Contovounesios @ 2019-03-14 19:08 ` Miguel V. S. Frasson 2019-03-14 21:43 ` Stefan Monnier ` (2 more replies) 1 sibling, 3 replies; 43+ messages in thread From: Miguel V. S. Frasson @ 2019-03-14 19:08 UTC (permalink / raw) To: Stefan Monnier Cc: Michael Heerdegen, Basil L. Contovounesios, Nicolas Petton, 34852 Hi In any case, of another implementation for seq-intersection or not, I think that the solution from Stefan should be implemented anyway because * it makes seq-contains provide a useful return value when ELT=nil, so it is a good exception; If ELT=nil, seq-contains currently returns nil anyway; * it makes seq-contains become a real predicate function, making it more useful; * since seq-contains has been used as predicate before, it is unpredictable which code uses it out of official repositories, so this fix potentially fixes other code. Cheers Miguel Em qui, 14 de mar de 2019 às 10:34, Stefan Monnier <monnier@iro.umontreal.ca> escreveu: > > Yet another approach might be to make an exception in seq-contains if > the returned element is nil (and return something else in that case). > E.g. > > diff --git a/lisp/emacs-lisp/seq.el b/lisp/emacs-lisp/seq.el > index 4a811d7895..d2398eb588 100644 > --- a/lisp/emacs-lisp/seq.el > +++ b/lisp/emacs-lisp/seq.el > @@ -360,7 +360,7 @@ seq-sort-by > Equality is defined by TESTFN if non-nil or by `equal' if nil." > (seq-some (lambda (e) > (when (funcall (or testfn #'equal) elt e) > - e)) > + (or e t))) > sequence)) > > (cl-defgeneric seq-set-equal-p (sequence1 sequence2 &optional testfn) > > > -- Stefan -- Miguel Vinicius Santini Frasson mvsfrasson@gmail.com ^ permalink raw reply [flat|nested] 43+ messages in thread
* bug#34852: 26.1; seq-intersection ignores nil as element 2019-03-14 19:08 ` Miguel V. S. Frasson @ 2019-03-14 21:43 ` Stefan Monnier 2019-03-14 23:08 ` Miguel V. S. Frasson 2019-03-14 23:15 ` Michael Heerdegen 2019-03-15 15:55 ` Basil L. Contovounesios 2 siblings, 1 reply; 43+ messages in thread From: Stefan Monnier @ 2019-03-14 21:43 UTC (permalink / raw) To: Miguel V. S. Frasson Cc: Michael Heerdegen, Basil L. Contovounesios, Nicolas Petton, 34852 > If ELT=nil, seq-contains currently returns nil anyway; That's true when `testfn` is nil, but not if you provide your own `testfn`. Stefan ^ permalink raw reply [flat|nested] 43+ messages in thread
* bug#34852: 26.1; seq-intersection ignores nil as element 2019-03-14 21:43 ` Stefan Monnier @ 2019-03-14 23:08 ` Miguel V. S. Frasson 2019-03-14 23:14 ` Stefan Monnier 2019-03-14 23:45 ` Miguel V. S. Frasson 0 siblings, 2 replies; 43+ messages in thread From: Miguel V. S. Frasson @ 2019-03-14 23:08 UTC (permalink / raw) To: Stefan Monnier Cc: Michael Heerdegen, Basil L. Contovounesios, Nicolas Petton, 34852 Hi Em qui, 14 de mar de 2019 18:43, Stefan Monnier <monnier@iro.umontreal.ca> escreveu: > > > If ELT=nil, seq-contains currently returns nil anyway; > > That's true when `testfn` is nil, but not if you provide > your own `testfn`. Not really. (seq-contains nil '(nil t foo) (lambda (x) t)) -> nil It returns *nil* if testfn fails, or *nil* (ELT) if it succeds. Miguel ^ permalink raw reply [flat|nested] 43+ messages in thread
* bug#34852: 26.1; seq-intersection ignores nil as element 2019-03-14 23:08 ` Miguel V. S. Frasson @ 2019-03-14 23:14 ` Stefan Monnier 2019-03-14 23:21 ` Miguel V. S. Frasson 2019-03-14 23:42 ` Michael Heerdegen 2019-03-14 23:45 ` Miguel V. S. Frasson 1 sibling, 2 replies; 43+ messages in thread From: Stefan Monnier @ 2019-03-14 23:14 UTC (permalink / raw) To: Miguel V. S. Frasson Cc: Michael Heerdegen, Basil L. Contovounesios, Nicolas Petton, 34852 > (seq-contains nil '(nil t foo) (lambda (x) t)) -> nil > It returns *nil* if testfn fails, or *nil* (ELT) if it succeds. Just because it sometimes does doesn't mean it always does: (seq-contains '(0 3 4) 1 #'<) returns 3 Stefan ^ permalink raw reply [flat|nested] 43+ messages in thread
* bug#34852: 26.1; seq-intersection ignores nil as element 2019-03-14 23:14 ` Stefan Monnier @ 2019-03-14 23:21 ` Miguel V. S. Frasson 2019-03-14 23:42 ` Michael Heerdegen 1 sibling, 0 replies; 43+ messages in thread From: Miguel V. S. Frasson @ 2019-03-14 23:21 UTC (permalink / raw) To: Stefan Monnier Cc: Michael Heerdegen, Basil L. Contovounesios, Nicolas Petton, 34852 You are right. Em qui, 14 de mar de 2019 às 20:14, Stefan Monnier <monnier@iro.umontreal.ca> escreveu: > > > (seq-contains nil '(nil t foo) (lambda (x) t)) -> nil > > It returns *nil* if testfn fails, or *nil* (ELT) if it succeds. > > Just because it sometimes does doesn't mean it always does: > > (seq-contains '(0 3 4) 1 #'<) > > returns 3 > > > Stefan -- Miguel Vinicius Santini Frasson mvsfrasson@gmail.com ^ permalink raw reply [flat|nested] 43+ messages in thread
* bug#34852: 26.1; seq-intersection ignores nil as element 2019-03-14 23:14 ` Stefan Monnier 2019-03-14 23:21 ` Miguel V. S. Frasson @ 2019-03-14 23:42 ` Michael Heerdegen 2019-03-15 2:40 ` Stefan Monnier 1 sibling, 1 reply; 43+ messages in thread From: Michael Heerdegen @ 2019-03-14 23:42 UTC (permalink / raw) To: Stefan Monnier Cc: Basil L. Contovounesios, Nicolas Petton, 34852, Miguel V. S. Frasson Stefan Monnier <monnier@IRO.UMontreal.CA> writes: > > (seq-contains nil '(nil t foo) (lambda (x) t)) -> nil > > It returns *nil* if testfn fails, or *nil* (ELT) if it succeds. > > Just because it sometimes does doesn't mean it always does: > > (seq-contains '(0 3 4) 1 #'<) > > returns 3 Maybe it's too late here, but why is that a counterexample for > If ELT=nil, seq-contains currently returns nil anyway;" The first element is returned for that the test succeeds, what's special about it? < is not symmetrical, though, so it's a weird kind of equality test. Michael. ^ permalink raw reply [flat|nested] 43+ messages in thread
* bug#34852: 26.1; seq-intersection ignores nil as element 2019-03-14 23:42 ` Michael Heerdegen @ 2019-03-15 2:40 ` Stefan Monnier 2019-03-15 12:26 ` Michael Heerdegen 0 siblings, 1 reply; 43+ messages in thread From: Stefan Monnier @ 2019-03-15 2:40 UTC (permalink / raw) To: Michael Heerdegen Cc: Basil L. Contovounesios, Nicolas Petton, 34852, Miguel V. S. Frasson >> > (seq-contains nil '(nil t foo) (lambda (x) t)) -> nil >> > It returns *nil* if testfn fails, or *nil* (ELT) if it succeds. >> Just because it sometimes does doesn't mean it always does: >> (seq-contains '(0 3 4) 1 #'<) >> returns 3 > Maybe it's too late here, but why is that a counterexample for >> If ELT=nil, seq-contains currently returns nil anyway;" Duh, sorry, I lost sight of the goal along the way. A short real counter example is (seq-contains '(1) nil #'list) but it's admittedly contrived. A more real counter example is the one alluded to by Nicolas earlier: (seq-contains '((t 1) (nil 2)) nil (lambda (x y) (equal x (car y)))) > The first element is returned for that the test succeeds, what's special > about it? < is not symmetrical, though, so it's a weird kind of > equality test. The test doesn't need to be an equality test. IOW seq-contains is very close to seq-find. Stefan ^ permalink raw reply [flat|nested] 43+ messages in thread
* bug#34852: 26.1; seq-intersection ignores nil as element 2019-03-15 2:40 ` Stefan Monnier @ 2019-03-15 12:26 ` Michael Heerdegen 2019-03-15 14:47 ` Stefan Monnier 0 siblings, 1 reply; 43+ messages in thread From: Michael Heerdegen @ 2019-03-15 12:26 UTC (permalink / raw) To: Stefan Monnier Cc: Basil L. Contovounesios, Nicolas Petton, 34852, Miguel V. S. Frasson Stefan Monnier <monnier@IRO.UMontreal.CA> writes: > The test doesn't need to be an equality test. The doc doesn't specify in which order the args are delivered to the TESTFN, so the behavior is unspecified. For asymmetric TESTFNs I would rather go with `seq-some'. Michael. ^ permalink raw reply [flat|nested] 43+ messages in thread
* bug#34852: 26.1; seq-intersection ignores nil as element 2019-03-15 12:26 ` Michael Heerdegen @ 2019-03-15 14:47 ` Stefan Monnier 0 siblings, 0 replies; 43+ messages in thread From: Stefan Monnier @ 2019-03-15 14:47 UTC (permalink / raw) To: Michael Heerdegen Cc: Basil L. Contovounesios, Nicolas Petton, 34852, Miguel V. S. Frasson >> The test doesn't need to be an equality test. > The doc doesn't specify in which order the args are delivered to the > TESTFN, so the behavior is unspecified. Indeed, that's another problem with seq-contains. Stefan ^ permalink raw reply [flat|nested] 43+ messages in thread
* bug#34852: 26.1; seq-intersection ignores nil as element 2019-03-14 23:08 ` Miguel V. S. Frasson 2019-03-14 23:14 ` Stefan Monnier @ 2019-03-14 23:45 ` Miguel V. S. Frasson 1 sibling, 0 replies; 43+ messages in thread From: Miguel V. S. Frasson @ 2019-03-14 23:45 UTC (permalink / raw) To: Stefan Monnier Cc: Michael Heerdegen, Basil L. Contovounesios, Nicolas Petton, 34852 [-- Attachment #1: Type: text/plain, Size: 530 bytes --] Please ignore this e-mail of mine. Em qui, 14 de mar de 2019 20:08, Miguel V. S. Frasson <mvsfrasson@gmail.com> escreveu: > Hi > > Em qui, 14 de mar de 2019 18:43, Stefan Monnier > <monnier@iro.umontreal.ca> escreveu: > > > > > If ELT=nil, seq-contains currently returns nil anyway; > > > > That's true when `testfn` is nil, but not if you provide > > your own `testfn`. > > Not really. > > (seq-contains nil '(nil t foo) (lambda (x) t)) -> nil > > It returns *nil* if testfn fails, or *nil* (ELT) if it succeds. > > Miguel > [-- Attachment #2: Type: text/html, Size: 964 bytes --] ^ permalink raw reply [flat|nested] 43+ messages in thread
* bug#34852: 26.1; seq-intersection ignores nil as element 2019-03-14 19:08 ` Miguel V. S. Frasson 2019-03-14 21:43 ` Stefan Monnier @ 2019-03-14 23:15 ` Michael Heerdegen 2019-03-15 15:56 ` Basil L. Contovounesios 2019-03-15 15:55 ` Basil L. Contovounesios 2 siblings, 1 reply; 43+ messages in thread From: Michael Heerdegen @ 2019-03-14 23:15 UTC (permalink / raw) To: Miguel V. S. Frasson Cc: Basil L. Contovounesios, Nicolas Petton, Stefan Monnier, 34852 "Miguel V. S. Frasson" <mvsfrasson@gmail.com> writes: > Hi > > In any case, of another implementation for seq-intersection or not, I > think that the solution from Stefan should be implemented anyway > because > > * it makes seq-contains provide a useful return value when ELT=nil, so > it is a good exception; If ELT=nil, seq-contains currently returns nil > anyway; > > * it makes seq-contains become a real predicate function, making it > more useful; > > * since seq-contains has been used as predicate before, it is > unpredictable which code uses it out of official repositories, so this > fix potentially fixes other code. BTW, another (alternative) alternative would be to make it return (list ELT). That would be a bit less backward-compatible, but a bit more consistent. Michael. ^ permalink raw reply [flat|nested] 43+ messages in thread
* bug#34852: 26.1; seq-intersection ignores nil as element 2019-03-14 23:15 ` Michael Heerdegen @ 2019-03-15 15:56 ` Basil L. Contovounesios 2019-03-15 16:08 ` Miguel V. S. Frasson 0 siblings, 1 reply; 43+ messages in thread From: Basil L. Contovounesios @ 2019-03-15 15:56 UTC (permalink / raw) To: Michael Heerdegen Cc: Nicolas Petton, Miguel V. S. Frasson, 34852, Stefan Monnier Michael Heerdegen <michael_heerdegen@web.de> writes: > "Miguel V. S. Frasson" <mvsfrasson@gmail.com> writes: > >> In any case, of another implementation for seq-intersection or not, I >> think that the solution from Stefan should be implemented anyway >> because >> >> * it makes seq-contains provide a useful return value when ELT=nil, so >> it is a good exception; If ELT=nil, seq-contains currently returns nil >> anyway; >> >> * it makes seq-contains become a real predicate function, making it >> more useful; >> >> * since seq-contains has been used as predicate before, it is >> unpredictable which code uses it out of official repositories, so this >> fix potentially fixes other code. > > BTW, another (alternative) alternative would be to make it return > (list ELT). That would be a bit less backward-compatible, but a > bit more consistent. +1, either this or returning a boolean is fine with me. -- Basil ^ permalink raw reply [flat|nested] 43+ messages in thread
* bug#34852: 26.1; seq-intersection ignores nil as element 2019-03-15 15:56 ` Basil L. Contovounesios @ 2019-03-15 16:08 ` Miguel V. S. Frasson 2019-03-16 20:33 ` Miguel V. S. Frasson 0 siblings, 1 reply; 43+ messages in thread From: Miguel V. S. Frasson @ 2019-03-15 16:08 UTC (permalink / raw) To: Basil L. Contovounesios Cc: Michael Heerdegen, Nicolas Petton, Stefan Monnier, 34852 [-- Attachment #1: Type: text/plain, Size: 1384 bytes --] Hi I was convinced by the discussions here that changing seq-contains is a bad idea. I had the false premise that ELT=nil makes seq-contains return nil. If I could make a suggestion, it would be include an &optional NOT-FOUND to be the value returned in case of not finding any element matching TESTFN. Cheers Miguel Em sex, 15 de mar de 2019 12:56, Basil L. Contovounesios <contovob@tcd.ie> escreveu: > Michael Heerdegen <michael_heerdegen@web.de> writes: > > > "Miguel V. S. Frasson" <mvsfrasson@gmail.com> writes: > > > >> In any case, of another implementation for seq-intersection or not, I > >> think that the solution from Stefan should be implemented anyway > >> because > >> > >> * it makes seq-contains provide a useful return value when ELT=nil, so > >> it is a good exception; If ELT=nil, seq-contains currently returns nil > >> anyway; > >> > >> * it makes seq-contains become a real predicate function, making it > >> more useful; > >> > >> * since seq-contains has been used as predicate before, it is > >> unpredictable which code uses it out of official repositories, so this > >> fix potentially fixes other code. > > > > BTW, another (alternative) alternative would be to make it return > > (list ELT). That would be a bit less backward-compatible, but a > > bit more consistent. > > +1, either this or returning a boolean is fine with me. > > -- > Basil > [-- Attachment #2: Type: text/html, Size: 2329 bytes --] ^ permalink raw reply [flat|nested] 43+ messages in thread
* bug#34852: 26.1; seq-intersection ignores nil as element 2019-03-15 16:08 ` Miguel V. S. Frasson @ 2019-03-16 20:33 ` Miguel V. S. Frasson 2019-03-16 20:49 ` Basil L. Contovounesios 0 siblings, 1 reply; 43+ messages in thread From: Miguel V. S. Frasson @ 2019-03-16 20:33 UTC (permalink / raw) To: Basil L. Contovounesios Cc: Michael Heerdegen, Nicolas Petton, Stefan Monnier, 34852 Hi Maybe this is the same bug, now with seq-difference (seq-difference '(nil) '(1 nil) #'eq) -> (nil) (In my applications, nil is a frequent element of my lists) Is this fixed by the proposed patches? Cheers. Miguel Em sex, 15 de mar de 2019 às 13:08, Miguel V. S. Frasson <mvsfrasson@gmail.com> escreveu: > > Hi > > I was convinced by the discussions here that changing seq-contains is a bad idea. > > I had the false premise that ELT=nil makes seq-contains return nil. > > If I could make a suggestion, it would be include an &optional NOT-FOUND to be the value returned in case of not finding any element matching TESTFN. > > Cheers > > Miguel > > Em sex, 15 de mar de 2019 12:56, Basil L. Contovounesios <contovob@tcd.ie> escreveu: >> >> Michael Heerdegen <michael_heerdegen@web.de> writes: >> >> > "Miguel V. S. Frasson" <mvsfrasson@gmail.com> writes: >> > >> >> In any case, of another implementation for seq-intersection or not, I >> >> think that the solution from Stefan should be implemented anyway >> >> because >> >> >> >> * it makes seq-contains provide a useful return value when ELT=nil, so >> >> it is a good exception; If ELT=nil, seq-contains currently returns nil >> >> anyway; >> >> >> >> * it makes seq-contains become a real predicate function, making it >> >> more useful; >> >> >> >> * since seq-contains has been used as predicate before, it is >> >> unpredictable which code uses it out of official repositories, so this >> >> fix potentially fixes other code. >> > >> > BTW, another (alternative) alternative would be to make it return >> > (list ELT). That would be a bit less backward-compatible, but a >> > bit more consistent. >> >> +1, either this or returning a boolean is fine with me. >> >> -- >> Basil -- Miguel Vinicius Santini Frasson mvsfrasson@gmail.com ^ permalink raw reply [flat|nested] 43+ messages in thread
* bug#34852: 26.1; seq-intersection ignores nil as element 2019-03-16 20:33 ` Miguel V. S. Frasson @ 2019-03-16 20:49 ` Basil L. Contovounesios 2019-03-16 21:32 ` Miguel V. S. Frasson 0 siblings, 1 reply; 43+ messages in thread From: Basil L. Contovounesios @ 2019-03-16 20:49 UTC (permalink / raw) To: Miguel V. S. Frasson Cc: Michael Heerdegen, Nicolas Petton, Stefan Monnier, 34852 "Miguel V. S. Frasson" <mvsfrasson@gmail.com> writes: > Maybe this is the same bug, now with seq-difference > > (seq-difference '(nil) '(1 nil) #'eq) > -> (nil) > > (In my applications, nil is a frequent element of my lists) It is indeed the same bug. > Is this fixed by the proposed patches? Yes. -- Basil ^ permalink raw reply [flat|nested] 43+ messages in thread
* bug#34852: 26.1; seq-intersection ignores nil as element 2019-03-16 20:49 ` Basil L. Contovounesios @ 2019-03-16 21:32 ` Miguel V. S. Frasson 0 siblings, 0 replies; 43+ messages in thread From: Miguel V. S. Frasson @ 2019-03-16 21:32 UTC (permalink / raw) To: Basil L. Contovounesios Cc: Michael Heerdegen, Nicolas Petton, Stefan Monnier, 34852 Thanks, Basil. Em sáb, 16 de mar de 2019 às 17:49, Basil L. Contovounesios <contovob@tcd.ie> escreveu: > > "Miguel V. S. Frasson" <mvsfrasson@gmail.com> writes: > > > Maybe this is the same bug, now with seq-difference > > > > (seq-difference '(nil) '(1 nil) #'eq) > > -> (nil) > > > > (In my applications, nil is a frequent element of my lists) > > It is indeed the same bug. > > > Is this fixed by the proposed patches? > > Yes. > > -- > Basil -- Miguel Vinicius Santini Frasson mvsfrasson@gmail.com ^ permalink raw reply [flat|nested] 43+ messages in thread
* bug#34852: 26.1; seq-intersection ignores nil as element 2019-03-14 19:08 ` Miguel V. S. Frasson 2019-03-14 21:43 ` Stefan Monnier 2019-03-14 23:15 ` Michael Heerdegen @ 2019-03-15 15:55 ` Basil L. Contovounesios 2 siblings, 0 replies; 43+ messages in thread From: Basil L. Contovounesios @ 2019-03-15 15:55 UTC (permalink / raw) To: Miguel V. S. Frasson Cc: Michael Heerdegen, Nicolas Petton, Stefan Monnier, 34852 "Miguel V. S. Frasson" <mvsfrasson@gmail.com> writes: > In any case, of another implementation for seq-intersection or not, I > think that the solution from Stefan should be implemented anyway > because > > * it makes seq-contains provide a useful return value when ELT=nil, so > it is a good exception; If ELT=nil, seq-contains currently returns nil > anyway; Special-casing nil invalidates any benefits of returning the element found, as it conflates nil and t and is inconsistent with other non-nil values. If seq-contains is to be made a proper predicate that continues returning the element found, then the best proposal so far has been Michael's[1], namely to return (list ELT). The alternative is to simply return a boolean, rather than the element found, but this is lossier than Michael's suggestion. [1]: https://debbugs.gnu.org/34852#68 -- Basil ^ permalink raw reply [flat|nested] 43+ messages in thread
* bug#34852: 26.1; seq-intersection ignores nil as element 2019-03-14 13:09 ` Michael Heerdegen 2019-03-14 13:34 ` Stefan Monnier @ 2019-03-14 16:17 ` Basil L. Contovounesios 2019-03-14 16:35 ` Michael Heerdegen 2019-03-14 16:45 ` Nicolas Petton 2 siblings, 1 reply; 43+ messages in thread From: Basil L. Contovounesios @ 2019-03-14 16:17 UTC (permalink / raw) To: Michael Heerdegen Cc: Nicolas Petton, Miguel V. S. Frasson, 34852, Stefan Monnier Michael Heerdegen <michael_heerdegen@web.de> writes: > "Basil L. Contovounesios" <contovob@tcd.ie> writes: > >> One solution is to leave seq-contains as it is, and switch to using >> seq-position (or some new predicate) as a predicate instead. Another is >> to make seq-contains return a boolean instead of the needle found, which >> would be a backward-incompatible change similar to that for >> map-contains-key. I attach a patch for each of these respective >> solutions; WDYT? > > We also have `seq-some' which can be used as a contain predicate, > e.g. to fix this bug: > > From c53a80c29e696ab64d4279ca6f495c8e0e1b16b4 Mon Sep 17 00:00:00 2001 > From: Michael Heerdegen <michael_heerdegen@web.de> > Date: Thu, 14 Mar 2019 13:55:41 +0100 > Subject: [PATCH] Fix seq-intersection with nil > > --- > lisp/emacs-lisp/seq.el | 13 +++++++------ > 1 file changed, 7 insertions(+), 6 deletions(-) > > diff --git a/lisp/emacs-lisp/seq.el b/lisp/emacs-lisp/seq.el > index 4a811d7895..5718343a8f 100644 > --- a/lisp/emacs-lisp/seq.el > +++ b/lisp/emacs-lisp/seq.el > @@ -409,12 +409,13 @@ seq-sort-by > (cl-defgeneric seq-intersection (sequence1 sequence2 &optional testfn) > "Return a list of the elements that appear in both SEQUENCE1 and SEQUENCE2. > Equality is defined by TESTFN if non-nil or by `equal' if nil." > - (seq-reduce (lambda (acc elt) > - (if (seq-contains sequence2 elt testfn) > - (cons elt acc) > - acc)) > - (seq-reverse sequence1) > - '())) > + (let ((testfn (or testfn #'equal))) > + (seq-reduce (lambda (acc elt) > + (if (seq-some (apply-partially testfn elt) sequence2) > + (cons elt acc) > + acc)) > + (seq-reverse sequence1) > + '()))) > > (cl-defgeneric seq-difference (sequence1 sequence2 &optional testfn) > "Return a list of the elements that appear in SEQUENCE1 but not in SEQUENCE2. > -- > 2.20.1 > > > (probably needed in more places as you did in one of your patches) > > So I think we don't necessarily need something new or a backward > incompatible change. My first patch makes an analogous backward-compatible change using the more efficient seq-position in place of seq-some. Thanks, -- Basil ^ permalink raw reply [flat|nested] 43+ messages in thread
* bug#34852: 26.1; seq-intersection ignores nil as element 2019-03-14 16:17 ` Basil L. Contovounesios @ 2019-03-14 16:35 ` Michael Heerdegen 2019-03-14 17:02 ` Basil L. Contovounesios 0 siblings, 1 reply; 43+ messages in thread From: Michael Heerdegen @ 2019-03-14 16:35 UTC (permalink / raw) To: Basil L. Contovounesios Cc: Nicolas Petton, Miguel V. S. Frasson, 34852, Stefan Monnier "Basil L. Contovounesios" <contovob@tcd.ie> writes: > My first patch makes an analogous backward-compatible change using the > more efficient seq-position in place of seq-some. Why is it more efficient? The implementations are more or less analogue, with the exception that seq-position additionally increments a counter. Michael. ^ permalink raw reply [flat|nested] 43+ messages in thread
* bug#34852: 26.1; seq-intersection ignores nil as element 2019-03-14 16:35 ` Michael Heerdegen @ 2019-03-14 17:02 ` Basil L. Contovounesios 2019-03-14 17:23 ` Basil L. Contovounesios 0 siblings, 1 reply; 43+ messages in thread From: Basil L. Contovounesios @ 2019-03-14 17:02 UTC (permalink / raw) To: Michael Heerdegen Cc: Nicolas Petton, Miguel V. S. Frasson, 34852, Stefan Monnier Michael Heerdegen <michael_heerdegen@web.de> writes: > "Basil L. Contovounesios" <contovob@tcd.ie> writes: > >> My first patch makes an analogous backward-compatible change using the >> more efficient seq-position in place of seq-some. > > Why is it more efficient? The implementations are more or less > analogue, with the exception that seq-position additionally increments a > counter. Because seq-some involves an additional level of function indirection. This is confirmed by profiling and the attached mini-benchmark, when run as follows: emacs -batch -f batch-byte-compile bench.el emacs -script bench.elc A call to seq-position is also less verbose than one to seq-some for the purpose of finding an element of a sequence. Having said that, the differences are obviously very small. -- Basil ^ permalink raw reply [flat|nested] 43+ messages in thread
* bug#34852: 26.1; seq-intersection ignores nil as element 2019-03-14 17:02 ` Basil L. Contovounesios @ 2019-03-14 17:23 ` Basil L. Contovounesios 0 siblings, 0 replies; 43+ messages in thread From: Basil L. Contovounesios @ 2019-03-14 17:23 UTC (permalink / raw) To: Michael Heerdegen Cc: Nicolas Petton, Miguel V. S. Frasson, 34852, Stefan Monnier [-- Attachment #1: bench.el --] [-- Type: application/emacs-lisp, Size: 602 bytes --] [-- Attachment #2: Type: text/plain, Size: 730 bytes --] "Basil L. Contovounesios" <contovob@tcd.ie> writes: > Michael Heerdegen <michael_heerdegen@web.de> writes: > >> "Basil L. Contovounesios" <contovob@tcd.ie> writes: >> >>> My first patch makes an analogous backward-compatible change using the >>> more efficient seq-position in place of seq-some. >> >> Why is it more efficient? The implementations are more or less >> analogue, with the exception that seq-position additionally increments a >> counter. > > Because seq-some involves an additional level of function indirection. > This is confirmed by profiling and the attached mini-benchmark, when run > as follows: > > emacs -batch -f batch-byte-compile bench.el > emacs -script bench.elc Oops, forgot to attach. -- Basil ^ permalink raw reply [flat|nested] 43+ messages in thread
* bug#34852: 26.1; seq-intersection ignores nil as element 2019-03-14 13:09 ` Michael Heerdegen 2019-03-14 13:34 ` Stefan Monnier 2019-03-14 16:17 ` Basil L. Contovounesios @ 2019-03-14 16:45 ` Nicolas Petton 2019-03-14 17:08 ` Basil L. Contovounesios 2 siblings, 1 reply; 43+ messages in thread From: Nicolas Petton @ 2019-03-14 16:45 UTC (permalink / raw) To: Michael Heerdegen, Basil L. Contovounesios Cc: Miguel V. S. Frasson, 34852, Stefan Monnier [-- Attachment #1: Type: text/plain, Size: 410 bytes --] Michael Heerdegen <michael_heerdegen@web.de> writes: Hi Michael, > We also have `seq-some' which can be used as a contain predicate, > e.g. to fix this bug: Using seq-contains was wrong, and I think seq-some should have been used instead, so I like your patch better (it's IMO better to use seq-some used as a predicate than seq-position). Unless somebody disagrees, I'll install your patch. Cheers, Nico [-- Attachment #2: signature.asc --] [-- Type: application/pgp-signature, Size: 487 bytes --] ^ permalink raw reply [flat|nested] 43+ messages in thread
* bug#34852: 26.1; seq-intersection ignores nil as element 2019-03-14 16:45 ` Nicolas Petton @ 2019-03-14 17:08 ` Basil L. Contovounesios 2019-03-18 11:55 ` Nicolas Petton 0 siblings, 1 reply; 43+ messages in thread From: Basil L. Contovounesios @ 2019-03-14 17:08 UTC (permalink / raw) To: Nicolas Petton Cc: Michael Heerdegen, Miguel V. S. Frasson, 34852, Stefan Monnier Nicolas Petton <nicolas@petton.fr> writes: > Michael Heerdegen <michael_heerdegen@web.de> writes: > > Hi Michael, > >> We also have `seq-some' which can be used as a contain predicate, >> e.g. to fix this bug: > > Using seq-contains was wrong, and I think seq-some should have been used > instead, so I like your patch better (it's IMO better to use seq-some > used as a predicate than seq-position). > > Unless somebody disagrees, I'll install your patch. If you go with the seq-some patch then please edit it to avoid using apply-partially, which is quite inefficient. The implementations of seq-set-equal-p, seq-uniq, and seq-difference will also need to be updated, in addition to that of seq-intersection. -- Basil ^ permalink raw reply [flat|nested] 43+ messages in thread
* bug#34852: 26.1; seq-intersection ignores nil as element 2019-03-14 17:08 ` Basil L. Contovounesios @ 2019-03-18 11:55 ` Nicolas Petton 2019-03-18 19:06 ` Michael Heerdegen 2019-03-20 20:51 ` Nicolas Petton 0 siblings, 2 replies; 43+ messages in thread From: Nicolas Petton @ 2019-03-18 11:55 UTC (permalink / raw) To: Basil L. Contovounesios Cc: Michael Heerdegen, Miguel V. S. Frasson, 34852, Stefan Monnier [-- Attachment #1: Type: text/plain, Size: 879 bytes --] "Basil L. Contovounesios" <contovob@tcd.ie> writes: >> Unless somebody disagrees, I'll install your patch. > > If you go with the seq-some patch then please edit it to avoid using > apply-partially, which is quite inefficient. Yes, will do. > The implementations of seq-set-equal-p, seq-uniq, and seq-difference > will also need to be updated, in addition to that of seq-intersection. Yes, thank you. I'm now thinking about introducing a proper predicate to be used instead of seq-contains for such cases, I would name it `seq-includes-p'. Here are my reasons: - seq-some takes a predicate function, but we'd like a function that takes an elt to be tested. - seq-contains returns the element found on purpose, it is not a predicate. I think it has its use-cases, and I don't want to change it into a predicate now (I would have to rename it anyway). Cheers, Nico [-- Attachment #2: signature.asc --] [-- Type: application/pgp-signature, Size: 487 bytes --] ^ permalink raw reply [flat|nested] 43+ messages in thread
* bug#34852: 26.1; seq-intersection ignores nil as element 2019-03-18 11:55 ` Nicolas Petton @ 2019-03-18 19:06 ` Michael Heerdegen 2019-03-18 20:14 ` Nicolas Petton 2019-03-20 20:51 ` Nicolas Petton 1 sibling, 1 reply; 43+ messages in thread From: Michael Heerdegen @ 2019-03-18 19:06 UTC (permalink / raw) To: Nicolas Petton Cc: Basil L. Contovounesios, Miguel V. S. Frasson, 34852, Stefan Monnier Nicolas Petton <nicolas@petton.fr> writes: > - seq-contains returns the element found on purpose, it is not a > predicate. I think it has its use-cases, and I don't want to change > it into a predicate now (I would have to rename it anyway). I think most current appearances are using it as a predicate, however. What do you intend - obsolete seq-contains? I don't think we should have an additional function - seq-contains already overlaps with seq-some. Why would you have to rename it btw? To add a -p (I ask because seq-some also doesn't end with -p)? Just pondering... Michael. ^ permalink raw reply [flat|nested] 43+ messages in thread
* bug#34852: 26.1; seq-intersection ignores nil as element 2019-03-18 19:06 ` Michael Heerdegen @ 2019-03-18 20:14 ` Nicolas Petton 0 siblings, 0 replies; 43+ messages in thread From: Nicolas Petton @ 2019-03-18 20:14 UTC (permalink / raw) To: Michael Heerdegen Cc: Basil L. Contovounesios, Miguel V. S. Frasson, 34852, Stefan Monnier [-- Attachment #1: Type: text/plain, Size: 656 bytes --] Michael Heerdegen <michael_heerdegen@web.de> writes: > I think most current appearances are using it as a predicate, however. You have a point and we also have `seq-find' which returns the element found. > What do you intend - obsolete seq-contains? I don't think we should > have an additional function - seq-contains already overlaps with > seq-some. I didn't think about it, obsoleting `seq-contains' would work as well, and it can actually make sense. I would then name the new function `seq-contains-p'. > Why would you have to rename it btw? To add a -p (I ask because > seq-some also doesn't end with -p)? Yes, to add a -p suffix. Nicolas [-- Attachment #2: signature.asc --] [-- Type: application/pgp-signature, Size: 487 bytes --] ^ permalink raw reply [flat|nested] 43+ messages in thread
* bug#34852: 26.1; seq-intersection ignores nil as element 2019-03-18 11:55 ` Nicolas Petton 2019-03-18 19:06 ` Michael Heerdegen @ 2019-03-20 20:51 ` Nicolas Petton 2019-03-20 22:33 ` Michael Heerdegen 2019-03-21 17:46 ` Basil L. Contovounesios 1 sibling, 2 replies; 43+ messages in thread From: Nicolas Petton @ 2019-03-20 20:51 UTC (permalink / raw) To: Basil L. Contovounesios Cc: Michael Heerdegen, Miguel V. S. Frasson, 34852, Stefan Monnier [-- Attachment #1.1: Type: text/plain, Size: 33 bytes --] Hi, Here's a patch for master. [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #1.2: 0001-New-seq-contains-p-predicate-Bug-34852.patch --] [-- Type: text/x-patch, Size: 6097 bytes --] From 985aa028f05a418dddfd6394b739f42c32b01345 Mon Sep 17 00:00:00 2001 From: Nicolas Petton <nicolas@petton.fr> Date: Wed, 20 Mar 2019 21:44:01 +0100 Subject: [PATCH] New seq-contains-p predicate (Bug#34852) * lisp/emacs-lisp/seq.el (seq-contains-p): New predicate function. It is a replacement for seq-contains which cannot be used as a predicate when a sequence contains nil values as it returns the element found. (seq-contains): Make obsolete. * test/lisp/emacs-lisp/seq-tests.el (test-seq-contains-p): (test-seq-intersection-with-nil, test-seq-set-equal-p-with-nil, test-difference-with-nil): Add regression tests. * doc/lispref/sequences.texi (Sequence Functions): Document seq-contains-p. --- doc/lispref/sequences.texi | 9 +++++---- lisp/emacs-lisp/seq.el | 20 +++++++++++++++----- test/lisp/emacs-lisp/seq-tests.el | 21 +++++++++++++++++++++ 3 files changed, 41 insertions(+), 9 deletions(-) diff --git a/doc/lispref/sequences.texi b/doc/lispref/sequences.texi index 0c3c4e3b28..a7f270c068 100644 --- a/doc/lispref/sequences.texi +++ b/doc/lispref/sequences.texi @@ -782,10 +782,11 @@ Sequence Functions @end defun -@defun seq-contains sequence elt &optional function - This function returns the first element in @var{sequence} that is equal to -@var{elt}. If the optional argument @var{function} is non-@code{nil}, -it is a function of two arguments to use instead of the default @code{equal}. +@defun seq-contains-p sequence elt &optional function + This function returns non-@code{nil} if at least one element in +@var{sequence} is equal to @var{elt}. If the optional argument +@var{function} is non-@code{nil}, it is a function of two arguments to +use instead of the default @code{equal}. @example @group diff --git a/lisp/emacs-lisp/seq.el b/lisp/emacs-lisp/seq.el index 4a811d7895..39c93e25ed 100644 --- a/lisp/emacs-lisp/seq.el +++ b/lisp/emacs-lisp/seq.el @@ -356,6 +356,7 @@ seq-sort-by count)) (cl-defgeneric seq-contains (sequence elt &optional testfn) + (declare (obsolete "Use `seq-contains-p' instead." "27.1")) "Return the first element in SEQUENCE that is equal to ELT. Equality is defined by TESTFN if non-nil or by `equal' if nil." (seq-some (lambda (e) @@ -363,11 +364,20 @@ seq-sort-by e)) sequence)) +(cl-defgeneric seq-contains-p (sequence elt &optional testfn) + "Return non-nil if SEQUENCE contains an element equal to ELT. +Equality is defined by TESTFN if non-nil or by `equal' if nil." + (catch 'seq--break + (seq-doseq (e sequence) + (when (funcall (or testfn #'equal) e elt) + (throw 'seq--break t))) + nil)) + (cl-defgeneric seq-set-equal-p (sequence1 sequence2 &optional testfn) "Return non-nil if SEQUENCE1 and SEQUENCE2 contain the same elements, regardless of order. Equality is defined by TESTFN if non-nil or by `equal' if nil." - (and (seq-every-p (lambda (item1) (seq-contains sequence2 item1 testfn)) sequence1) - (seq-every-p (lambda (item2) (seq-contains sequence1 item2 testfn)) sequence2))) + (and (seq-every-p (lambda (item1) (seq-contains-p sequence2 item1 testfn)) sequence1) + (seq-every-p (lambda (item2) (seq-contains-p sequence1 item2 testfn)) sequence2))) (cl-defgeneric seq-position (sequence elt &optional testfn) "Return the index of the first element in SEQUENCE that is equal to ELT. @@ -385,7 +395,7 @@ seq-sort-by TESTFN is used to compare elements, or `equal' if TESTFN is nil." (let ((result '())) (seq-doseq (elt sequence) - (unless (seq-contains result elt testfn) + (unless (seq-contains-p result elt testfn) (setq result (cons elt result)))) (nreverse result))) @@ -410,7 +420,7 @@ seq-sort-by "Return a list of the elements that appear in both SEQUENCE1 and SEQUENCE2. Equality is defined by TESTFN if non-nil or by `equal' if nil." (seq-reduce (lambda (acc elt) - (if (seq-contains sequence2 elt testfn) + (if (seq-contains-p sequence2 elt testfn) (cons elt acc) acc)) (seq-reverse sequence1) @@ -420,7 +430,7 @@ seq-sort-by "Return a list of the elements that appear in SEQUENCE1 but not in SEQUENCE2. Equality is defined by TESTFN if non-nil or by `equal' if nil." (seq-reduce (lambda (acc elt) - (if (not (seq-contains sequence2 elt testfn)) + (if (not (seq-contains-p sequence2 elt testfn)) (cons elt acc) acc)) (seq-reverse sequence1) diff --git a/test/lisp/emacs-lisp/seq-tests.el b/test/lisp/emacs-lisp/seq-tests.el index d8f00cfea4..6522def423 100644 --- a/test/lisp/emacs-lisp/seq-tests.el +++ b/test/lisp/emacs-lisp/seq-tests.el @@ -185,6 +185,14 @@ test-sequences-oddp (with-test-sequences (seq '(3 4 5 6)) (should (= 5 (seq-contains seq 5))))) +(ert-deftest test-seq-contains-p () + (with-test-sequences (seq '(3 4 5 6)) + (should (eq (seq-contains-p seq 3) t)) + (should-not (seq-contains-p seq 7))) + (with-test-sequences (seq '()) + (should-not (seq-contains-p seq 3)) + (should-not (seq-contains-p seq nil)))) + (ert-deftest test-seq-every-p () (with-test-sequences (seq '(43 54 22 1)) (should (seq-every-p (lambda (elt) t) seq)) @@ -436,5 +444,18 @@ test-sequences-oddp (should (equal (seq-rest lst) '(2 3))) (should (equal (seq-rest vec) [2 3])))) +;; Regression tests for bug#34852 +(progn + (ert-deftest test-seq-intersection-with-nil () + (should (equal (seq-intersection '(1 2 nil) '(1 nil)) '(1 nil)))) + + (ert-deftest test-seq-set-equal-p-with-nil () + (should (seq-set-equal-p '("a" "b" nil) + '(nil "b" "a")))) + + (ert-deftest test-difference-with-nil () + (should (equal (seq-difference '(1 nil) '(2 nil)) + '(1))))) + (provide 'seq-tests) ;;; seq-tests.el ends here -- 2.20.1 [-- Attachment #1.3: Type: text/plain, Size: 6 bytes --] Nico [-- Attachment #2: signature.asc --] [-- Type: application/pgp-signature, Size: 487 bytes --] ^ permalink raw reply related [flat|nested] 43+ messages in thread
* bug#34852: 26.1; seq-intersection ignores nil as element 2019-03-20 20:51 ` Nicolas Petton @ 2019-03-20 22:33 ` Michael Heerdegen 2019-03-21 8:02 ` Nicolas Petton 2019-03-21 17:46 ` Basil L. Contovounesios 1 sibling, 1 reply; 43+ messages in thread From: Michael Heerdegen @ 2019-03-20 22:33 UTC (permalink / raw) To: Nicolas Petton Cc: Basil L. Contovounesios, Miguel V. S. Frasson, 34852, Stefan Monnier Nicolas Petton <nicolas@petton.fr> writes: > +(cl-defgeneric seq-contains-p (sequence elt &optional testfn) > + "Return non-nil if SEQUENCE contains an element equal to ELT. > +Equality is defined by TESTFN if non-nil or by `equal' if nil." > + (catch 'seq--break > + (seq-doseq (e sequence) > + (when (funcall (or testfn #'equal) e elt) > + (throw 'seq--break t))) > + nil)) A detail: could you factor out the result of (or testfn #'equal) so that `or' is not called repeatedly in the loop? Michael. ^ permalink raw reply [flat|nested] 43+ messages in thread
* bug#34852: 26.1; seq-intersection ignores nil as element 2019-03-20 22:33 ` Michael Heerdegen @ 2019-03-21 8:02 ` Nicolas Petton 0 siblings, 0 replies; 43+ messages in thread From: Nicolas Petton @ 2019-03-21 8:02 UTC (permalink / raw) To: Michael Heerdegen Cc: Basil L. Contovounesios, Miguel V. S. Frasson, 34852, Stefan Monnier [-- Attachment #1: Type: text/plain, Size: 230 bytes --] Michael Heerdegen <michael_heerdegen@web.de> writes: > A detail: could you factor out the result of (or testfn #'equal) so that > `or' is not called repeatedly in the loop? Yes, and I'll do that elsewhere as well. Cheers, Nico [-- Attachment #2: signature.asc --] [-- Type: application/pgp-signature, Size: 487 bytes --] ^ permalink raw reply [flat|nested] 43+ messages in thread
* bug#34852: 26.1; seq-intersection ignores nil as element 2019-03-20 20:51 ` Nicolas Petton 2019-03-20 22:33 ` Michael Heerdegen @ 2019-03-21 17:46 ` Basil L. Contovounesios 2019-03-21 20:01 ` Nicolas Petton 2019-03-21 20:16 ` Nicolas Petton 1 sibling, 2 replies; 43+ messages in thread From: Basil L. Contovounesios @ 2019-03-21 17:46 UTC (permalink / raw) To: Nicolas Petton Cc: Michael Heerdegen, Miguel V. S. Frasson, 34852, Stefan Monnier Nicolas Petton <nicolas@petton.fr> writes: > Here's a patch for master. Thanks, I have only some minor comments: > diff --git a/lisp/emacs-lisp/seq.el b/lisp/emacs-lisp/seq.el > index 4a811d7895..39c93e25ed 100644 > --- a/lisp/emacs-lisp/seq.el > +++ b/lisp/emacs-lisp/seq.el > @@ -356,6 +356,7 @@ seq-sort-by > count)) > > (cl-defgeneric seq-contains (sequence elt &optional testfn) > + (declare (obsolete "Use `seq-contains-p' instead." "27.1")) According to make-obsolete, "use instead" strings should not start with a capital letter, but even better is (obsolete seq-contains-p "27.1"), which adds a link to seq-contains-p in the *Help* buffer. > @@ -420,7 +430,7 @@ seq-sort-by > "Return a list of the elements that appear in SEQUENCE1 but not in SEQUENCE2. > Equality is defined by TESTFN if non-nil or by `equal' if nil." > (seq-reduce (lambda (acc elt) > - (if (not (seq-contains sequence2 elt testfn)) > + (if (not (seq-contains-p sequence2 elt testfn)) > (cons elt acc) > acc)) Is there any harm in inverting this conditional structure, so that it reads positively? > diff --git a/test/lisp/emacs-lisp/seq-tests.el b/test/lisp/emacs-lisp/seq-tests.el > index d8f00cfea4..6522def423 100644 > --- a/test/lisp/emacs-lisp/seq-tests.el > +++ b/test/lisp/emacs-lisp/seq-tests.el > @@ -185,6 +185,14 @@ test-sequences-oddp > (with-test-sequences (seq '(3 4 5 6)) > (should (= 5 (seq-contains seq 5))))) > > +(ert-deftest test-seq-contains-p () > + (with-test-sequences (seq '(3 4 5 6)) > + (should (eq (seq-contains-p seq 3) t)) > + (should-not (seq-contains-p seq 7))) > + (with-test-sequences (seq '()) > + (should-not (seq-contains-p seq 3)) > + (should-not (seq-contains-p seq nil)))) > + I think there should also be an explicit nil membership check: (should (seq-contains-p [nil] nil)) (should (seq-contains-p '(nil) nil)) -- Basil ^ permalink raw reply [flat|nested] 43+ messages in thread
* bug#34852: 26.1; seq-intersection ignores nil as element 2019-03-21 17:46 ` Basil L. Contovounesios @ 2019-03-21 20:01 ` Nicolas Petton 2019-03-21 20:16 ` Nicolas Petton 1 sibling, 0 replies; 43+ messages in thread From: Nicolas Petton @ 2019-03-21 20:01 UTC (permalink / raw) To: Basil L. Contovounesios Cc: Michael Heerdegen, Miguel V. S. Frasson, 34852, Stefan Monnier [-- Attachment #1: Type: text/plain, Size: 1538 bytes --] "Basil L. Contovounesios" <contovob@tcd.ie> writes: > Nicolas Petton <nicolas@petton.fr> writes: > >> (cl-defgeneric seq-contains (sequence elt &optional testfn) >> + (declare (obsolete "Use `seq-contains-p' instead." "27.1")) > > According to make-obsolete, "use instead" strings should not start with > a capital letter, but even better is (obsolete seq-contains-p "27.1"), > which adds a link to seq-contains-p in the *Help* buffer. Indeed, that's better, thank you. >> @@ -420,7 +430,7 @@ seq-sort-by >> "Return a list of the elements that appear in SEQUENCE1 but not in SEQUENCE2. >> Equality is defined by TESTFN if non-nil or by `equal' if nil." >> (seq-reduce (lambda (acc elt) >> - (if (not (seq-contains sequence2 elt testfn)) >> + (if (not (seq-contains-p sequence2 elt testfn)) >> (cons elt acc) >> acc)) > > Is there any harm in inverting this conditional structure, so that it > reads positively? It's not the purpose of this patch, but I can commit it separately. >> +(ert-deftest test-seq-contains-p () >> + (with-test-sequences (seq '(3 4 5 6)) >> + (should (eq (seq-contains-p seq 3) t)) >> + (should-not (seq-contains-p seq 7))) >> + (with-test-sequences (seq '()) >> + (should-not (seq-contains-p seq 3)) >> + (should-not (seq-contains-p seq nil)))) >> + > > I think there should also be an explicit nil membership check: > > (should (seq-contains-p [nil] nil)) > (should (seq-contains-p '(nil) nil)) Good idea! Nico [-- Attachment #2: signature.asc --] [-- Type: application/pgp-signature, Size: 487 bytes --] ^ permalink raw reply [flat|nested] 43+ messages in thread
* bug#34852: 26.1; seq-intersection ignores nil as element 2019-03-21 17:46 ` Basil L. Contovounesios 2019-03-21 20:01 ` Nicolas Petton @ 2019-03-21 20:16 ` Nicolas Petton 1 sibling, 0 replies; 43+ messages in thread From: Nicolas Petton @ 2019-03-21 20:16 UTC (permalink / raw) To: Basil L. Contovounesios Cc: Michael Heerdegen, Miguel V. S. Frasson, 34852, Stefan Monnier [-- Attachment #1: Type: text/plain, Size: 250 bytes --] tags 34852 fixed close 34852 27.1 thanks "Basil L. Contovounesios" <contovob@tcd.ie> writes: > Nicolas Petton <nicolas@petton.fr> writes: > >> Here's a patch for master. I pushed a revised patch to master, so I'm closing this issue. Cheers, Nico [-- Attachment #2: signature.asc --] [-- Type: application/pgp-signature, Size: 487 bytes --] ^ permalink raw reply [flat|nested] 43+ messages in thread
end of thread, other threads:[~2019-03-21 20:16 UTC | newest] Thread overview: 43+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2019-03-14 2:16 bug#34852: 26.1; seq-intersection ignores nil as element Miguel V. S. Frasson 2019-03-14 12:07 ` Michael Heerdegen 2019-03-14 13:09 ` Nicolas Petton 2019-03-14 12:22 ` Basil L. Contovounesios 2019-03-14 12:52 ` Miguel V. S. Frasson 2019-03-14 16:16 ` Basil L. Contovounesios 2019-03-14 13:09 ` Michael Heerdegen 2019-03-14 13:34 ` Stefan Monnier 2019-03-14 16:19 ` Basil L. Contovounesios 2019-03-14 16:45 ` Michael Heerdegen 2019-03-14 17:14 ` Basil L. Contovounesios 2019-03-14 19:08 ` Miguel V. S. Frasson 2019-03-14 21:43 ` Stefan Monnier 2019-03-14 23:08 ` Miguel V. S. Frasson 2019-03-14 23:14 ` Stefan Monnier 2019-03-14 23:21 ` Miguel V. S. Frasson 2019-03-14 23:42 ` Michael Heerdegen 2019-03-15 2:40 ` Stefan Monnier 2019-03-15 12:26 ` Michael Heerdegen 2019-03-15 14:47 ` Stefan Monnier 2019-03-14 23:45 ` Miguel V. S. Frasson 2019-03-14 23:15 ` Michael Heerdegen 2019-03-15 15:56 ` Basil L. Contovounesios 2019-03-15 16:08 ` Miguel V. S. Frasson 2019-03-16 20:33 ` Miguel V. S. Frasson 2019-03-16 20:49 ` Basil L. Contovounesios 2019-03-16 21:32 ` Miguel V. S. Frasson 2019-03-15 15:55 ` Basil L. Contovounesios 2019-03-14 16:17 ` Basil L. Contovounesios 2019-03-14 16:35 ` Michael Heerdegen 2019-03-14 17:02 ` Basil L. Contovounesios 2019-03-14 17:23 ` Basil L. Contovounesios 2019-03-14 16:45 ` Nicolas Petton 2019-03-14 17:08 ` Basil L. Contovounesios 2019-03-18 11:55 ` Nicolas Petton 2019-03-18 19:06 ` Michael Heerdegen 2019-03-18 20:14 ` Nicolas Petton 2019-03-20 20:51 ` Nicolas Petton 2019-03-20 22:33 ` Michael Heerdegen 2019-03-21 8:02 ` Nicolas Petton 2019-03-21 17:46 ` Basil L. Contovounesios 2019-03-21 20:01 ` Nicolas Petton 2019-03-21 20:16 ` Nicolas Petton
Code repositories for project(s) associated with this external index https://git.savannah.gnu.org/cgit/emacs.git https://git.savannah.gnu.org/cgit/emacs/org-mode.git This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.