Skip to content

Commit d5e7386

Browse files
committed
gather/take user-vs-library considerations
Incorporate feedback from awwaiid++, PerlJam++, sorear++.
1 parent b4e7bc1 commit d5e7386

File tree

1 file changed

+22
-6
lines changed

1 file changed

+22
-6
lines changed

S04-control.pod

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -700,14 +700,30 @@ X<gather>X<take>
700700
A variant of C<do> is C<gather>. Like C<do>, it is followed by a statement
701701
or block, and executes it once. Unlike C<do>, it evaluates the statement or
702702
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
704704
the C<gather>. The C<take> function's signature is like that of C<return>;
705705
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.)]
711727

712728
If you take multiple items in a comma list (since it is, after all, a list
713729
operator), they will be wrapped up in a C<Parcel> object for return as the

0 commit comments

Comments
 (0)