in reply to Re: Map Vs Foreach
in thread Map Vs Foreach

map is a slow

Why do you say that?

map{} takes an input array and makes a new output array

map transforms lists, not only arrays. Likewise, for iterates over lists.

As well, map doesn't have to produce any output. A void context map is poor style in my book, but there's no performance penalty in modern Perls.

Replies are listed 'Best First'.
Re^3: Map Vs Foreach
by Marshall (Canon) on Nov 26, 2009 at 08:23 UTC
    map{} is a wrong idea if the output isn't being used. That is why it can be "slow". But I am hearing that there is no performance penalty for a "void map{}"... meaning that Perl won't create and allocate memory for the output of map{} if is not being used? I didn't know about that. When did this performance enhancement happen?

    I think we both agree that a "void map{}" is bad style. I looked at the post from Ratazong and saw the following code being bench marked:

    my @sqrt_results = map { sqrt ($_ ) } @input;
    This is a perfect thing for map{}: translate one thing to another. map{} can also make 1 to many and many to one translations. In general, I use map{} when the transformation can be expressed as a "one liner+" and foreach() when the code is longer. As a matter of style, this allows me to put foreach(@input) at the top instead of at the end of the program text, compare with: @output = map{lots of lines}@input.
      map{} is a wrong idea if the output isn't being used.
      Why? We use functions and operators without using their output all the time (print for instance). What makes map special that's not using its return value is a sin?
      I didn't know about that. When did this performance enhancement happen?
      6 years ago (5.8.1). After many years of people using the performance penalty of map-in-void-context as an argument not to use map in void context, someone actually produced a one line patch to eliminate that. Didn't stop people from ranting against using map-in-void-context though. Didn't even stop people using the performance argument either.

      Besides, wasn't it Larry himself who said that using things in other ways than originally intended isn't bad in itself? That one can enjoy sex, even if you aren't using it to reproduce yourself?

        To follow up on myself, here's the quote from Larry. He even said it in a debate about map-in-void-context:
        Date: Mon, 1 Nov 1999 15:46:45 -0800 (PST) From: Larry Wall <larry at wall.org> To: hv at crypt0.demon.co.uk Cc: Larry Wall <larry at wall.org>, Simon Cozens <simon at brecon.co.u +k>, perl5-porters at perl.org Subject: Re: grep/map in void context hv at crypt0.demon.co.uk writes: : Isn't the point that (void)'grep EXPR, LIST' is now better written a +s : 'EXPR for LIST'? Or am I misunderstanding your point here? It really doesn't bother me if people want to use grep or map in a voi +d context. It didn't bother me before there was a for modifier, and now that there is one, it still doesn't bother me. I'm just not very easy to bother. The argument against using an operator for other than its primary purpose strikes me the same as the old argument that you shouldn't hav +e sex for other than procreational purposes. Sometimes side effects are more enjoyable than the originally intended effect. That being said, I'd never grep someone in a void context myself. Larry

        Using map in void context is like using print '' to obtain the number 1.

        Jenda
        Enoch was right!
        Enjoy the last years of Rome.

      You asked about the difference between lists and arrays. Here's an example of map operating on lists, not arrays:

      say for map { "$_ squared is " . $_ ** 2 } 1 .. 10;

      If an operator operates on lists, Perl's list context ensures that it can handle arrays. If an operator operates on arrays (push, splice), it won't necessarily operate on lists.