Beefy Boxes and Bandwidth Generously Provided by pair Networks
Think about Loose Coupling
 
PerlMonks  

Re: map vs for\foreach.

by MidLifeXis (Monsignor)
on Mar 11, 2015 at 14:27 UTC ( [id://1119638]=note: print w/replies, xml ) Need Help??


in reply to map vs for\foreach.

I strictly reserve map for coercion of a set of FOO items into a set of BAR items (@lista -> map -> @listb), for/foreach for iteration (do_something for @list), and while for terminating on a condition (do_something while sometest()). I don't use map unless I am consistently transforming ALL (typically) of the original items to the new set, although I may combine it with a leading grep if I only want a subset.

--MidLifeXis

Replies are listed 'Best First'.
Re^2: map vs for\foreach.
by karlgoethebier (Abbot) on Mar 11, 2015 at 21:36 UTC
    "I strictly reserve map for coercion of a set of FOO items into a set of BAR items (@lista -> map -> @listb)..."

    And i don't understand why you insist on this.

    Just because there must be an example:

    #!/usr/bin/env perl use strict; use warnings; use Data::Dump; my @foo = ( 1 .. 10 ); dd \@foo; my @bar = map { ++$_ } @foo; dd \@foo; dd \@bar;

    So why is map { ++$_ } @foo; wrong?

    I vaguely remember that there where some performance issues...patched?

    Best regards, Karl

    «The Crux of the Biscuit is the Apostrophe»

      It isn't wrong, it is just not saying what you mean. map is a transformation. for is a loop. If I use map, it is understood that there are to be no modifications to the original data set (and conversely, if there are side effects, I did it wrong). If I use for, then there is the potential for modification of the original data.

      It is, for me, about clarity of intent. That is why I insist (in my code) on this usage.

      --MidLifeXis

        > If I use map, it is understood that there are to be no modifications to the original data set

        I was meditating if map should be changed in this respect.

        Questions:

        • are there use cases where a new list is returned and the old list needs to be altered by alias?
        • if yes, should we introduce a non aliasing default var to avoid this trap? something like $__ or so?
        The usual workaround is to copy $_, like in

        DB<111> @b = map {my $x=$_; ++$x} @a => (2 .. 11) DB<112> @a => (1 .. 10)

        Then again its pretty easy to replace ++$_ with $_+1 and s/x/y/ with s/x/y/r in current Perl versions.

        Not sure if there are any modifying operators left without a non-modifying counterpart.

        Cheers Rolf
        (addicted to the Perl Programming Language and ☆☆☆☆ :)

        PS: Je suis Charlie!

        "... if there are side effects, I did it wrong"

        Yes, yes. But you can do what you want: You get the side effect for free - even if you don't want it.

        #!/usr/bin/env perl use strict; use warnings; use Data::Dump; my @original_data_set = ( 1 .. 10 ); dd \@original_data_set; my @modified_data_set = map { ++$_ } @original_data_set; dd \@original_data_set, \@modified_data_set; __END__ karls-mac-mini:monks karl$ ./1119774.pl [1 .. 10] ([2 .. 11], [2 .. 11])

        Best regards, Karl

        «The Crux of the Biscuit is the Apostrophe»

      So why is map { ++$_ } @foo; wrong?

      If for no other reasons: it’s a little harder to follow and four characters more typing than $_++ for @foo. Superstition makes me post-increment; I think it’s not slower anymore but was back in the dinosaur age. (Update: map $_++, @foo is a little shorter too…)

        Superstition makes me post-increment; I think it’s not slower anymore but was back in the dinosaur age.

        Post-increment is necessarily slower since it requires making a copy of the scalar that pre-increment doesn't. However, Perl replaces post-increment operators in void context with pre-increment operators.

        $ perl -MO=Deparse -e'$_++ for @a;' ++$_ foreach (@a); -e syntax OK $ perl -MO=Deparse -e'map { $_++ } @a;' map {$_++;} @a; -e syntax OK
Re^2: map vs for\foreach.
by builat (Monk) on Mar 11, 2015 at 14:33 UTC
    Is it good practice to mix map with lambda functions? like:
    map{ sub{...} } @list;

      That is essentially what a map is - although your syntax is wrong. Unless you do something like: map { sub {...}->(...) } @foo to force the execution of the sub, you will simply get a set of sub {...} anonymous subroutines the same size as @foo.

      The contents of the BLOCK in the map call are what I think you are thinking of as the sub. OTOH, something like:

      @subs = map { my $something = $_; sub { blah( $something, ... ); } } @data;

      would give you a set of subroutines that each operate on a specific item in @data. In this case, you are still transforming @data into a set of subs working on a closures.

      --MidLifeXis

        Ok, that just blew my mind. (Gotta love those Perl "aha!" moments!)

        Thanks, MidLifeXis :-)

        -Bib

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://1119638]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others avoiding work at the Monastery: (3)
As of 2024-03-28 17:57 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found