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

[email protected] (Perl6 RFC Librarian)
Newsgroups perl.perl6.language,perl.perl6.announce
Message-ID <[email protected]>
This and other RFCs are available on the web at
  http://dev.perl.org/rfc/

=head1 TITLE

Builtins: zip() and unzip()

=head1 VERSION

  Maintainer: Jeremy Howard <[email protected]>
  Date: 11 August 2000
  Version: 1
  Mailing List: [email protected]
  Number: 90

=head1 ABSTRACT

It is proposed that two new functions, C<zip>, and C<unzip>, be added to
Perl. C<zip(\@list1, \@list2, ...)> would return a list that interleaved
its arguments. C<unzip($list_size, \@list)> would reverse this operation.

=head1 DESCRIPTION

Miranda, the upcoming Python v2.0, and numerous functional languages use
a function called C<zip> to interleave the arguments of arrays together.
It is proposed that Perl implement this function, and evaluate it lazily.
For instance:

  @a = (1,3,5);
  @b = (2,4,6);
  @zipped_list = zip(\@a,\@b);   # (1,2,3,4,5,6)

This makes it easy to operate on multiple lists using flexible reduction
functions:

  $sum_xy = sub {reduce ^last+^x*^y, zip($_[0], $_[1])};
  print $sum_xy->(\@a, \@b);   # Prints '44', i.e. 1*2+3*4+5*6

In order to reverse this operation we need an C<unzip> function:

  @zipped_list = zip(\@a,\@b);   # (1,2,3,4,5,6)
  @unzipped_list = unzip(3, \@zipped_list);   # ([1,3,5], [2,4,6])

If the list to be unzipped is not an exact multiple of the partition size,
the final list references are not padded--their length is one less than
the list size. For example:

  @list = (1..7);
  @unzipped_list2 = unzip(3, \@list);   # ([1,4,7], [2,5], [3,6])
  
=head1 IMPLEMENTATION

The C<zip> and C<unzip> functions should be evaluated lazily.

Effectively, C<zip> creates an iterator over multiple lists. If used as
part of a reduction, the actual interleaved list need never be created.
For instance:

  $sum_xy = sub {reduce ^last+^x*^y, zip($_[0], $_[1])};
  $answer = $sum_xy->(\@a, \@b);
  
should be evaluated as if it read:

  $answer = 0;
  $answer += $a[$_] * $b[$_] for (0..$#a-1));
  
which does not need to create an intermediate list.

=head1 REFERENCES

RFC 23: Higher order functions

RFC 76: Builtin: reduce
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.