RFC 199 (v2) Short-circuiting C<grep>, C<map>, and C<reduce> with C<last>

[email protected] (Perl6 RFC Librarian)
Newsgroups perl.perl6.language,perl.perl6.announce
Message-ID <[email protected]>
(or "Allowing built-in functions to use loop blocks")
Reply-To: [email protected]

This and other RFCs are available on the web at
  http://dev.perl.org/rfc/

=head1 TITLE

Short-circuiting C<grep>, C<map>, and C<reduce> with C<last>
(or "Allowing built-in functions to use loop blocks")

=head1 VERSION

  Maintainer: Garrett Goebel <[email protected]>
  Date: 6 Sep 2000
  Last Modified: 7 Sep 2000
  Mailing List: [email protected]
  Number: 199
  Version: 2
  Status: Developing

=head1 ABSTRACT

Allow built-in functions like C<grep>, C<map>, and C<reduce> which take
blocks as a parameter to be short-circuited with C<last>

=head1 DESCRIPTION

It'd be nice if one could use C<grep> to find out if a value is
held in a list without having to iterate through every element
of said list. It would follow that one should also be able to
label such built-in functions. 

Damian already has plans for C<reduce> that would
require this. I'm sure others can figure out their own uses for
short-circuiting C<grep>, C<map>, and C<reduce>. 

Adoption of this suggestion would create problems with any Perl 5 code
that goes against conventional wisdowm and uses C<last> within a C<grep>
or C<map> block. The workaround would require the Perl 5 to 6 translator
to generate labels for any unlabled C<next>, C<last>, and C<redo> 
statements and their associated C<while>, C<until>, C<for>, and
C<foreach> statements.

Neither Tom Christiansen nor Jarkko Hietaniemi profess to know why the
suggestion with regards to C<grep> hasn't already been implemented.
Perhaps it has to do with the fact that the blocks in C<grep> and C<map>
are only appear to be loops, where as C<while>, C<until>, C<for>, and 
C<foreach> are loops. I have practically no knowledge of the Perl
internals or possible history related to this issue. Please 
enlighten me, and I'll include it in a later revision of this RFC.

If a the built-in's block were terminated by a call to C<last>,
the built-in immediately returns the last block value (i.e.
C<undef> on the first block call, $_[0] otherwise). Or maybe that's
@_ otherwise... someone straighten me out please.

@a = grep( {$_ < 3 or last } (1, 2, 3, 2, 1);

results in:

@a = (1, 2);


@a = grep( { {$_ < 3 or last} } (1, 2, 3, 2, 1);

results in:

@a = (1, 2, 2, 1);

=head1 IMPLEMENTATION

I haven't a clue. Please feel free to suggest one for the next revision.

=head1 REFERENCES

RFC's that require this functionality:

RFC 76:  Builtin: reduce

Ideas that offer alternative routes to similar functionality:

RFC 22: Builtin switch statement

RFC ??: Damian Conway's forthcoming superpositions RFC
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.