<Moved to perl6-language-data from PDL Porters>

[EMAIL PROTECTED] wrote:
> Jeremy Howard wrote:
>
> > <quote>
> > 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];
> > </quote>
>
> Nice quote. One itch remains for me: the need for the parentheses should
> be done away with:
>
>   @arr[0..2; 1]
>
> Should be fine if ';' implies list context for its args and since it
> also is associative. Remember, we wan't to save extra key strokes ;)
>
I agree. I had planned to put this in the RFC but I got distracted by
wondering under exactly what conditions the () are required to remove
ambiguity. I never got around to answering this question and then forgot to
mention it in the RFC at all! I'll add it in now. Can anyone think of
situations in which the () would be required?

BTW, it occurs to me that:

  @matrix[ 0.. ; 1..9:2 ]

will be very hard to implement. The cartesian product expands to
([0,1],[0,3],[0,5],...). It will require some cleverness to recognise that
the domain of the relevent indices is from non-contiguous parts of the list,
with an infinite number of indices between each part. I haven't done an
implementation section for this RFC yet, so any suggestions about how
infinite lists with the ';' operator might work would be much appreciated.

Here's the current draft of the RFC (we should be cleaning it up and
submitting it in the next couple of days):

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

=head1 TITLE

New operator ';' for creating array slices

=head1 VERSION

  Maintainer: Jeremy Howard <[EMAIL PROTECTED]>
  Created: 3 September 2000
  Status: Developing
  Last modified: 3 September 2000
  Version: 1
  Mailing List: [EMAIL PROTECTED]
  Number: ?

=head1 ABSTRACT

<RFCC> 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])

The same logic applies if both operands are lists of lists.

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
of 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

<RFCA>

RFC 81: Lazily evaluated list generation functions

RFC 24: Semi-finite (lazy) lists


Reply via email to