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