Beefy Boxes and Bandwidth Generously Provided by pair Networks
Welcome to the Monastery

Re: For vs. Foreach

by ikegami (Pope)
on Feb 13, 2009 at 17:56 UTC ( #743655=note: print w/replies, xml ) Need Help??

in reply to For vs. Foreach

Care must be used if one is to say [...] they can be used "interchangeably".

The keywords can be used interchangeably. Any difference is purely stylistic.

Anyhow, I'm interested in why Perl has the two styles of "for" constructs

Three kinds of loops use for/foreach as far as I'm concerned:

  • Counting loop: for[each] [VAR] (EXPR .. EXPR)
  • Iterative loop: for[each] [VAR] (LIST)
  • C-style for loop: for[each] (EXPR; EXPR; EXPR)

The following iterative loops are optimised in one way or another:

  • for[each] (@array)
  • for[each] (reverse @array)
  • for[each] (reverse EXPR .. EXPR)
  • for[each] (reverse CONST_EXPR .. CONST_EXPR)

"For" looks to behave differently depending on it's context: c-style vs. (er) foreach-style. If one uses c-style "for" loops you don't always get localised indexing variables as you seem to in "foreach" loops.

That's either unclear or wrong.

C-style for loops (whether written with for or foreach) don't localise the index variable simply because they don't accept an index variable.

However, you are free to declare variables in all three of its control expressions, and they will be scoped to the loop.

Replies are listed 'Best First'.
Re^2: For vs. Foreach
by Eimi Metamorphoumai (Deacon) on Feb 13, 2009 at 18:25 UTC
    I'm curious why you consider the "counting loop" to be a fundamentally different kind of loop, instead of listing it among the optimised iterative loops. Is there any difference as far as observable behavior, or is it just that it's implemented differently, or is there really no difference but that's how you conceive of it?

      Good question.

      It is truly optimised to count from the first to the last without creating a list. You could lump it as an optimisation since the effect is the same as if ".." was the range operator. (It's not.) I choose not to.

      People already have a concept of a counting loop from countless other languages. They expect to find a counting loop and presume Perl provides the C-style for loop that purpose. I'm giving them what they are looking for.

      By labeling it as a counting loop, I try to clear the false perception that it should be avoided for efficiency reasons, in order to encourage the use of the for my $i ($x..$y) over the less readable for (my $i=$x; $i<=$y; ++$i).

        Wow! Thank you!

        I have seen that counting construct (i.e., using the ($x..$y) construct in counting for loops) many times before but in the fog of my mind, I had never "connected" the synapses.

        For me, your advice absolutely really *does* improve the readability and maintainability.

        Your advice got through to my adled brain. So you've got one more convert. Thank you.


        ack Albuquerque, NM
        If you break out foreach $n (1..10) { } as separate from foreach $n (LIST) { }, then you should also break out foreach $item (@an_array) {} as a special kind of foreach as well, since a list copy is not made.

        And then you'd also have to break out a slice too. Or any other array lvalue.

        I think your false distinction of "counting loop" as separate is just that. False. There are two kinds of loops: for and foreach. They each have subfeatures. That's it. Not three kinds.

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://743655]
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others drinking their drinks and smoking their pipes about the Monastery: (4)
As of 2020-12-05 18:08 GMT
Find Nodes?
    Voting Booth?
    How often do you use taint mode?

    Results (65 votes). Check out past polls.