From 58e7ca2718a860ca2fb5692684d6d128a7c1ae75 Mon Sep 17 00:00:00 2001 From: Colin Woodbury Date: Tue, 20 Dec 2022 09:41:51 +0900 Subject: [PATCH 2/4] doc: add new SRFI-171 reducers to the manual --- doc/ref/srfi-modules.texi | 96 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 91 insertions(+), 5 deletions(-) diff --git a/doc/ref/srfi-modules.texi b/doc/ref/srfi-modules.texi index bce5b4eac..6eb1a563e 100644 --- a/doc/ref/srfi-modules.texi +++ b/doc/ref/srfi-modules.texi @@ -5836,7 +5836,7 @@ identity in the reduction. @cindex transducers reducers @deffn {Scheme Procedure} rcons -a simple consing reducer. When called without values, it returns its +A simple consing reducer. When called without values, it returns its identity, @code{'()}. With one value, which will be a list, it reverses the list (using @code{reverse!}). When called with two values, it conses the second value to the first. @@ -5848,7 +5848,7 @@ the second value to the first. @end deffn @deffn {Scheme Procedure} reverse-rcons -same as rcons, but leaves the values in their reversed order. +The same as @code{rcons}, but leaves the values in their reversed order. @example (list-transduce (tmap (lambda (x) (+ x 1))) reverse-rcons (list 0 1 2 3)) @result{} (4 3 2 1) @@ -5856,7 +5856,7 @@ same as rcons, but leaves the values in their reversed order. @end deffn @deffn {Scheme Procedure} rany pred? -The reducer version of any. Returns @code{(reduced (pred? value))} if +The reducer version of @code{any}. Returns @code{(reduced (pred? value))} if any @code{(pred? value)} returns non-#f. The identity is #f. @example @@ -5869,7 +5869,7 @@ any @code{(pred? value)} returns non-#f. The identity is #f. @end deffn @deffn {Scheme Procedure} revery pred? -The reducer version of every. Stops the transduction and returns +The reducer version of @code{every}. Stops the transduction and returns @code{(reduced #f)} if any @code{(pred? value)} returns #f. If every @code{(pred? value)} returns true, it returns the result of the last invocation of @code{(pred? value)}. The identity is #t. @@ -5894,6 +5894,77 @@ transduction. @end example @end deffn +@subheading Guile-specific reducers +These reducers are available in the @code{(srfi srfi-171 gnu)} module, +and are provided outside the standard described by the SRFI-171 +document. + +@deffn {Scheme Procedure} rfold proc seed +The fundamental reducer. @code{rfold} creates an ad-hoc reducer based on +a given 2-argument @var{proc}. A @var{seed} is required as the initial +accumulator value, which also becomes the final return value in the case +where there was no input left in the transduction. + +The first argument to the @var{proc} is the accumulating value, and the +second is the current item of the transduction. + +Note that functions like @code{+} and @code{*} are automatically valid +reducers, because they yield sane values even when given 0 or 1 +arguments. Other functions like @code{max} cannot be used as-is as +reducers since they require at least 2 arguments. For functions like +this, @code{rfold} is appropriate. + +@example +;; Turning built-ins into reducers. Identical to rmax. +(list-transduce (tfilter odd?) (rfold max 0) '(1 2 3 4 5)) +@result{} 5 + +;; Custom lambdas into reducers. Identical to rlast. +(list-transduce (tmap identity) + (rfold (lambda (_ input) input) #f) + '("abc" "def" "ghi")) +@result{} "ghi" + +;; Track the 3 largest values in a transduction. +(define (three-largest acc input) + (take (sort (cons input acc) >) 3)) + +(list-transduce (tfilter odd?) + (rfold three-largest '(0 0 0)) + '(7 1 4 2 13 5 9 2 8)) +@result{} (13 9 7) +@end example +@end deffn + +@deffn {Scheme Procedure} rfind pred? +Find the first element in the transduction that satisfies a given +predicate. Yields #f if no such element was found. + +@example +(list-transduce (tmap identity) + (rfind string?) + '(1 c #t 4.12 "Jack" ())) +@result{} "Jack" +@end example +@end deffn + +@deffn {Scheme Procedure} rfirst seed +@deffnx {Scheme Procedure} rlast seed +Yield the first (or last) value of the transduction, or the @var{seed} +value if there is none. +@end deffn + +@deffn {Scheme Procedure} rfor-each proc +Apply @var{proc} for its side-effects to every value of the +transduction, ignoring all results. Like its @ref{SRFI-1} cousin, yields +@code{*unspecified*}. +@end deffn + +@deffn {Scheme Procedure} rmax seed +@deffnx {Scheme Procedure} rmin seed +Yield the maximum (or minimum) value of the transduction, or the +@var{seed} value if there is none. +@end deffn @node SRFI-171 Transducers @subsubsection Transducers @@ -6057,7 +6128,7 @@ Stateless. @subheading Guile-specific transducers These transducers are available in the @code{(srfi srfi-171 gnu)} -library, and are provided outside the standard described by the SRFI-171 +module, and are provided outside the standard described by the SRFI-171 document. @deffn {Scheme Procedure} tbatch reducer @@ -6085,6 +6156,21 @@ value)}, saving it's result between iterations. @end example @end deffn +@deffn {Scheme Procedure} twindow n + +Returns a transducer that yields @var{n}-length windows of overlapping +values. This is different from @code{tsegment} which yields +non-overlapping windows. If there were fewer items in the input than +@var{n}, then this yields nothing. + +@example +(list-transduce (twindow 3) rcons '(1 2 3 4 5)) +@result{} ((1 2 3) (2 3 4) (3 4 5)) +@end example + +Stateful. +@end deffn + @node SRFI-171 Helpers @subsubsection Helper functions for writing transducers -- 2.39.0