RFC 205 (v1) Arrays: New operator ';' for creating array slices

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

=head1 TITLE

Arrays: New operator ';' for creating array slices

=head1 VERSION

  Maintainer: Jeremy Howard <[email protected]>
  Date: 8 September 2000
  Mailing List: [email protected]
  Number: 205
  Version: 1
  Status: Developing

=head1 ABSTRACT

RFC 204 described and extension of standard list indexing which allows
indexing directly into a multidimensional array by using a list of lists
of coordinates. This RFC describes a new operator C<;> that can create
lists of coordinates corresponding to slices and blocks of
multidimensional arrays. The C<;> operator creates the cartesian product
of its operands as a list of lists. It can only operate within a list
constructor.

=head1 DESCRIPTION

It is proposed that a new operator C<;> be introduced that operates within
a list constructor to create the cartesian product of its operands:

  @lol = ( (1,2) ; (3,4) );   # ([1,3], [1,4], [2,3], [2,4])

The order of the resultant list is to generate pairs by iterating through
the right-hand operand for each element of the left-hand operand in turn,
going from left to right.

If an operand is a list of lists, the C<;> operator creates the cartesian
product of the component lists:

  @lol = ( ([1,3],[1,4]);(5,6) ) # ([1,3,5], [1,3,6], [1,4,5], [1,4,6])

which is equivalent to:

  @lol = ( (1 ; (1,4)); (5,6) ) # ([1,3,5], [1,3,6], [1,4,5], [1,4,6])
  
which, because C<;> is associative, is equivalent to:

  @lol = ( 1 ; (1,4); (5,6) ) # ([1,3,5], [1,3,6], [1,4,5], [1,4,6])

and, because C<;> evaluates its arguments in a list context, and has a
higher precendence than C<,>, it equivalent to:

  @lol = ( 1 ; 1,4 ; 5,6 ) # ([1,3,5], [1,3,6], [1,4,5], [1,4,6])

C<;> is particularly useful for creating slices of multidimensional
arrays:

  my int @array = ([1,2,3],
                   [4,5,6],
                   [7,8,9]);
  @col2 = @array[0..2; 1];   # @array[[0,1],[1,1],[2,1]] == (2,5,8)
  
Large matrices can be flexibly manipulated using infinite lists (from RFC
24) and list generation functions (from RFC 81):

  my int @matrix = get_big_file();
  my @first_5_odd_cols = ( 0.. ; 1..9:2 ); # ([0,1],[0,3],[0,5],...)
  my @matrix_slice = @matrix[@first_5_odd_cols];

@matrix_slice now contains the whole of columns 1,3,5,7,9 of @matrix.
Furthermore, @first_5_odd_cols can be used to slice another matrix later,
which may be of a different size.

Because this whole-dimension slicing is so common, any argument to C<;>
may be omitted. Omitted operands default to (0..):

  ( ;1..9:2 ) == ( 0.. ; 1..9:2 );

Furthermore, in order to create generic slices that return 'all the nth
elements' regardless of the number of dimensions of the array, the
left-most or right-most operand to C<;> may be '*', which expands to (0..)
for every missing dimension of the sliced array:

  my int @b :bounds(1,1,1) = get_some_matrix();
  my @first_elems = @b[0;*];   # @b[[0,0,0],[0,0,1],[0,1,0],[0,1,1]]

The '*' operand may only be used in an array slicing context.

=head1 IMPLEMENTATION

Lazy, naturally.

=head1 REFERENCES

RFC 202: Overview of multidimensional array RFCs

RFC 81: Lazily evaluated list generation functions

RFC 24: Semi-finite (lazy) lists

=head1 ACKNOWLEDGEMENTS

Buddha Buck: Original suggestion of C<;> for multidimensional array access
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.