On 4/19/07, John W. Krahn <[EMAIL PROTECTED]> wrote:
Chas Owens wrote:
> Yes, foreach was aliased to for for backwards compatibility,

Huh?  Do you have something to back up that claim?

Well, perlsyn* says
      The "foreach" keyword is actually a synonym for the "for" keyword, so
      you can use "foreach" for readability or "for" for brevity.  (Or
      because the Bourne shell is more familiar to you than csh, so writing
      "for" comes more naturally.)

But Synopsis 4* says
      There is no foreach statement any more. It's always spelled for
in Perl 6,
      so it always takes a list as an argument

So, you can either start training yourself to say for instead of
foreach now or wait for culture shock down the road.


> but, like
> telnet and rsh, it should not be used in new code.

Really?  I assume you mean the protocols and not the programs?

The protocols and the programs (unless you are using the telnet
program for manual testing of server protocols).


>> I would myself use "for" for the C-style loops
>
> And this is why.  As long as people think "well, I have foreach which
> is for iterating and for which is for C-style loops" they will
> continue to write C-style loops.  C-style loops are bad.  They are
> there for backwards compatibility.  I can't think of a single for loop
> that isn't better written as a range based for loop or while loop. For
> instance
>
> standard range based loop
> for (my $i = 0; $i < 10; $i++) {}
> for my $i (0 .. 9) {}

How about:

for ( my $i = 0; $i < 10; $i += 3 ) {}

foreach my $i ( ? .. ? ) {}

for my $i (0 .. 3) {
  $i *= 3;
}

for my $i (map { $_ * 3 } 0 .. 3) {
       print "$i\n";
}

The bigger question is why is the end condition 10?  Did you intend to
include it the list?  Are you making an off by one error?  This is why
the C-style for loop is bad.

A better phrasing would be:

my @a = (0 .. 10);
for (my $i = 0; $i < @a; $i += 3) { func($a[$i])}

This is much harder to move away from the C-style for loop.  I also
can't think of the last time I needed to do it.

Hmm, the naive  implementation is not bad, it communicates the intent
a little better in my mind, but I don't like it.

my @a = (0 .. 10);
my $i = 0;
for my $elem (@a) {
       next if $i++ % 3;
       func($elem);
}

I think this solution communicates the intent best.

my @a = (0 .. 10);
my $i = 0;
for my $elem (grep {not $i++ % 3} @a) {
       func($elem);
}

In Perl 6 we will have better options.

I don't like this one, it seems too kludgey

for @a -> $elem, undef, undef { func($elem) }

This one is only a little better than the Perl 5 variant

for each(@a ; 0 .. *) -> $elem, $i {
   next if $i % 3;
   func($elem)
}


Of course, there is the C-style for loop in disguise

loop ($i = 0; $i < @a; $i += 3) { func($a[$i]) }


This looks the C-style for loop in disguise

for 0 .. $#a : by(3) -> $i { func($a[$i]) }

But with a little tweak I think it is the best of all

for @a[0 .. $#a : by(3)] -> $elem { func($elem) }


> often $i winds up being used as an index which just makes me cringe.
>
> The infinite loop
> for (;;) {}
> while (1) {}
>
> The reason C programmers give for using for (;;) is that it generates
> less overhead on their platform, but, at least with my tests*,
> while(1) is more efficient in Perl.

I ran your benchmark on my computer and for(;;) and while(1) ran at about the
same speed.

Which still proves the point, for(;;) is no better than while (1) for
infinite loops.  In my opinion while is better since I will eventually
realize that this should not be an infinite loop.

my $continue = 1;
$SIG{__TERM__} = sub { $continue = 0 };
while ($continue} {
}

* http://perldoc.perl.org/perlsyn.html
* http://dev.perl.org/perl6/doc/design/syn/S04.html

--
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
http://learn.perl.org/


Reply via email to