This and other RFCs are available on the web at
http://dev.perl.org/rfc/
=head1 TITLE
Builtin: reduce
=head1 VERSION
Maintainer: Damian Conway <[EMAIL PROTECTED]>
Date: 10 Aug 2000
Last Modified: 19 Sep 2000
Mailing List: [EMAIL PROTECTED]
Number: 76
Version: 2
Status: Frozen
=head1 ABSTRACT
This RFC proposes a builtin C<reduce> function, modelled after Graham Barr's
C<reduce> subroutine from builtin.pm
=head1 DESCRIPTION
A new builtin -- C<reduce> -- is proposed.
This function would take an block, subroutine reference, or curried function
(hereafter referred to as I<the reduction subroutine>),
and call it repeatedly to reduce the remaining arguments
(hereafter, referred to as C<the list>).
If the reduction subroutine has a prototype, that prototype
determines how many items are reduced at a time. If the reduction subroutine
is a block or has no prototype, two items are reduced each time.
The first call to the reduction subroutine will be passed the first N
elements of the list, and subsequent calls will be passed the result of
the previous call and the next N-1 elements in the list, until no more
elements remain in the list. If fewer than N-1 elements remain on the
final call, all the remaining elements are passed. All calls to the
reduction subroutine are made in a scalar context.
In all cases, the elements of the list are lazily evaluated. That is,
any element of the list that is not a literal value is only evaluated
when that element is passed to (and actually used by) the reduction
subroutine.
If the original list has no elements, C<reduce> immediately throws an
exception. If the original list has a single element, that element is
immediately returned (without ever calling the reduction subroutine).
Otherwise, in a scalar context, the result of the final reduction call
is the result returned by C<reduce>. In a list context, a list of all
the interim values, plus the final value, would be returned.
If the reduction subroutine is ever terminated by a call to C<last>, the
enclosing C<reduce> immediately returns the last reduction value -- or
list of partial values -- to that point. If the C<last> occurs during
the first reduction, an exception is thrown.
=head1 EXAMPLES
Summation:
$sum = reduce {$_[0]+$_[1]} 0, @numbers;
$sum = reduce sub{$_[0]+$_[1]}, 0, @numbers;
$sum = reduce ^_+^_, 0, @numbers;
Note that the first element of the list -- zero in this case, 1 in the next
example -- represents the default value if the list is empty.
Production:
$prod = reduce {$_[0]*$_[1]} 1, @numbers;
$prod = reduce sub{$_[0]*$_[1]}, 1, @numbers;
$prod = reduce ^_*^_, 1, @numbers;
Minimization:
$min = reduce ^x <= ^y ? ^x : ^y, @numbers
$min = reduce ^x le ^y ? ^x : ^y, @strings
Minimization to zero:
$min = reduce any(^x,^y)<0 && last || ^x<^y && ^x || ^y, @numbers
Collection:
@triples = @{ reduce sub($;$$$){ [@{shift},[@_] }, [], @singles };
Separation:
$sorted = reduce { push @{$_[0][$_[1]%2]}, $_[1]; $_[0] }
[[],[]],
@numbers;
Accumulative sequence generation:
@increase = reduce ^value + ^delta, $original, @bonuses;
@growth = reduce ^value * ^rate, $principal, @annual_interest_rates;
=head1 IMPLEMENTATION
Extend Graham's builtin, I'd imagine.
=head1 REFERENCES
builtin.pm
RFC: Higher Order Functions