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 August 2000
  Last Modified: 20 Sep 2000
  Mailing List: [EMAIL PROTECTED]
  Number: 76
  Version: 3
  Status: Frozen
  Frozen since: v2

=head1 ABSTRACT

This RFC proposes a built-in C<reduce> function, modelled after Graham
Barr's C<reduce> subroutine from the List::Utils module (a.k.a. The
Module Formerly Known As builtin.pm).

=head1 DESCRIPTION

A new built-in -- 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. All calls to the reduction subroutine are
made in a scalar context.

If fewer than N-1 elements would be available for the final reduction
call, a exception is thrown. Note that this exception could be thrown
I<before> the reduction begins, by determining the total number of elements
to be reduced (I<R>) and the number of elements to be processed on each
reduction step (I<r>) and testing whether the resulting number of steps --
(I<R>-I<r>)/(I<r>-1) -- is integral.

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.


=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 ? 0 : ^x<^y ? ^x : ^y,  @numbers


Collection:

        @triples = @{ reduce sub($;$$$){ [@{shift},[@_]] }, [], @singles };


Separation:

        $sorted = reduce { push @{$_[0][$_[1]%2]}, $_[1]; $_[0] }
                         [[],[]],
                         @numbers;

        # or, more cleanly:

        $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 List::Util, I'd imagine.


=head1 REFERENCES

The List::Util module

RFC 23: Higher order functions

RFC 128: Subroutines: Extend subroutine contexts to include
                      named parameters and lazy arguments

RFC 199: Short-circuiting built-in functions and user-defined subroutines

Reply via email to