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
 

Reply via email to