This and other RFCs are available on the web at
  http://dev.perl.org/rfc/

=head1 TITLE

Builtin: partition

=head1 VERSION

  Maintainer: Jeremy Howard <[EMAIL PROTECTED]>
  Date: 11 August 2000
  Version: 1
  Mailing List: [EMAIL PROTECTED]
  Number: 91

=head1 ABSTRACT

It is proposed that a new function, C<partition>, be added to Perl.
C<partition($partition_size, \@list)> would return @list broken into
references to sub-lists, each one $list_size in size.

=head1 DESCRIPTION

In order to work with lists of arbitary size, it is often necessary to
split a list into equal sized sub-lists. A C<partition> function is
proposed that achieves this:

  @list = (1,2,3,4,5,6);
  @partitioned_list = partition(2, \@list);   # ([1,2],[3,4],[5,6])

This is useful to provide tuples to functions that can operate on lists of
lists, for instance:

  @sum_pairs = map {$_->[0] + $_->[1]} @partitioned_list;   # (3,7,11)

If the list to be unzipped is not an exact multiple of the partition size,
the final list reference is not padded. For example:

  @list2 = (1..7);
  @partitioned_list2 = partition(3, @list2);   # ([1,2,3], [4,5,6], [7])

C<zip> (see RFC 90) and C<partition> can work together to allow manipulation
of arbitary sized lists. For instance, we can extend the $sum_xy function
used as an example in the C<zip> RFC, which takes two lists and returns
the sum of them multiplied together component-wise:

  $sum_xy = sub {reduce ^last+^x*^y, zip($_[0], $_[1])};

to a function $sum_mult that does the same with an arbitary number of
lists:

  # Multiply all the elements of a list together, returning the result
  $apply_times = reduce (^total * ^element, @^multiplicands);
  # Swap the rows and columns of a list of lists
  $transpose = partition(
    # Find the size of each column
    scalar @^list_of_lists,
    # Interleave the rows
    zip(@^lists_of_lists);
  )

  # Take a list of references to lists, multiply them component-wise,
  #   and return their sum
  $sum_mult = reduce (
    ^total + $apply_times->( @^next_list ),
    $transpose->(^list_of_lists),
  );

  # Example usage of $sum_mult
  @a = (1,3,5);
  @b = (2,4,6);
  @c = (-1,1,-1);
  $answer = $sum_mult->(\@a, \@b, \@c);   # 1*2*-1+3*4*1+5*6*-1 = -20

=head1 IMPLEMENTATION

The C<partition> functions should be evaluated lazily. Because it is used
in common operations such as the transposition of a matrix, its efficiency
is particularly important.

=head1 REFERENCES

RFC 23: Higher order functions

RFC 76: Builtin: reduce

RFC 90: Builtins: zip() and unzip()

=head1 ACKNOWLEDGEMENTS

Damian Conway: Numerous comments on first draft


Reply via email to