Reputation: 3168
I've been writing perl code full-time for a couple months now(bioinformatics), and am always trying to improve my skills. Just today, it dawned on me that I never use map or grep. Looking back through my code I realize these tools could save me a couple lines here or there, but only at the expense of the flexibility of a foreach loop. My question is as follows:
Are there any circumstances you have run across where using map or grep has brought significant advantage over a foreach/for loop, beyond saving a line or two of code?
Thanks for your time!
Upvotes: 14
Views: 1126
Reputation: 22294
I'm constantly using map
and grep
. And apply
, first
, any
, and many others from List::MoreUtils
. I find that, in general, they explain what the code is doing as opposed to how the code is doing it.
In general, I find that when my code reads the same as the spec, it's more likely to be correct as well as more likely to handle corner/edge cases. Perl allows me to do this much better than any language I've used in the past, and I take advantage of it.
For example, if my spec says that I will do foo()
if $blah
is in some list, my code reads exactly that way:
foo() if any { $_ eq $blah } some_list();
Same idea for the rest of these tools. The code and the spec look eerily similar, and that's one of the great things about Perl.
Upvotes: 16
Reputation: 434835
The Schwartzian Transform would be an example:
@sorted = map { $_->[0] }
sort { $a->[1] cmp $b->[1] }
map { [$_, foo($_)] }
@unsorted;
You could do that with a pile of foreach
loops but you'd have to pick them apart to figure out what was going on; once you've seen the Schwartzian Transform you recognize the idiom immediately.
In general I think map
and grep
are good in that they allow you to clearly and compactly represent your intent without layers of syntax. If you see a map
then you know that some sort of simple data structure transformation is going on; if you see a grep
then you know that some filtering/selection is going on. You could do it all with foreach
but the intent of your code isn't as clear as it would be with map
or grep
; you could even do it all with if
and goto
if you wanted to but then your intent would be buried under even more syntax and state tracking.
Upvotes: 40