laziness, impatience, and hubris PerlMonks

### For vs. While

by Andrew_Levenson (Hermit)
 on Dec 05, 2006 at 23:51 UTC Need Help??
Andrew_Levenson has asked for the wisdom of the Perl Monks concerning the following question:

I've been messing with my "Japh" thing (I tried to space it out for this node as best I could) and I noticed something peculiar (to me, at least):
```V(qw/74 401 211 79/);
sub V{while(@_){
\$v**=\$V?\$#_:\$V;
print(
map{
\$V<\$v?
chr(shift):
chr(reverse(pop))}\$_)
,\$V+=\$#_%2!=1?1:0}}

If I swap the while for a for, it only prints out "Ja".
Why might it do that?
I thought I may be cutting it off early by pop'ing off of the end, but that doesn't make any sense to me.

```

V(qw/74 401 211 79/);sub V{while(@_){\$v**=\$V?\$#_:\$V;
print(map{\$V<\$v?chr(shift):chr(reverse(pop))}\$_),\$V+=\$#_%2!=1?1:0}}

Replies are listed 'Best First'.
Re: For vs. While
by ikegami (Pope) on Dec 05, 2006 at 23:57 UTC

for (@array) loops until the number of iterations is greater than the number of elements in the array. When you reached the 3rd iteration of your for loop, @_ only has two elements (because of shift and pop), so the loop exits.

```sub f1 {
while (@_) {
print(shift);
}
print("\n");
}

sub f2 {
for (@_) {
print(shift);
}
print("\n");
}

sub f3 {
for (map \$_, @_) {
print(shift);
}
print("\n");
}

f1(map/./g, Japh);  # Japh
f2(map/./g, Japh);  # Ja
f3(map/./g, Japh);  # Japh

f2 iterates over the elements of @_.
f3 iterates over a premade list on the stack, so it doesn't matter that @_ changes.

Ahh, that makes perfect sense. Thanks!
```

V(qw/74 401 211 79/);sub V{while(@_){\$v**=\$V?\$#_:\$V;
print(map{\$V<\$v?chr(shift):chr(reverse(pop))}\$_),\$V+=\$#_%2!=1?1:0}}

That behaviour is specifically for for (@array). for (@array) is different than other forms of for (LIST). As soon as one iterates over anything but just an array, it's the size of the list on the stack that matters.

The real difference is that for (@array) is optimized to avoid flattening @array onto the stack. Instead, for (@array) navigates @array in place. For all other expressions, a list is formed on the stack and for iterates over that.

The following show the difference between iterating in place, and iterating over a list on the stack.

```sub f4 {
for (@_) {
print(\$_);
shift;
}
print("\n");
}

sub f5 {
for ((), @_) {
print(\$_);
shift;
}
print("\n");
}

f4(map/./g, Japh);  # Jp
f5(map/./g, Japh);  # Japh
Re: For vs. While
by Joost (Canon) on Dec 05, 2006 at 23:56 UTC
Pop and shift without arguments work on the @_ array (in subroutines at least), and modifying arrays update: that is; adding or removing elements - modifying elements is fine while looping through them with for(each) is IIRC not even officially supported. Even though it appears to do more or less what I'd expect.

In short it doesn't work for exactly the reason you mentioned. :-)

Create A New User
Node Status?
node history
Node Type: perlquestion [id://588005]
Approved by Joost
help
Chatterbox?
 [Lady_Aleena]: Corion, I knew that, I was just giving Discipulus a hard time. choroba likes the story at the end of the node [choroba]: reminds me of the days at the bank [Corion]: Lady_Aleena: Hehe ;-D [Lady_Aleena]: Corion, it was PerlMonks who kept pushing me to get Linux, so now I know some of the commands to use in word play. [Corion]: Lady_Aleena: :-D [Lady_Aleena]: Corion, so do you think the gods would be open to taking over Cookies should I disappear for too long a time?

How do I use this? | Other CB clients
Other Users?
Others imbibing at the Monastery: (8)
As of 2017-04-26 08:32 GMT
Sections?
Information?
Find Nodes?
Leftovers?
Voting Booth?
I'm a fool:

Results (471 votes). Check out past polls.