http://www.perlmonks.org?node_id=594208

in reply to Re^2: Mutable foreach list?

The following are all implemented differently:

• for (EXPR; EXPR; EXPR) ("C-style for loop", an augmented while loop.)
• for (EXPRX..EXPRY) (A range and nothing else.)
• for (reverse CONSTX..CONSTY) (A constant range, preceded by reverse.)
• for (reverse EXPRX..EXPRY) (A variable range, preceded by reverse.)
• for (@ARRAY) (An array and nothing else.)
• for (reverse @ARRAY) (Reverse of an array and nothing else.)
• for (reverse LIST) (Reverse of any list that doesn't fit the above patterns.)
• for (LIST) (Any list that doesn't fit the above patterns.)

You might find the difference between foreach (@ARRAY) and foreach (LIST) interesting.

```{
my \$x = 1;
my \$y = 4;

# The initial values are saved.

my @a;

foreach (\$x..\$y) {
push @a, \$_;
\$y++;
}

print("@a\n");
# 1 2 3 4
}

{
my \$x = 1;
my \$y = 4;

# The initial values are saved.

my @a;

foreach (reverse \$x..\$y) {
push @a, \$_;
\$x--;
}

print("@a\n");
# 4 3 2 1
}

{
my @a = (1, 2, 3, 4);
my \$i = 5;

# Loops "while (pass_num < @a)".
# In this case, that means loop forever.

foreach (@a) {  # Loops "while (pass_num < @a)"
push(@a, \$i++);
if (@a == 20) { push(@a, '...'); last; }  # Avoid infinite loop.
}

print("@a\n");
# 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 ...
}

{
my @a = (1, 2);
my @b = (3, 4);
my \$i = 5;

# Creates a list at the start of the
# loop and iterates over that list.
# In this case, elements are added to @b,
# but not to the list on the stack, so
# it loops 4 times.

foreach (@a, @b) {
push(@b, \$i++);
}

print("@a @b\n");
# 1 2 3 4 5 6 7 8
}

The difference between
foreach (reverse CONSTX..CONSTY)
and
foreach (reverse EXPRX..EXPRY)
is that the list in built at compile time in the former.

```>perl -le "for (1..2) { for (reverse 1..3) { print; \$_=5; } }"
3
2
1
5
5
5

>perl -le "for (1..2) { for (reverse 1..(\$x=3)) { print; \$_=5; } }"
3
2
1
3
2
1