Re: Style question: map versus foreach
From: Abigail (abigail_at_abigail.nl)
Date: 11/11/03
- Next message: Anno Siegel: "Re: Checking environment variable existence"
- Previous message: Anno Siegel: "Re: Calling a sub in main script from module"
- In reply to: Darin McBride: "Re: Style question: map versus foreach"
- Next in thread: Darin McBride: "Re: Style question: map versus foreach"
- Reply: Darin McBride: "Re: Style question: map versus foreach"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Date: 11 Nov 2003 12:46:30 GMT
Darin McBride (dmcbride@naboo.to.org.no.spam.for.me) wrote on MMMDCCXXIV
September MCMXCIII in <URL:news:grWrb.362981$pl3.319787@pd7tw3no>:
@@ Abigail wrote:
@@
@@ > Darin McBride (dmcbride@naboo.to.org.no.spam.for.me) wrote on MMMDCCXXIII
@@ > September MCMXCIII in <URL:news:RKQrb.361373$6C4.143831@pd7tw1no>:
@@ > :: Abigail wrote:
@@ > ::
@@ > :: > If you're going to assume the maintainer doesn't know basic concepts
@@ > :: > of Perl, all bets are off. Then one might want to avoid hashes and
@@ > :: > regexes too.
@@ > ::
@@ > :: True to a point. However, there is no cleaner way to do hashes or
@@ > :: regexes. There is a clearer way to do map in void context: foreach.
@@ >
@@ > But could you give an objective reason why foreach is "clearer" than
@@ > map (after defining what "clearer" is)? Or is it your own preference?
@@
@@ <sigh> I thought I had. Let me try again:
@@
@@ The only real difference between map and foreach is that map returns a
@@ value, while foreach doesn't [1]. Thus, if you intend on ignoring the
@@ return, don't create it in the first place and just use foreach.
map in void context has never returned anything. No function in void
context has ever returned anything. How could it - if it returned
something, it couldn't have been in void context. Now, up to 2 versions
ago, map created a temporary list, even if it didn't need it. That has
now been fixed.
@@ [1] Foreach actually returns the same way any block does - the last
@@ statement executed in the last time through the loop is the return
@@ value. But this is not generally useful. It only makes perl more
@@ consistant.
@@
@@ > What makes foreach cleaner than while? Or is while cleaner than
@@ > foreach? Which one ought to go? Or can we have foreach, for, while,
@@ > until, goto, and bare blocks, but not map in void context?
@@
@@ While vs foreach is another discussion (I wish we'd stick to a single
@@ topic, but that's not generally possible on usenet, I suspect). If the
@@ only data I have to work with is whether we're in void context or not,
@@ then neither while nor foreach are different. However, they have other
@@ strengths which would come up should we actually debate those. Again,
@@ use whichever one makes the most readable sense.
The latter is a good remark. That's why I sometimes use while, sometimes
for/foreach, and sometimes map in void context. See, there is a difference
how you read them:
map ACTION DATA;
for DATA ACTION;
If I want to have the focus on the action, I prefer map. If I want to
focus on the action, I prefer for. But focus isn't the only thing that's
important for readability. I prefer shorter things before larger things.
So, if my block is large, I'll prefer to use for. But if the data is
coming from a long and complex expression, I'll favour map.
@@ Until vs while is easy - again, the most readable one wins. If your
@@ assertion is positive, use while, if it is negative, use until.
So, you decide on for vs while and while vs until on a case by case
basis. That's good. However, you dismiss map right away.
@@ > :: The main point of map is the return value. The main point of foreach
@@ > :: is the iteration over an array (no return value implied).
@@ > ::
@@ > :: o Avoid using grep() (or map()) or `backticks` in a void
@@ > :: context, that is, when you just throw away their
@@ > :: return values. Those functions all have return val-
@@ > :: ues, so use them. Otherwise use a foreach() loop or
@@ > :: the system() function instead.
@@ > ::
@@ > :: I think this is the whole debate. Unfortunately, there's no real
@@ > :: explicit justification here.
@@ >
@@ > Which makes it just the personal preference of one man, doesn't it?
@@
@@ No - it means that the perlstyle authors (who are probably more
@@ proficient in perl than the both of us put together) thought this would
@@ be obvious and unneeding of justification.
Well, apparently it isn't obvious, and in dire need of a justification.
But I don't think Larry is going to do that. Some fragments of perlstyle:
Larry has his reasons for each of these things, but he
doesn't claim that everyone else's mind works the same as
his does.
o Just because you CAN do something a particular way
doesn't mean that you SHOULD do it that way. Perl is
designed to give you several ways to do anything, so
consider picking the most readable one. For instance
open(FOO,$foo) || die "Can't open $foo: $!";
is better than
die "Can't open $foo: $!" unless open(FOO,$foo);
because the second way hides the main point of the
statement in a modifier. On the other hand
print "Starting analysis\n" if $verbose;
is better than
$verbose && print "Starting analysis\n";
because the main point isn't whether the user typed -v
or not.
See? Larry thinks that it's important that you mention the main point
first. So, if the main point is the action, not the data it acts upon,
you would write:
map ACTION DATA;
and not
for DATA ACTION;
@@ > :: Given that map and foreach do almost exactly the same thing with only
@@ > :: the desired contexts being different, it makes sense to me that one
@@ > :: would use the version one desires based on that context difference.
@@ > :: Thus, when I see map in void context, the first thought in my mind is
@@ > :: "they didn't get the return from map!".
@@ >
@@ > Ah, yes. Logical. There are thousands and thousands of user defined
@@ > functions whose return value isn't collected. There are many Perl
@@ > defined functions and operators whose return value isn't collected.
@@ >
@@ > Noone ever makes a fuss. But if the function of which the return
@@
@@ I do. If there are two user defined functions that do exactly the same
@@ thing, but one allocates and returns an array, and the other does not
@@ but has the same desired side effects, I would expect people to use the
@@ appropriate one depending on whether they want the array returned or
@@ not. I don't see any difference.
There are two points against that:
1) map in void context *doesn't* allocated an array whose
values remained unused.
2) it goes against all ideas of encapsulation. If in order
to use a module, I would first have to study the implementation
of its functions, why bother? I could write my own. But you
go further, you require people to first have studied the
implementation of perl before they can pick the "right way".
I presume you have carefully studied all the libraries Perl
links in as well?
@@
@@ > value isn't collected is called "map", hundreds of Perl programmer
@@ > brains go into overload, and the programmers start running around
@@ > like chickens without their heads. "They didn't get the return from
@@ > map! They didn't get the return from map! Keep your daughters inside!
@@ > Keep your daughters inside! The end of times in coming! The antichrist
@@ > has arrived!"
@@
@@ I'm not sure that the Six Degrees of Godwin game would have anticipated
@@ this as "legitimate topic drift".
@@
@@ > I really don't get it. map in void context isn't doing anything else
@@ > than the countless of other functions in void context that are called
@@ > because of their side effects. Yet it sparks gigabytes of discussions.
@@
@@ Only because there is an exact duplicate of map functionally that is
@@ there for void context.
There is also an exact duplicate of 'unless' (which even takes less
characters to type). Should 'unless' be avoided as well? The functionality
of while() can also exactly be duplicated with bare blocks. Should
while() be avoided? If the answers are 'no', then why is it so bad
there's another way of doing a map in void context?
@@
@@ > :: In general, side
@@ > :: effects make code harder to understand.
@@ >
@@ > Then you shouldn't be programming in Perl. Because in Perl, you can't
@@ > do much useful without side effects.
@@
@@ Hmmm... I dunno - I've managed to do a lot of useful stuff without side
@@ effects in perl.
Really? Could you show some code? Remember, assignment and print are
only useful because of their side effects.
Abigail
-- perl -we 'print split /(?=(.*))/s => "Just another Perl Hacker\n";'
- Next message: Anno Siegel: "Re: Checking environment variable existence"
- Previous message: Anno Siegel: "Re: Calling a sub in main script from module"
- In reply to: Darin McBride: "Re: Style question: map versus foreach"
- Next in thread: Darin McBride: "Re: Style question: map versus foreach"
- Reply: Darin McBride: "Re: Style question: map versus foreach"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Relevant Pages
|