GNU bug report logs -
#78656
[PATCH] Add new reduction primitives `fold-left' and `fold-right'
Previous Next
To reply to this bug, email your comments to 78656 AT debbugs.gnu.org.
Toggle the display of automated, internal messages from the tracker.
Report forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#78656
; Package
emacs
.
(Sun, 01 Jun 2025 02:36:08 GMT)
Full text and
rfc822 format available.
Acknowledgement sent
to
Zach Shaftel <zach <at> shaf.tel>
:
New bug report received and forwarded. Copy sent to
bug-gnu-emacs <at> gnu.org
.
(Sun, 01 Jun 2025 02:36:08 GMT)
Full text and
rfc822 format available.
Message #5 received at submit <at> debbugs.gnu.org (full text, mbox):
[Message part 1 (text/plain, inline)]
Tags: patch
this patch adds left and right sequence reduction functions in C, along
with tests for them. i don't know if this is the sort of thing the
maintainers actually would want to merge, but i figured i would just
submit it and hear your feedback. would also appreciate any stylistic
feedback, for future patch submissions.
In GNU Emacs 31.0.50 (build 1, x86_64-pc-linux-gnu, GTK+ Version
3.24.49, cairo version 1.18.4) of 2025-05-27 built on bigbox
Repository revision: 75acd19b011febb3eb35ee1bec1552b96e1bb25a
Repository branch: HEAD
System Description: Arch Linux
Configured using:
'configure --with-modules --without-xwidgets --with-native-compilation
--with-tree-sitter --without-gsettings --without-gconf --without-gpm
--with-pgtk --without-compress-install --with-mps --without-xaw3d
'CFLAGS=-mtune=native -march=native -O2 -g''
[0001-Add-new-reduction-primitives-fold-left-and-fold-righ.patch (text/patch, attachment)]
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#78656
; Package
emacs
.
(Sun, 01 Jun 2025 05:48:06 GMT)
Full text and
rfc822 format available.
Message #8 received at 78656 <at> debbugs.gnu.org (full text, mbox):
> Date: Sat, 31 May 2025 22:35:20 -0400
> From: Zach Shaftel via "Bug reports for GNU Emacs,
> the Swiss army knife of text editors" <bug-gnu-emacs <at> gnu.org>
>
> this patch adds left and right sequence reduction functions in C, along
> with tests for them. i don't know if this is the sort of thing the
> maintainers actually would want to merge, but i figured i would just
> submit it and hear your feedback. would also appreciate any stylistic
> feedback, for future patch submissions.
Thanks.
We already have seq-reduce, so fold-left seems to be unneeded? As to
fold-right, couldn't we just add another function to seq.el? Or are
there good reasons to have these implemented in C?
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#78656
; Package
emacs
.
(Sun, 01 Jun 2025 07:17:01 GMT)
Full text and
rfc822 format available.
Message #11 received at 78656 <at> debbugs.gnu.org (full text, mbox):
"Zach Shaftel via \"Bug reports for GNU Emacs, the Swiss army knife of text editors\"" <bug-gnu-emacs <at> gnu.org> writes:
> Tags: patch
>
> this patch adds left and right sequence reduction functions in C, along
> with tests for them. i don't know if this is the sort of thing the
We have cl-reduce, which can be made to behave like fold-right using the
:from-end argument. The old implementation doesn't look particularly
efficient in that case, but is it bad enough to warrant a different API?
In particular, I believe the new function has quadratic complexity when
called on multibyte strings, while cl-reduce has linear complexity.
> maintainers actually would want to merge, but i figured i would just
> submit it and hear your feedback. would also appreciate any stylistic
> feedback, for future patch submissions.
Well, you asked, so a few things I would have done differently:
I think it's a good idea to mention function arguments in order in the
docstring, where doing so doesn't make it totally unreadable. Right
now, we have
+DEFUN ("fold-left", Ffold_left, Sfold_left, 3, 3, 0,
+ doc: /* Reduce SEQUENCE from the left with FUNCTION, starting from
+INIT-VALUE.
+ (Lisp_Object function, Lisp_Object init_value, Lisp_Object sequence)
Ffold_left should CHECK_LIST_END after the FOR_EACH_TAIL loop so it
throws an error when called on a dotted list.
Two entirely stylistic remarks:
+ result = calln (function, result, Faref (sequence, make_fixnum(i)));
I would have preferred "make_fixnum (i)" here, with a space.
+static Lisp_Object
+fold_right_array (Lisp_Object fn, Lisp_Object value, Lisp_Object *elts, EMACS_INT len)
+{
Emacs source code usually puts the length first, then the pointer to the
first element:
static EMACS_INT
mapcar1 (EMACS_INT leni, Lisp_Object *vals, Lisp_Object fn, Lisp_Object seq)
Pip
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#78656
; Package
emacs
.
(Sun, 01 Jun 2025 17:39:02 GMT)
Full text and
rfc822 format available.
Message #14 received at 78656 <at> debbugs.gnu.org (full text, mbox):
Eli Zaretskii <eliz <at> gnu.org> writes:
> We already have seq-reduce, so fold-left seems to be unneeded?
i don't disagree. the intent was to simply have `seq-reduce' provide a
generic wrapper over `fold-left', the way `seq-do' and `seq-map' do for
`mapc' and `mapcar'. but i really only added `fold-left' because i was
already adding `fold-right', and it kinda felt weird to have one without
the other.
> As to fold-right, couldn't we just add another function to seq.el? Or
> are there good reasons to have these implemented in C?
the main reason was for `fold-right' to use a C array to temporarily
hold list elements, instead of needing to `vconcat' or `reverse' the
list first. that's not hugely problematic, and i think an elisp
implementation would also be fine.
more generally, my thinking is that reduction is a core operator in
functional programming, which has become a dominant style in the elisp
ecosystem, so it would be nice to have a speed/space efficient
implementation. i assumed that's why `mapcar' is in C.
but, ultimately i knew this might not be a good fit. i was just curious,
and also wanted to see how well i understood the C internals.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#78656
; Package
emacs
.
(Sun, 01 Jun 2025 23:54:02 GMT)
Full text and
rfc822 format available.
Message #17 received at 78656 <at> debbugs.gnu.org (full text, mbox):
Pip Cet <pipcet <at> protonmail.com> writes:
> We have cl-reduce, which can be made to behave like fold-right using the
> :from-end argument. The old implementation doesn't look particularly
> efficient in that case, but is it bad enough to warrant a different
> API?
not necessarily. i don't particularly like to use the cl seq functions
due to their verbosity, but that's just preference. i would love a
`seq-reduce-right' added to seq.el though.
> In particular, I believe the new function has quadratic complexity when
> called on multibyte strings, while cl-reduce has linear complexity.
yeah i just wrote a generic loop for non-vector arrays, but specialized
implementations could be added for other array types too of course.
> Well, you asked, so a few things I would have done differently:
>
> I think it's a good idea to mention function arguments in order in the
> docstring, where doing so doesn't make it totally unreadable.
that makes sense. i think the documentation as a whole could be
improved.
> Ffold_left should CHECK_LIST_END after the FOR_EACH_TAIL loop so it
> throws an error when called on a dotted list.
i missed that, thanks for the heads up
> Two entirely stylistic remarks:
>
> + result = calln (function, result, Faref (sequence, make_fixnum(i)));
>
> I would have preferred "make_fixnum (i)" here, with a space.
damn, thought i corrected all those :-)
> +static Lisp_Object
> +fold_right_array (Lisp_Object fn, Lisp_Object value, Lisp_Object *elts, EMACS_INT len)
> +{
>
> Emacs source code usually puts the length first, then the pointer to the
> first element:
>
> static EMACS_INT
> mapcar1 (EMACS_INT leni, Lisp_Object *vals, Lisp_Object fn, Lisp_Object seq)
good to know, thank you
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#78656
; Package
emacs
.
(Mon, 02 Jun 2025 05:51:02 GMT)
Full text and
rfc822 format available.
Message #20 received at 78656 <at> debbugs.gnu.org (full text, mbox):
> From: Zach Shaftel <zach <at> shaf.tel>
> Cc: 78656 <at> debbugs.gnu.org
> Date: Sun, 01 Jun 2025 13:38:41 -0400
>
> Eli Zaretskii <eliz <at> gnu.org> writes:
>
> > As to fold-right, couldn't we just add another function to seq.el? Or
> > are there good reasons to have these implemented in C?
>
> the main reason was for `fold-right' to use a C array to temporarily
> hold list elements, instead of needing to `vconcat' or `reverse' the
> list first. that's not hugely problematic, and i think an elisp
> implementation would also be fine.
>
> more generally, my thinking is that reduction is a core operator in
> functional programming, which has become a dominant style in the elisp
> ecosystem, so it would be nice to have a speed/space efficient
> implementation. i assumed that's why `mapcar' is in C.
>
> but, ultimately i knew this might not be a good fit. i was just curious,
> and also wanted to see how well i understood the C internals.
On balance, I'd prefer to have a new function in seq.el rather than
another primitive in C. Since we didn't need this function until now,
it is reasonable to assume it is not going to be a hot spot in any
program, so an implementation in C is not really required.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#78656
; Package
emacs
.
(Mon, 02 Jun 2025 23:08:01 GMT)
Full text and
rfc822 format available.
Message #23 received at 78656 <at> debbugs.gnu.org (full text, mbox):
Eli Zaretskii <eliz <at> gnu.org> writes:
> On balance, I'd prefer to have a new function in seq.el rather than
> another primitive in C. Since we didn't need this function until now,
> it is reasonable to assume it is not going to be a hot spot in any
> program, so an implementation in C is not really required.
Since this would just add an implicit `seq-reverse' call, this doesn't
sound convincing either. `cl-reduce' is able to reduce :from-end. If
at all, then adding a new argument to `seq-reduce' that causes reducing
from the end sounds more sensible to me.
@Zach: I really can feel your desire to have a primitive but part of the
story is also that Emacs Lisp is not that purely functional language
that some of us wish, since it's a lot more iteration oriented than
other Lisps - recursion depth is horribly limited, for example. Trying
to use a purely functional style in Elisp doesn't work well.
So, in Elisp we are having most of these things in seq.el instead of the
core, and I think it's appropriate. Especially folding is an operation
that is not used that often in Elisp.
Michael.
This bug report was last modified 5 days ago.
Previous Next
GNU bug tracking system
Copyright (C) 1999 Darren O. Benham,
1997,2003 nCipher Corporation Ltd,
1994-97 Ian Jackson.