On 8 Sep 2000 04:47:52 -0000, Perl6 RFC Librarian wrote:
>Short-circuiting C<grep>, C<map>, and C<reduce> with C<last>
>(or "Allowing built-in functions to use loop blocks")
>Neither Tom Christiansen nor Jarkko Hietaniemi profess to know why the
>suggestion with regards to C<grep> hasn't already been implemented.
I can give a reason, and it's a language-theoretical one, not a
practical one. grep() and map() are supposed to apply a code block to
each item in a list, and build a result list based upon the block's
decision. But, in theory, processing order has never been officially
declared.
I quote from perlfunc, for grep():
Evaluates the BLOCK or EXPR for each element of LIST (locally
setting `$_' to each element) and returns the list value
consisting of those elements for which the expression evaluated
to true.
Currently, grep() and map() seem to work from left to right
(experimental evidence), but from right to left, all shuffled, or each
item processed by one of a bunch of parallel processors, are all equally
valid assumptions in the functional model.
So, your code block should not use an outer variable $i and do $i++
inside the code block, because the outcome would be different in all the
above cases.
In the same gist, a "last" inside the code block would, if you don't
know exectution order, result in a completely unpredictable result.
Allowing both $i++ and last in a grep code block, which requires an by
official announcement that the execution shall forever be sequential,
from left to right, would break down this simple functional model. It's
your choice.
p.s. Who cares that grep() processes every item for a boolean test? If
you have a 1000 items, on average, you need 500 tests anyway if you're
sure it is in there, and 1000 if it's not. Breaking out of grep early
would at worst do nothing, and at best, on average, double the speed.
(for random cases, somewhere between the two). Hardly worth mentioning.
;-)
--
Bart.