Abigail said:
Darin McBride (
[email protected]) wrote on MMMDCCXXIII
September MCMXCIII in <URL::: 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.
[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.
Until vs while is easy - again, the most readable one wins. If your
assertion is positive, use while, if it is negative, use until.
And now we're really straying off the topic of this thread.
You can do loops in the following ways:
[ If you're trying to be pedantic, you missed some. ]
Good for when you have a C-style index.
Good for when you have a perl-style index.
Good when what you're trying to do is an action, and it happens to be
looped, rather than what you're trying to do is loop, and during the
loop you want to do something. Use the right loop construct for what
you're trying to do rather than try to jimmy the wrong construct into
doing what you want (which is what you have to do in most other
languages with limited choices).
These are the same as each other with the minor difference noted above
- one's assertion is positive while the other is negative. Good when
you're waiting for a condition to be false/true, and until that
happens, you want to do stuff.
Hmmm - there is probably a bit more needed here (redo?) I would
definitely not recommend this.
Good if you're making regex substitutions.
Good if you're trying to find many of the same thing in a given string.
Not generally good for looping - there is usually a better construct
for what you're trying to do.
Good if you're mapping one space (array) onto another space (array).
Good for finding a subset of a given array.
Don't pick on map in void context. Could you please pick one, and make
a case against the other 10, and not just map?
Use the one that fits the job you have for it. Both map and m// are
there to create an array. If you don't want the array, I fail to see
why you'd use m//, but for map, foreach is exactly equivalent in the
void context. Use it.
:: 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.
:: 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.
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.
:: Then, after scrutinising the
:: map's block (as it's usually a block not an expression), I may figure
:: out that they intended to have void (e.g., only doing it for the side
:: effect). And then, if that's not the source of the problem, I can go
:: on.
But if the function wasn't called "map", but "zeebleflup", and it was
used in void context, would you get confused as well? What if it was
called "apply_this_function_over_the_elements_of_a_list"?
Well, if it were called "zeebleflup", I'd be looking for zeebleflup's
definition to understand what the heck it is, and why someone thought
that this was a brilliant name to give a function.
You see, I'm not worried about some "map" crusade. I'm looking for
readability. I'd be just as curious about why someone calls map in
void context as someone calling $my_circle->get_radius() in void
context. If someone was looking at the return to a function that
obviously shouldn't have one, I'd be just as curious (although I can't
think of an example function name that would cause me to think this
offhand).
:: However, if they had used foreach to begin with, I might have been
:: able to skip over the code altogether knowing that "ignoring the
:: return" is exactly what was intended.
Again, why do you assume that if map was used in void context the
programmer was in error, and you have to confirm yourself it wasn't the
case, and you don't have this Pavlov reaction with other functions? What
makes map trigger this behaviour?
Who said I don't have this reaction to any other function? Perhaps
some of your previous sparring partners are that way, but you paint me
unfairly with the same brush. If I were into the same ad hominum style
debate, I'd start wondering about your knee-jerk reactions...
:: Simply have your code say what you mean rather than trick the virtual
:: machine into doing what you want by side effect.
If I write:
map {BLOCK} LIST;
I write *exactly* what I mean. I want to map an operation over a list.
It simple can't be named simpler.
If we were writing LISP where that's what map means, that's fine. But
in perl, if you want to "map an operation over a list", that's called
"foreach".
:: 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.