More of:
authorKevin Ryde <user42@zip.com.au>
Mon, 28 Feb 2005 00:33:40 +0000 (00:33 +0000)
committerKevin Ryde <user42@zip.com.au>
Mon, 28 Feb 2005 00:33:40 +0000 (00:33 +0000)
(SRFI-1 Fold and Map): Rewrite fold, pair-fold and reduce for clarity.

doc/ref/srfi-modules.texi

index f3d59e8..c02840a 100644 (file)
@@ -522,9 +522,9 @@ elements from a list,
 @end example
 
 Clearly the same sort of thing can be done with a @code{for-each} and
-a variable in which build the result, but a self-contained @var{proc}
-can be re-used in multiple contexts, where a @code{for-each} would
-have to be written out each time.
+a variable in which to build the result, but a self-contained
+@var{proc} can be re-used in multiple contexts, where a
+@code{for-each} would have to be written out each time.
 @end deffn
 
 @deffn {Scheme Procedure} pair-fold proc init lst1 @dots{} lstN
@@ -533,68 +533,47 @@ The same as @code{fold} and @code{fold-right}, but apply @var{proc} to
 the pairs of the lists instead of the list elements.
 @end deffn
 
-@deffn {Scheme Procedure} reduce proc identity lst
-@deffnx {Scheme Procedure} reduce-right proc identity lst
-@code{reduce} is a variant of @code{fold} (see above), designed for
-cases where the initial value is an ``identity'', so that @var{proc}
-can start directly from the first element of @var{lst}.
+@deffn {Scheme Procedure} reduce proc default lst
+@deffnx {Scheme Procedure} reduce-right proc default lst
+@code{reduce} is a variant of @code{fold}, where the first call to
+@var{proc} is on two elements from @var{lst}, rather than one element
+and a given initial value.
 
-Consider folding with @code{+} and initial value 0, calls would be for
-instance
+If @var{lst} is empty, @code{reduce} returns @var{default} (this is
+the only use for @var{default}).  If @var{lst} has just one element
+then that's the return value.  Otherwise @var{proc} is called on the
+elements of @var{lst}.
 
-@example
-(fold + 0 '(4 5 6))
-@result{}
-(+ 4 0)
-(+ 5 4)
-(+ 6 9)
-@end example
+Each @var{proc} call is @code{(@var{proc} @var{elem} @var{previous})},
+where @var{elem} is from @var{lst} (the second and subsequent elements
+of @var{lst}), and @var{previous} is the return from the previous call
+to @var{proc}.  The first element of @var{lst} is the @var{previous}
+for the first call to @var{proc}.
 
-The first call @code{(+ 4 0)} is unnecessary, adding 0 to 4 doesn't
-change that value.  The first element @code{4} may as well be the
-initial ``previous'' value argument to @var{proc}.  This is what
-@code{reduce} does.
+For example, the following adds a list of numbers, the calls made to
+@code{+} are shown.  (Of course @code{+} accepts multiple arguments
+and can add a list directly, with @code{apply}.)
 
 @example
-(reduce + 0 '(4 5 6))
-@result{}
-(+ 5 4)
-(+ 6 9)
+(reduce + 0 '(5 6 7)) @result{} 18
+
+(+ 6 5)  @result{} 11
+(+ 7 11) @result{} 18
 @end example
 
-The @var{identity} parameter is the return when @var{lst} is empty,
-that's the only time @var{identity} is used.  If @var{lst} has just
-one element, that's the return with no calls to @var{proc}.
+@code{reduce} can be used instead of @code{fold} where the @var{init}
+value is an ``identity'', meaning a value which under @var{proc}
+doesn't change the result, in this case 0 is an identity since
+@code{(+ 5 0)} is just 5.  @code{reduce} avoids that unnecessary call.
 
 @code{reduce-right} is a similar variation on @code{fold-right},
-working from the end (ie.@: the right) of @var{lst}.  Calls in this
-case become
-
-@example
-(reduce-right + 0 '(4 5 6))
-@result{}
-(+ 5 6)
-(+ 4 11)
-@end example
+working from the end (ie.@: the right) of @var{lst}.  The last element
+of @var{lst} is the @var{previous} for the first call to @var{proc},
+and the @var{elem} values go from the second last.
 
 @code{reduce} should be preferred over @code{reduce-right} if the
 order of processing doesn't matter, or can be arranged either way,
 since @code{reduce} is a little more efficient.
-
-In the above examples of course @code{+} takes any number of
-arguments, so it can be used on a list just with @code{apply}.  An
-example where that's not the case would be SRFI-19 @code{add-duration}
-(@pxref{SRFI-19 Time}) on a list of durations,
-
-@example
-(use-modules (srfi srfi-19))
-(reduce add-duration
-        (make-time time-duration 0 0)
-        (list (make-time time-duration 0 4)
-              (make-time time-duration 0 5)
-              (make-time time-duration 0 6)))
-@result{} #<time duration 15 seconds>
-@end example
 @end deffn
 
 @deffn {Scheme Procedure} unfold p f g seed [tail-gen]