On Sun, Mar 17, 2002 at 12:10:43PM -0700, Chris Fedde wrote:
>
> * Directly address style and resource arguments.
>
> * Expunge levity for the humor impaired.
>
> cvs diff -u perlfaq6.pod
> Index: perlfaq6.pod
> ===================================================================
> RCS file: /home/perlcvs/perlfaq/perlfaq6.pod,v
> retrieving revision 1.8
> diff -u -r1.8 perlfaq6.pod
> --- perlfaq6.pod 31 Jan 2002 04:27:55 -0000 1.8
> +++ perlfaq6.pod 17 Mar 2002 18:58:12 -0000
> @@ -634,10 +634,16 @@
>
> =head2 What's wrong with using grep or map in a void context?
>
> -Both grep and map build a return list, regardless of their context.
> -This means you're making Perl go to the trouble of building up a
> -return list that you then just ignore. That's no way to treat a
> -programming language, you insensitive scoundrel!
> +Both grep and map are mechanisms for generating lists. There may
> +not be anything technically wrong with using grep and map in a void
> +context, except that it does not make your intent clear. Grep and
> +map can be useful to help obfuscate code, but if you intent is to
> +write clear, readable and maintainable code then use for.
> +
> +There is a potential resource problem with current versions of Perl
> +when using map and grep in void context. Perl pushes the result
> +list onto a stack. If the return list is large then your program
> +wastes memory to no good end.
I don't like either paragraph. To start with the latter, if you really
want to advocate against the use of map in void context based on
performance issues, please make it clear that it's only because a fault
in the *implementation of perl* that there is a performance issue - don't
give the impression it's the Perl programmer who is wrong, and should know
better. Note also that this performance issue has been known to p5p for
many years - but it hasn't been deemed serious enough to actually fix it.
I also object to the statement that map (or grep) in void context doesn't
make the intent clear. That's a *subjective* issue. It all depends on
one's programming experience. People who have limited experience, and
only know ALGOL derivated languages (like C) may find it unnatural, but
people with a broader experience might find it natural. I don't think the
FAQ should have this narrow vision, and proclaim that map in void context
means the intent is unclear. There's not much difference between:
for (LIST) {BLOCK}
and
map {BLOCK} LIST;
except for some ordering trivialities. What's next, claiming
$var += 3;
doesn't make the intention clear because the binary operator comes
before the assignment operator?
I'd suggest something along the lines of:
Both C<grep> and C<map> are mechanisms to map an operation on
the elements of a list. Technically, there is nothing wrong with
using C<map> and C<grep> in void context (in Perl, we constantly
use operations with a return value in void context - C<print> and
assignment for instance), but it seems to upset many people. While
Perl allows you to do many things in more than one way, those people
insist C<for> is the only right way to map an operation with side
effects over a list.
There is also a potential performance problem with C<map> and C<grep>
in void context. Perl doesn't recognize that the operation is done
in void context, and will build a list of values - which will be
discarded. Something you might want to consider if you use C<map>
or C<grep> on a huge list. Note however that while this problem has
been known for many years, it hasn't been found serious enough to fix.
Abigail