Author: lwall
Date: 2010-02-17 02:01:45 +0100 (Wed, 17 Feb 2010)
New Revision: 29760

Modified:
   docs/Perl6/Spec/S04-control.pod
Log:
[S04] bring gather/take description more in line with modern realities


Modified: docs/Perl6/Spec/S04-control.pod
===================================================================
--- docs/Perl6/Spec/S04-control.pod     2010-02-16 23:43:09 UTC (rev 29759)
+++ docs/Perl6/Spec/S04-control.pod     2010-02-17 01:01:45 UTC (rev 29760)
@@ -13,8 +13,8 @@
 
     Created: 19 Aug 2004
 
-    Last Modified: 17 Dec 2009
-    Version: 93
+    Last Modified: 16 Feb 2010
+    Version: 94
 
 This document summarizes Apocalypse 4, which covers the block and
 statement syntax of Perl.
@@ -683,28 +683,40 @@
 =head2 The C<gather> statement prefix
 X<gather>X<take>
 
-A variant of C<do> is C<gather>.  Like C<do>, it is followed by a
-statement or block, and executes it once.  Unlike C<do>, it evaluates
-the statement or block in sink (void) context; its return value is instead
-specified by calling the C<take> list prefix operator one or more times
-within the dynamic scope of the C<gather>.  The C<take> function's
-signature is like that of C<return>; it merely wraps up a C<Parcel>
-of its arguments without imposing any additional constraints (in the
-absence of context propagation by the optimizer).  The value returned
-by the C<take> to its own context is that same C<Parcel> object (which
-is ignored when the C<take> is in sink context).  Regardless of the
-C<take>'s context, the C<Parcel> object is also added to the list of
-values being gathered, which is returned by the C<gather> in the form
-of a lazy list of C<Parcel>s, with each element corresponding to one C<take>
-parcel.  (A C<Parcel>s is normally flattened when bound into slurpy context,
-but when bound into a slice context, the C<Parcel> objects become real
-sublists.  The eventual binding context thus determines whether to
-throw away or keep the groupings resulting from each individual C<take> call.)
+A variant of C<do> is C<gather>.  Like C<do>, it is followed by a statement
+or block, and executes it once.  Unlike C<do>, it evaluates the statement or
+block in sink (void) context; its return value is instead specified by calling
+the C<take> list prefix operator one or more times within the dynamic scope of
+the C<gather>.  The C<take> function's signature is like that of C<return>;
+while having the syntax of a list operator, it merely returns a single item
+which if, if you return multiple items in a comma list, be wrapped up in a
+C<Parcel> object.  No additional constraints are enforce by context, since
+all context is lazy in Perl 6.  The flattening or non-flattening of any such
+returned C<Parcel> will be dependent on how the gather's return iterator is
+iterated (with .get vs .getarg).
 
+The value returned by the C<take> to the C<take>'s own context is
+that same returned object (which is ignored when the C<take> is in
+sink context).  Regardless of the C<take>'s immediate context, the
+object returned is also added to the list of values being gathered,
+which is returned by the C<gather> in the form of a lazy list (that
+is, an iterator, really), with each element of that list corresponding
+to one C<take> object (either a C<Parcel> or any other single object
+serving as a degenerate parcel).
+
+Any C<Parcel>s in the returned list are normally flattened when bound
+into slurpy context.  When bound into a slice context, however,
+the C<Parcel> objects become real C<Seq> objects that keep their
+identity as discrete sublists.  The eventual binding context thus
+determines whether to throw away or keep the groupings resulting from
+each individual C<take> call.  Since most list contexts are flat
+rather than sliced, the boundaries between individual C<take>
+calls usually disappear.
+
 Because C<gather> evaluates its block or statement in sink context,
 this typically causes the C<take> function to be evaluated in sink
 context.  However, a C<take> function that is not in sink context
-gathers its arguments I<en passant> and also returns them unchanged.
+gathers its return objects I<en passant> and also returns them unchanged.
 This makes it easy to keep track of what you last "took":
 
     my @uniq = gather for @list {
@@ -720,24 +732,24 @@
 
     my @y;
     @x = gather for 1..2 {          # flat context for list of parcels
-        my $x = take $_, $_ * 10;   # item context for individual parcel
-        push @y, $x;
+        my ($y) := take $_, $_ * 10;  # item context promotes parcel to seq
+        push @y, $y;
     }
-    # @x contains 4 Ints:  1,10,2,20
-    # @y contains 2 Parcels: (1,10),(2,20)
+    # @x contains 4 Ints:  1,10,2,20 flattened by list assignment to @x
+    # @y contains 2 Seqs: Seq(1,10),Seq(2,20) sliced by binding to positional 
$y
 
-Likewise, we can just remember the gather's result by binding and
-later coerce it:
+Likewise, we can just remember the gather's result parcel by binding and
+later coercing it:
 
-    $c := gather for 1..2 {
+    my |$c := gather for 1..2 {
         take $_, $_ * 10;
     }
     # $c.flat produces 1,10,2,20 -- flatten fully into a list of Ints.
-    # $c.slice produces (1,10),(2,20) -- list of Parcels, a 2-D list.
-    # $c.item produces ((1,10),(2,20)) -- the saved Parcel itself as one item 
in item context.
+    # $c.slice produces Seq(1,10),Seq(2,20) -- list of Seqs, a 2-D list.
+    # $c.item produces Seq((1,10),(2,20)) -- coerced to Seq of unresolved 
Parcels
 
 Note that the C<take> itself is in sink context in this example because
-the C<for> loop is in sink context.
+the C<for> loop is in the sink context provided inside the gather.
 
 A C<gather> is not considered a loop, but it is easy to combine with a loop
 statement as in the examples above.

Reply via email to