What's the point of using "map()" for two elements in perl?

I've seen code where there are just two rather static elements to be mapped such as time intervals with start and end dates, yet map() is being used rather than explicit code for mapping, e.g.

{ map { ... } qw(start end) }   # vs.
{ start => ..., end => ... }

Which way is preferrable, and why?

The map form may be less concise but looks more functional (as in functional programming), so I guess that's why it may be preferred over explicit code and is perhaps more DRY.

However, it looks less legible to me because there is more logic going on behind, and mapping should also be less efficient because it invokes calls a and consists of more atomic operations.

EDIT There is a conflicting goal in programming: KISS (keep it { pick 2 from: small, simple, stupid }). Using map slightly complicates code.

Answers


There is a principle of coding known as DRY. Don't Repeat Yourself.

It asserts that:

Every piece of knowledge must have a single, unambiguous, authoritative representation within a system.

And that can be interpreted as condensing duplicate typing with (things like) map/for.

I use idioms like the one you've quoted when I'm trying to expand some text - for example:

 my @defs = map { "DEF:$_=$source_file:$_:MAX" } qw ( read write ); 

This generates me some DEF lines for rrdtool.

I'm doing it this way, because for some cases, I've got considerably longer lists of 'things I want to define' and want to be consistent. (Sometimes I have say, 10 similar lines that differ only by a single word).

But also because:

my @defs = ( "DEF:read=$source_file:read:MAX",
             "DEF:write=$source_file:write:MAX" ); 

There's not much in it for two elements, and I'd suggest it's as much a matter of style as anything. However, if you've got more than that, it quickly becomes very beneficial because you can change the single line - say you've got a different file location? Want to swap MAX for AVERAGE?

It's also quite shockingly easy to go 'punctuation blind' when looking at a long sequence of similar statements, where someone's typo-ed and added a , where it should be . or similar.

And ... you probably don't lose a great deal in terms of readability. But will acknowledge that's something of a style point, because whilst map is pretty amazing, it can make for some rather hard to read code if you're not careful.

Also to specifically address:

mapping should also be less efficient because it invokes calls a and consists of more atomic operations.

A wise man once said:

premature optimization is the root of all evil

Don't think about the efficiency of a statement - look at the legibility/readability. Compilers are pretty clever. Most "obvious" optimisations, they already make for you. Processors are also pretty fast. Your limiting factor in most code isn't the amount of CPU cycles you need, it's IO throughput and memory footprint. So don't worry about it - write clear code.

And if there's a performance critical demand on your code, you should be using a code profiler to look at where you gain the most efficiency for your effort at refactoring. You may end up with less clear code in doing so (sometimes) but that's a more clear tradeoff.


Assuming you're not just setting both items to the same constant or something similarly trivial, I would expect the map version to be more concise.

IMO, the main point in favor of the map version is that you know the same process will be used to produce both values. Not only for the sake of DRY, but also because it eliminates any concern that one might have a subtle change which the other doesn't.

As for the performance concern... If your use case is sufficiently performance-sensitive for any potential difference to matter, then you shouldn't be using Perl in the first place. Switching to well-written C (not C#, not C++, not Objective C - just plain C) will have a far greater performance impact than micro-optimizing whether you assign two values individually vs. using a loop to set them. But the odds of your use case being that sensitive are approximately zero anyhow.


Need Your Help

Email reports via SQL Server 2008 R2 Reporting Services

sql-server reporting-services ssrs-2008

We have SQL Server Reporting Services running on SQL Server 2008 R2 and we've created some subscriptions to email to specific people. My question is: can I query a database and use an email address...

Domain Object extends Data Transfer Object

.net oop domain-driven-design data-transfer-objects

I'm new to DDD and OO principles, sorry for my poor knowledge.