Side-effects are something to be avoided when programming.
In Perl? So, you'd prefer to avoid assignment, print statements, regular expressions, and even fetching the value of a variable?
There are programming languages that are more suitable for avoiding side-effects. But programming in Perl while avoiding side-effects makes as much sense as writing English novels while avoiding vowels.
I also like my code to be as self-documenting as possible.
Who doesn't? For me having code as much self-documenting as possible doesn't mean map in void context isn't.
I find map is less than optimal for both of these reasons.
$sum += $index{$_} for split(//, $word);
The map-in-void context equivalent would be
map $sum += $index{$_}, split(//, $word);
I see as many side-effects as the code using 'for', so your example doesn't prove your first reason. In fact, the 'side-effect' reason people often come up with doesn't make any sense. If you do map EXPR, LIST or map BLOCK LIST, the side-effects are in EXPR or BLOCK. The 'for' equivalents are EXPR for LIST and for (LIST) BLOCK. Same EXPR and BLOCK. Same side-effects.
As for documentation (or clearness) issues, I see differences between:
map {BLOCK} LIST
and
for (LIST) {BLOCK}
and that's the order of BLOCK and LIST. If I find the action more important, I prefer map {BLOCK} LIST, as it lists the statement(s) first. If I want to put the focus on the data, I use for (LIST) {BLOCK}. (There's also a difference in context, map gives list context, for void context, but that's seldomly an issue).
I hardly ever use the map EXPR, LIST construct though (regardless of context), as it doesn't clearly separate the action from the data. | [reply] [d/l] [select] |
I don't consider assignment to have a "side effect". Assignment is the effect. It might have a side effect if I'm working with a tied variable, I guess, but that's out somewhere else.
Another difference between for and map is what happens when the BLOCK modifies the array that it's iterating over.
my @x;
# loops once
@x = qw( x );
map { push @x, 'x' } @x;
# loops forever
@x = qw( x );
push @x, 'x' for @x;
| [reply] [d/l] [select] |
Hi, kyle -
I seldom disagree with what you say ... in this case, however, I do, since assignment does indeed have a side effect since it returns a logical true when it was successful. Otherwise the following code would not work:
if ( my $a = 2 )
{
print "Assigned a value to $a";
}
(Yes, I know it produces a warning ... but it still runs ;-) Any comments?
Regards -
Pat | [reply] [d/l] |
| [reply] [d/l] [select] |
I don't consider assignment to have a "side effect". Assignment is the effect.
So,
map {$sum += $_} @array;
is side-effect free? | [reply] [d/l] |
So, you'd prefer to avoid assignment,
I don't know what side effects you are talking about for assignments.
print statements,
I'm not fond of how print changes $!, but it's much more convenient than the alternative. There's also a very high level of consistency with other like functions. system is where it goes overboard ($?).
regular expressions,
I don't use $1, etc. I use the match operator in list context instead.
and even fetching the value of a variable?
Memoizing is a harmless side-effect.
I see as many side-effects as the code using 'for'
As I see it,
The purpose of for is to affect something (necessarily external) repeatedly.
The purpose of map is to transform a list.
You may see things differently, but it was clear that I was explaining how I see things.
| [reply] [d/l] [select] |