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

Reply via email to