GNU bug report logs -
#58278
Add new function seq-keep
Previous Next
Reported by: Jonas Bernoulli <jonas <at> bernoul.li>
Date: Mon, 3 Oct 2022 21:31:02 UTC
Severity: normal
Fixed in version 29.1
Done: Lars Ingebrigtsen <larsi <at> gnus.org>
Bug is archived. No further changes may be made.
To add a comment to this bug, you must first unarchive it, by sending
a message to control AT debbugs.gnu.org, with unarchive 58278 in the body.
You can then email your comments to 58278 AT debbugs.gnu.org in the normal way.
Toggle the display of automated, internal messages from the tracker.
Report forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#58278
; Package
emacs
.
(Mon, 03 Oct 2022 21:31:02 GMT)
Full text and
rfc822 format available.
Acknowledgement sent
to
Jonas Bernoulli <jonas <at> bernoul.li>
:
New bug report received and forwarded. Copy sent to
bug-gnu-emacs <at> gnu.org
.
(Mon, 03 Oct 2022 21:31:02 GMT)
Full text and
rfc822 format available.
Message #5 received at submit <at> debbugs.gnu.org (full text, mbox):
While I still appreciate the `dash' package, I try to avoid it in
a package when all or most of its used `dash' functions and macros,
can be replaced with equivalent functions/macros from `seq', `cl-lib'
or other parts of Emacs.
Unfortunately I cannot find a replacement for `-keep', which I have been
using a lot. I propose that we add something like:
(cl-defgeneric seq-keep (pred sequence)
"Return a list of all non-nil results of (PRED element) for elements in SEQUENCE."
(delq nil (seq-map (lambda (elt) (funcall pred elt))
sequence)))
Cheers,
Jonas
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#58278
; Package
emacs
.
(Mon, 03 Oct 2022 23:49:02 GMT)
Full text and
rfc822 format available.
Message #8 received at 58278 <at> debbugs.gnu.org (full text, mbox):
Jonas Bernoulli <jonas <at> bernoul.li> writes:
> Unfortunately I cannot find a replacement for `-keep', which I have been
> using a lot. I propose that we add something like:
>
> (cl-defgeneric seq-keep (pred sequence)
> "Return a list of all non-nil results of (PRED element) for elements in SEQUENCE."
> (delq nil (seq-map (lambda (elt) (funcall pred elt))
> sequence)))
Hm... well, here PRED isn't a predicate, really, but a transforming
function? But you wish to filter out the nil results of that
transforming function.
That sounds useful -- there's more than a 100 matches for "delq
nil.*map" in-tree only -- but it's slightly confusing that the function
isn't altogether a predicate, but only kinda. Would a function
signature like
(cl-defgeneric seq-keep (function sequence &optional pred)
...)
make more sense for this combination of map/filter? (The default
predicate would, of course, be "not null".)
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#58278
; Package
emacs
.
(Tue, 04 Oct 2022 10:07:01 GMT)
Full text and
rfc822 format available.
Message #11 received at 58278 <at> debbugs.gnu.org (full text, mbox):
>>>>> On Tue, 04 Oct 2022 01:47:59 +0200, Lars Ingebrigtsen <larsi <at> gnus.org> said:
Lars> Jonas Bernoulli <jonas <at> bernoul.li> writes:
>> Unfortunately I cannot find a replacement for `-keep', which I have been
>> using a lot. I propose that we add something like:
>>
>> (cl-defgeneric seq-keep (pred sequence)
>> "Return a list of all non-nil results of (PRED element) for elements in SEQUENCE."
>> (delq nil (seq-map (lambda (elt) (funcall pred elt))
>> sequence)))
Lars> Hm... well, here PRED isn't a predicate, really, but a transforming
Lars> function? But you wish to filter out the nil results of that
Lars> transforming function.
Lars> That sounds useful -- there's more than a 100 matches for "delq
Lars> nil.*map" in-tree only -- but it's slightly confusing that the function
Lars> isn't altogether a predicate, but only kinda. Would a function
Lars> signature like
Lars> (cl-defgeneric seq-keep (function sequence &optional pred)
Lars> ...)
Lars> make more sense for this combination of map/filter? (The default
Lars> predicate would, of course, be "not null".)
How is this different from 'cl-mapcan'? (apart from the syntactic sugar)
Robert
--
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#58278
; Package
emacs
.
(Tue, 04 Oct 2022 10:15:01 GMT)
Full text and
rfc822 format available.
Message #14 received at 58278 <at> debbugs.gnu.org (full text, mbox):
Robert Pluim <rpluim <at> gmail.com> writes:
> How is this different from 'cl-mapcan'? (apart from the syntactic sugar)
I don't see how seq-keep would resemble cl-mapcan much?
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#58278
; Package
emacs
.
(Tue, 04 Oct 2022 10:28:02 GMT)
Full text and
rfc822 format available.
Message #17 received at 58278 <at> debbugs.gnu.org (full text, mbox):
>>>>> On Tue, 04 Oct 2022 12:13:55 +0200, Lars Ingebrigtsen <larsi <at> gnus.org> said:
Lars> Robert Pluim <rpluim <at> gmail.com> writes:
>> How is this different from 'cl-mapcan'? (apart from the syntactic sugar)
Lars> I don't see how seq-keep would resemble cl-mapcan much?
Well, cl-mapcan applies a function to the elements of a sequence and
discards 'nil' results. Looks pretty similar to me.
Robert
--
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#58278
; Package
emacs
.
(Tue, 04 Oct 2022 10:43:02 GMT)
Full text and
rfc822 format available.
Message #20 received at 58278 <at> debbugs.gnu.org (full text, mbox):
Robert Pluim <rpluim <at> gmail.com> writes:
> Well, cl-mapcan applies a function to the elements of a sequence and
> discards 'nil' results. Looks pretty similar to me.
No, it concatenates the results, so the values returned by the function
has to be lists.
But, yes, if you return lists, then nil return values will "disappear".
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#58278
; Package
emacs
.
(Tue, 04 Oct 2022 10:51:02 GMT)
Full text and
rfc822 format available.
Message #23 received at 58278 <at> debbugs.gnu.org (full text, mbox):
>>>>> On Tue, 04 Oct 2022 12:42:50 +0200, Lars Ingebrigtsen <larsi <at> gnus.org> said:
Lars> Robert Pluim <rpluim <at> gmail.com> writes:
>> Well, cl-mapcan applies a function to the elements of a sequence and
>> discards 'nil' results. Looks pretty similar to me.
Lars> No, it concatenates the results, so the values returned by the function
Lars> has to be lists.
That始s why I said "apart from the syntactic sugar" 馃榾
Robert
--
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#58278
; Package
emacs
.
(Tue, 04 Oct 2022 11:11:01 GMT)
Full text and
rfc822 format available.
Message #26 received at 58278 <at> debbugs.gnu.org (full text, mbox):
Robert Pluim <rpluim <at> gmail.com> writes:
> That始s why I said "apart from the syntactic sugar" 馃榾
Having to rewrite
(seq-keep #'cl-digit-char-p '(?6 ?a))
=> (6)
to
(cl-mapcan (lambda (c)
(let ((res (cl-digit-char-p c)))
(and res (list res))))
'(?6 ?a))
=> (6)
is more than "syntactic sugar" in my book. Nobody would want to write
code like the latter.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#58278
; Package
emacs
.
(Tue, 04 Oct 2022 11:22:01 GMT)
Full text and
rfc822 format available.
Message #29 received at 58278 <at> debbugs.gnu.org (full text, mbox):
>>>>> On Tue, 04 Oct 2022 13:10:38 +0200, Lars Ingebrigtsen <larsi <at> gnus.org> said:
Lars> Robert Pluim <rpluim <at> gmail.com> writes:
>> That始s why I said "apart from the syntactic sugar" 馃榾
Lars> Having to rewrite
Lars> (seq-keep #'cl-digit-char-p '(?6 ?a))
Lars> => (6)
Lars> to
Lars> (cl-mapcan (lambda (c)
Lars> (let ((res (cl-digit-char-p c)))
Lars> (and res (list res))))
Lars> '(?6 ?a))
Lars> => (6)
Lars> is more than "syntactic sugar" in my book. Nobody would want to write
Lars> code like the latter.
I never meant that. I meant defining `seq-keep' in terms of `'cl-mapcan',
with the appropriate converting elements to lists done for you (or
even using `mapcan' if you始re willing to give up the &rest behaviour
of `cl-mapcan')
Robert
--
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#58278
; Package
emacs
.
(Tue, 04 Oct 2022 11:24:01 GMT)
Full text and
rfc822 format available.
Message #32 received at 58278 <at> debbugs.gnu.org (full text, mbox):
Robert Pluim <rpluim <at> gmail.com> writes:
> I never meant that. I meant defining `seq-keep' in terms of `'cl-mapcan',
> with the appropriate converting elements to lists done for you (or
> even using `mapcan' if you始re willing to give up the &rest behaviour
> of `cl-mapcan')
Oh, OK. I don't think that would be particularly efficient, though.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#58278
; Package
emacs
.
(Tue, 04 Oct 2022 11:38:01 GMT)
Full text and
rfc822 format available.
Message #35 received at 58278 <at> debbugs.gnu.org (full text, mbox):
>>>>> On Tue, 04 Oct 2022 13:23:02 +0200, Lars Ingebrigtsen <larsi <at> gnus.org> said:
Lars> Robert Pluim <rpluim <at> gmail.com> writes:
>> I never meant that. I meant defining `seq-keep' in terms of `'cl-mapcan',
>> with the appropriate converting elements to lists done for you (or
>> even using `mapcan' if you始re willing to give up the &rest behaviour
>> of `cl-mapcan')
Lars> Oh, OK. I don't think that would be particularly efficient, though.
I始ve measured it: it始s not (even when using mapcan) :-)
Robert
--
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#58278
; Package
emacs
.
(Tue, 04 Oct 2022 12:51:02 GMT)
Full text and
rfc822 format available.
Message #38 received at 58278 <at> debbugs.gnu.org (full text, mbox):
Lars Ingebrigtsen <larsi <at> gnus.org> writes:
> Would a function signature like
>
> (cl-defgeneric seq-keep (function sequence &optional pred)
> ...)
>
> make more sense for this combination of map/filter? (The default
> predicate would, of course, be "not null".)
Yes, that would be an improvement. Some (but certainly not all)
uses of dash's `-keep' look something like
(-keep (lambda (elt)
(and (symbolp elt)
(symbol-name elt)))
sequence)
and
(seq-keep #'symbol-name sequence #'symbolp)
would be much nicer in those situations.
In at least some of those cases `mapcan' would work just as well
as `-keep', so after adding &optional PRED, `seq-keep' could also
be used in many places one would have reached for `mapcan' before,
making it even more useful.
I am unsure how I feel about it myself, but we should also consider
(function pred sequence)
PRED wouldn't be optional then, but we should of course allow it to
be nil. (Forcing the use of #'identity would not make sense, since
we want FUNCTION to serve both as a predicate and a transforming
function in that case.)
Concerning the argument order, in my opinion
(seq-keep (lambda (elt)
...)
(lambda (elt)
...)
sequence)
looks better than
(seq-keep (lambda (elt)
...)
sequence
(lambda (elt)
...))
because the variable named "sequence" looks out of place in the second
instance. But of course all of FUNCTION, PRED and SEQUENCE can be just
a symbol or a more complex expression. For instance if only PRED is
complex, then
(seq-keep #'symbol-name sequence
(lambda (elt)
...))
looks better than
(seq-keep #'symbol-name
(lambda (elt)
...)
sequence)
So there is no order that is always best, from an aesthetic point
of view. In my own use at least, most of the time either all three
arguments would be moderately complex expressions or only the two
functions arguments would complex and the sequence argument would be
just a variable. For that reason I would favor the two functions to
be placed next to each other, I think.
The (function pred sequence) argument list has the advantage that it
is in (reverse) "chronological" order. First we have a sequence, then
we filter the elements, and finally we transform the elements that we
kept, at least conceptually.
Using actual chronological order (sequence pred function) is out of
question as that would conflict with all(?) other mapping functions;
as is (sequence [pred] function), I presume.
Just some food for thought; as of yet, I am unsure what order I
prefer myself -- though I lean towards (function pred sequence).
But if that is deemed unusual and thus undesirable, (function
sequence &optional pred) also works for me.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#58278
; Package
emacs
.
(Tue, 04 Oct 2022 13:48:02 GMT)
Full text and
rfc822 format available.
Message #41 received at 58278 <at> debbugs.gnu.org (full text, mbox):
Jonas Bernoulli <jonas <at> bernoul.li> writes:
> Yes, that would be an improvement. Some (but certainly not all)
> uses of dash's `-keep' look something like
>
> (-keep (lambda (elt)
> (and (symbolp elt)
> (symbol-name elt)))
> sequence)
>
> and
>
> (seq-keep #'symbol-name sequence #'symbolp)
>
> would be much nicer in those situations.
Hm... That's not exactly what I was thinking here. I was thinking
(cl-defgeneric seq-keep (func sequence &optional pred)
(if pred
(seq-filter pred (seq-mapcar func sequence))
(delq nil (seq-mapcar func sequence))))
which is the traditional "keep" semantics, but allows extending the
concept of "keep" to more than "is non-nil".
But that may well be an overcomplication -- in the unusual cases where
it's not nil that people want to keep, they can just type
(seq-filter pred (seq-mapcar func sequence))
themselves, which has very clear semantics.
So I think, on second consideration, I'd rather just go with
(cl-defgeneric seq-keep (func sequence)
(delq nil (seq-mapcar func sequence)))
like you originally suggested (but with just an argument name change).
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#58278
; Package
emacs
.
(Tue, 04 Oct 2022 13:57:01 GMT)
Full text and
rfc822 format available.
Message #44 received at 58278 <at> debbugs.gnu.org (full text, mbox):
Just for kicks, here's some random "del.*map" instances from the
Emacs sources:
(delq nil (mapcar (lambda (n) (and (>= n 0) n)) articles))
This should be (seq-filter #'cl-plusp articles).
(delq nil (mapcar #'gnus-server-to-method gnus-agent-covered-methods))
This would be nice as seq-keep.
(delq nil (mapcar
(lambda (c)
(when (string-prefix-p base c)
(substring c base-size)))
hist)))))
Ditto.
(delq nil (mapcar (lambda (action)
(cond
((eq action 'create) 'created)
((eq action 'modify) 'changed)
((eq action 'attrib) 'attribute-changed)
((memq action '(delete delete-self move-self)) 'deleted)
((eq action 'moved-from) 'renamed-from)
((eq action 'moved-to) 'renamed-to)
((eq action 'ignored) 'stopped)))
actions))
Ditto.
(delq nil (mapcar
(lambda (x) (if (string-match "\\`\\." x) x))
ido-temp-list)))
This should be seq-filter.
(cookies (delq nil (mapcar
(lambda (e)
(org-list-get-checkbox e s))
items))))
seq-keep.
(let* ((have (delq nil (mapcar
(lambda (x) (get-text-property 1 'time-of-day x))
list)))
seq-keep.
(string-join
(delq nil (mapcar
(lambda (item)
(when (cdr item)
(format "%s='%s'" (car item) (cdr item))))
`(("type" . ,type) ("sender" . ,sender)
("destination" . ,destination) ("path" . ,path)
("interface" . ,interface) ("member" . ,member))))
",")
seq-keep.
(reverse (delete "" (mapcar (lambda (r)
(replace-regexp-in-string "nil" "" r))
result0)))))))
This suggest that the signature should be
(func sequence &optional delete-element)
which defaults to nil, but could be "" here, and use seq-keep.
(delq 'type (mapcar #'car (haiku-selection-data clipboard nil))))
Ditto.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#58278
; Package
emacs
.
(Tue, 04 Oct 2022 14:00:02 GMT)
Full text and
rfc822 format available.
Message #47 received at 58278 <at> debbugs.gnu.org (full text, mbox):
Lars Ingebrigtsen <larsi <at> gnus.org> writes:
> This suggest that the signature should be
>
> (func sequence &optional delete-element)
>
> which defaults to nil, but could be "" here, and use seq-keep.
But that gets us into problems w.r.t. the comparison function -- we can
use delq here for "", but not for "foo", which seems inconsistent.
So... we're back to the (func sequence) as the signature.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#58278
; Package
emacs
.
(Tue, 04 Oct 2022 19:47:02 GMT)
Full text and
rfc822 format available.
Message #50 received at 58278 <at> debbugs.gnu.org (full text, mbox):
Lars Ingebrigtsen <larsi <at> gnus.org> writes:
> So... we're back to the (func sequence) as the signature.
So I've now added this to Emacs 29.
bug marked as fixed in version 29.1, send any further explanations to
58278 <at> debbugs.gnu.org and Jonas Bernoulli <jonas <at> bernoul.li>
Request was from
Lars Ingebrigtsen <larsi <at> gnus.org>
to
control <at> debbugs.gnu.org
.
(Tue, 04 Oct 2022 19:47:02 GMT)
Full text and
rfc822 format available.
bug archived.
Request was from
Debbugs Internal Request <help-debbugs <at> gnu.org>
to
internal_control <at> debbugs.gnu.org
.
(Wed, 02 Nov 2022 11:24:09 GMT)
Full text and
rfc822 format available.
bug No longer marked as fixed in versions 29.1 and reopened.
Request was from
Debbugs Internal Request <help-debbugs <at> gnu.org>
to
internal_control <at> debbugs.gnu.org
.
(Thu, 17 Nov 2022 02:03:01 GMT)
Full text and
rfc822 format available.
This bug report was last modified 2 years and 217 days ago.
Previous Next
GNU bug tracking system
Copyright (C) 1999 Darren O. Benham,
1997,2003 nCipher Corporation Ltd,
1994-97 Ian Jackson.