Author: larry Date: Mon Jan 29 14:06:49 2007 New Revision: 13545 Modified: doc/trunk/design/syn/S04.pod
Log: Clarifications requested by gaal++. Modified: doc/trunk/design/syn/S04.pod ============================================================================== --- doc/trunk/design/syn/S04.pod (original) +++ doc/trunk/design/syn/S04.pod Mon Jan 29 14:06:49 2007 @@ -438,12 +438,19 @@ =head2 The gather statement 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 void context; its return -value is instead specified by calling the C<take> function one or more times -within the dynamic scope of the C<gather>. The returned values are in the -form of a lazy multislice, with each slice corresponding to one -C<take> capture. (A multislice is lazily flattened in normal list context, +statement or block, and executes it once. Unlike C<do>, it evaluates +the statement or block in 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 captures the C<Capture> +of its argments without imposing any additional constraints (in the +absense of context propagation by the optimizer). The value returned +by the C<take> to its own context is that same C<Capture> object (which +is ignored when the C<take> is in void context). Regardless of the +C<take>'s context, the C<Capture> object is also added to the list of +values being gathered, which is returned by the C<gather> in the form +of a lazy multislice, with each slice corresponding to one C<take> +capture. (A multislice is lazily flattened in normal list context, but you may "unflatten" it again with a C<@@()> contextualizer.) Because C<gather> evaluates its block or statement in void context, @@ -458,8 +465,34 @@ $previous = take $_; } +The C<take> function essentially has two contexts simultaneously, the +context in which the gather is operating, and the context in which the +C<take> is operating. These need not be identical contexts, since they +may bind or coerce the resulting captures differently: + + my @y; + @x = gather for 1..2 { # @() context for list of captures + my $x = take $_, $_ * 10; # $() context for individual capture + push @y, $x; + } + # @x returns 1,10,2,20 + # @y returns [1,10],[2,20] + +Likewise, we can just remember the gather's result by binding and +later coerce it: + + $c := gather for 1..2 { + take $_, $_ * 10; + } + # @$c returns 1,10,2,20 + # @@$c returns [1,10],[2,20] + # $$c returns [[1,10],[2,20]] + +Note that the C<take> itself is in void context in this example because +the C<for> loop is in void context. + A C<gather> is not considered a loop, but it is easy to combine with a loop -as in the example above. +statement as in the examples above. =head2 Other C<do>-like forms