@@ -700,14 +700,30 @@ X<gather>X<take>
700
700
A variant of C<do> is C<gather>. Like C<do>, it is followed by a statement
701
701
or block, and executes it once. Unlike C<do>, it evaluates the statement or
702
702
block in sink (void) context; its return value is instead specified by calling
703
- the C<take> list prefix operator one or more times within the dynamic scope of
703
+ the C<take> list prefix operator one or more times within the scope (either lexical or dynamic) of
704
704
the C<gather>. The C<take> function's signature is like that of C<return>;
705
705
while having the syntax of a list operator, it merely returns a single item
706
- or "argument" (see L<S02> for definition). The C<take> function is lexotic
707
- if there is a visible outer C<gather>, but falls back to purely dynamic if not.
708
- (Use of the dynamic semantics cannot be guaranteed to be portable when passing
709
- closures into some other construct, either built-in or not, since implementations
710
- of libraries and of Perl itself may use C<gather>/C<take> internally.)
706
+ or "argument" (see L<S02> for definition).
707
+
708
+ The C<take> function is lexotic if there is a visible outer C<gather>,
709
+ but falls back to purely dynamic if not. Well, it doesn't really
710
+ fall back, since a C<take> knows at compile time whether it is being
711
+ used lexically or dynamically. Less obviously, so does a C<gather>;
712
+ if a C<gather> lexically contains any C<take> calls, it is marked as
713
+ lexotic-only, and it will be invisible to a dynamic C<take>. If the
714
+ C<gather> contains no C<take> lexically, it by definition cannot be
715
+ the lexotic target of any C<take>, so it can only harvest dynamic
716
+ C<take> calls. The only remaining difficulty arises if both the user
717
+ and a library writer attempt to use dynamic gather with user-defined
718
+ callbacks that contain C<take>. So we will say that it is erroneous
719
+ for a library writer to mix dynamic gather with callbacks unless
720
+ those callbacks are somehow "ungathered" to the outer dynamic scope.
721
+ [Conjecture: there should either be an C<callergather> primitive that
722
+ does this, or it should be added to the job description of C<lift>.
723
+ A third option is to allow labeled C<gather>/C<take> for such a situation,
724
+ and dynamic C<take> must match the C<gather>'s label (or lack thereof) exactly.
725
+ (Using the term "label" loosely, to include other solutions besides the label syntax,
726
+ such as .gather and .take methods on some identity object.)]
711
727
712
728
If you take multiple items in a comma list (since it is, after all, a list
713
729
operator), they will be wrapped up in a C<Parcel> object for return as the
0 commit comments