Author: larry Date: Sat May 13 09:07:03 2006 New Revision: 9237 Modified: doc/trunk/design/syn/S09.pod
Log: Clarifications on multidimensional notations. Modified: doc/trunk/design/syn/S09.pod ============================================================================== --- doc/trunk/design/syn/S09.pod (original) +++ doc/trunk/design/syn/S09.pod Sat May 13 09:07:03 2006 @@ -12,9 +12,9 @@ Maintainer: Larry Wall <[EMAIL PROTECTED]> Date: 13 Sep 2004 - Last Modified: 11 May 2006 + Last Modified: 13 May 2006 Number: 9 - Version: 10 + Version: 11 =head1 Overview @@ -26,8 +26,8 @@ =head1 Lazy lists All list contexts are lazy by default. They still flatten eventually, -but only when forced to. You have to use unary C<**> to get a non-lazy -flattening list context (that is, to flatten immediately like Perl 5). +but only when forced to. You have to use the C<eager> list operator to get a +non-lazy flattening list context (that is, to flatten immediately like Perl 5). =head1 Sized types @@ -136,18 +136,20 @@ @pieces = $buffer[$n..^$end]; Note that subscripting still pulls the elements out as numbers, -but C<substr()> returns the same buffer type. +but C<substr()> returns a buffer of the same type. =head1 Multidimensional arrays The declarations above declare one-dimensional arrays of indeterminate -length. Such arrays are autoextending just like ordinary Perl -arrays (at the price of occasionally copying the block of data to -another memory location). For many purposes, though, it's useful to -define array types of a particular size and shape that, instead of -autoextending, throw an exception if you try to access outside their -declared dimensionality. Such arrays tend to be faster to allocate and -access as well. +length. Such arrays are autoextending just like ordinary Perl arrays +(at the price of occasionally copying the block of data to another +memory location, or using a tree structure). For many purposes, +though, it's useful to define array types of a particular size and +shape that, instead of autoextending, throw an exception if you try +to access outside their declared dimensionality. Such arrays tend +to be faster to allocate and access as well. (The language must, +however, continue to protect you against overflow--these days, that's +not just a reliability issue, but also a security issue.) A multidimensional array is indexed by a semicolon list, which is really a list of pipes in disguise. Each sublist is a slice/pipe of one particular @@ -202,7 +204,7 @@ Conjecture, since @@x and @x are really the same object, any array can keep track of its dimensionality, and it only matters how you use it -in the end: +in contexts that care about the dimensionality: my @x; @x <== %hash.keys.grep: {/^X/}; @@ -214,7 +216,7 @@ [EMAIL PROTECTED] # flattened To declare a multidimensional array, you may declare it with a signature as -if it were a function returning one of its entries: +if it were a function returning I<one> of its entries: my num @nums (Int); # one dimension, @nums[Int] @@ -235,10 +237,11 @@ my int @ints (1..4, 1..2); # two dimensions, @ints[1..4; 1..2] -Note that this only influences your view of the array, not the actual -shape of the array. If you pass this array to another module, it -will see it as have a shape of C<(0..3, 0..1)> unless it also declares -a variable to view it differently. +Note that this only influences your view of the array in the current +lexical scope, not the actual shape of the array. If you pass +this array to another module, it will see it as having a shape +of C<(0..3,0..1)> unless it also declares a variable to view it +differently. Alternately, you may declare it using a prototype subscript, but then you must remember to use semicolons instead of commas to @@ -253,6 +256,7 @@ You can pass a multislice for the shape as well: + @@fooshape = (0..3; 0..1); my int @ints[[;[EMAIL PROTECTED]; my int @ints[@@fooshape]; # same thing @@ -290,6 +294,17 @@ (presuming C<Even> and C<Odd> are types already constrained to be even or odd). +The C<Whatever> type will be taken to mean C<Int> within an array +subscript, so you can also write: + + my int @ints[^42; *]; + +Saying + + my int @ints[^42; **]; + +would give you an array of indeterminate dimensionality. + =head1 PDL support An array C<@array> can be tied to a PDL at declaration time: @@ -385,7 +400,9 @@ But you should maybe write the last form anyway just for good documentation, unless you don't actually know how many more dimensions -there are. +there are. For that case you may use C<**>: + + @nums[0,1,2;**] If you wanted that C<0..2> range to mean @@ -440,7 +457,7 @@ 0 .. Inf :by(2) -That's why we have postfix C<..*> to mean C<..Inf>. +That's why we have C<..*> to mean C<..Inf>. =head1 PDL signatures @@ -647,7 +664,10 @@ do -> @wild { @b[[;] reverse @wild] = @a[[;] @wild]; }; produces an array with the dimensions reversed regardless of the -dimensionality of C<@a>. +dimensionality of C<@a>. Since the multidimensional C<@@wild> notation +is more or less equivalent to C<[;[EMAIL PROTECTED]>, you can also write that as: + + do -> @@wild { @b[reverse @@wild] = @a[[;] @@wild]; }; The optimizer is, of course, free to optimize away any implicit loops that it can figure out how to do more efficiently without changing @@ -670,10 +690,15 @@ just a string, say something like: my %hash{Any}; + my %hash{*}; + +A hash of indeterminate dimensionality is: + + my %hash{**}; -Likewise, you can limit the keys to objects of particular types: +As with arrays, you can limit the keys to objects of particular types: - my Fight %hash{Dog;Cat}; + my Fight %hash{Dog; Cat where {!.scared}}; The standard Hash is just