Slash Boxes
NOTE: use Perl; is on undef hiatus. You can read content, but you can't post it. More info will be forthcoming forthcomingly.

All the Perl that's Practical to Extract and Report

use Perl Log In

Log In

[ Create a new account ]

Matts (1087)

  (email not shown publicly)

I work for MessageLabs [] in Toronto, ON, Canada. I write spam filters, MTA software, high performance network software, string matching algorithms, and other cool stuff mostly in Perl and C.

Journal of Matts (1087)

Wednesday April 17, 2002
05:44 AM

Functional Perl

[ #4264 ]

Am I alone in preferring functional perl to procedural perl? I love using map, grep, map, join type stuff, rather than foreach/for loops to do the same. Today's example was "For each found blacklist entry in the hash, check it's value is true, then call $msg->got_hit() for that blacklist". In procedural perl that's:

foreach my $bl (keys %$blacklists) {
  if ($blacklists->{$bl}) {
  # alternatively:
  # $msg->got_hit("RCVD_IN_$bl") if $blacklists->{$bl};

However I prefer to write that as:

map { $msg->got_hit("RCVD_IN_$_") } grep { $blacklists->{$_} } keys %$blacklists;

I guess it's probably because I really grokked Haskell at Uni (until we got into the whole lambda calculus stuff, then I wandered off to do more beer drinking instead). It just fit my brain. I think what I like is that I specify the intent first, and then specify what I'm applying that intent to (because really that's secondary). I love that perl can be multi-paradigm like this, though I'm guessing my co-workers will probably hate me for it ;-)

PS: Yeah yeah map in void context and all that.

The Fine Print: The following comments are owned by whoever posted them. We are not responsible for them in any way.
More | Login | Reply
Loading... please wait.
  • Full support (Score:2, Insightful)

    For the record you have my full support on the use of map in void context. I use if quite often and even find a certain pleasure knowing that it would not pass a certain guru []'s code reviews ;--).

    • Re:Full support (Score:2, Informative)

      In case anyone doesn't know and cares, map in a void context is now optimized to not return any values, so it's no longer de facto inefficient.
      • I did know, but I didn't know when it was fixed. Do you know which perl fixed that?
        • My guess is 5.6.0. But I am not sure.
          • Various people in the latest TPR golf tournament, including me, had problems related to huge memory usage caused by map() in a void context. The same programs worked fine with for(). We were using 5.6.1.

            I didn't think much about it because I didn't know the optimization was supposed to have been done. Plus we all found shorter solutions later on that didn't have the memory problem.
    • I second that as well, in fact map in void context should be compulsory in Perl code to decide whether it's any good ;)

      The only time I've been bitten by it is on one of those occasions when I threw a map in naturally, only to notice later that a for loop would have been much simpler. But that's trivial to fix...


      -- Robin Berjon []

  • Am I alone in preferring functional perl to procedural perl?
    Certainly not. Have you seen Dominus' manuscript yet? It's somewhere at, which isn't resolving for me at the moment...
  • For the record, I agree with you 100%. Something's just fun about map, grep, Schwartzian transform, and things like that.

    Have you seen Ben Tilly's writeup Why I like functional programming [] in the monastery? Great stuff.

  • I've never understood the appeal of map() in void context, at least since the for() statement modifier came out.

    Why is using map() and ignoring the side effects any better than using grep() for the same purpose? Just because grep() is one character longer? It seems obfuscatory, but I must be missing something.

    I might write the line as

    $msg->got_hit("RCVD_IN_$_") for grep { $blacklists->{$_} } keys %$blacklists;

    which seems to communicate the idea more clearly.

  • Until more of the world switches to taking a functional perspective, I suspect that procedural code is going to be more understandable (and maintainable) by the general population of developers.

    Paradigm shifts often take time.

    • Here! Here!

      The problem with functional code is that most fresh meat, er, new hires/newbies won't grok what's going on in the code. By using procedural idioms over the functional ones, your code is more likely to be understood by others (and maybe even you) in the future. Using language neutral idioms in public Perl code goes a very long way to squashing Perl's "unmaintainable, spaghetti code" reputation.

      Does that mean eschewing map and grep all together? I don't think so. It is better to limit the use of

      • My favourite current map/grep idiom is:

        opendir(DIR, $somedir);
        my @files = grep { -f } map { "$somedir/$_" } readdir(DIR);

        Nice and succinct, and I think easy to understand (though I should probably be using File::Spec for portability, but *shrug*). I also partly wish you could do filters like this, sort of like SAX pipelines, so I could do something like:

        my (@files, @dirs) = grep2 { -f, -d } map { "$somedir/$_" } readdir(DIR);

        I'm sure pdcawley will now pipe in how Perl 6 will be able

        • Here's one I've found handy on occasion:

                  @stuff = sort keys %{{ map {$_ => undef} @stuff }};

          gets a sorted list of uniq entries in @stuff.

          I always use undef instead of 1 for insignificant hash values because it just *seems* like it should be more efficient. I've never benchmarked any stress-tests though.

      • By using procedural idioms over the functional ones, your code is more likely to be understood by others (and maybe even you) in the future.

        Any style can be abused to produce good or bad Perl code. Erring on the side of "procedural Perl" for the benefit of newbies doesn't mean it will naturally be easier to understand. I've seen grotty Perl code that's using a classic FORTRAN style, so I'd say that it's more important to write clearly than to write in a specific style. I've also seen code that's bee