in reply to Re: Re: Re: extracting corresponding values from another array
in thread extracting corresponding values from another array

Likewise. for(;;) is a dirty C trick that doesnt really belong in perl. Especially when the replacement is easier to understand, less prone to error and most importantly more efficient.
Oh, really? A significant part of Perl comes from C, shell, AWK, Ada, BASIC, Python, Fortran, and other languages. Why is for (;;) a dirty C trick that doesn't really belong in Perl, and why isn't for $var (@array) a dirty AWK trick that doesn't belong in Perl? Leave it to the villains of "Harry Potter and the Secret Chamber" to strive for "pure blood".

I also disagree with your other claims. I'm not convinced that the replacement is easier to understand, less prone to error, and more efficient. Let's consider the "dirty C trick":

for (my $i = 0; $i < 1000000; $i += 2) {$sum += $i}

The AWK-like replacement would be:

for my $i (map {$_ * 2} 0 .. 1000000 / 2) {$sum += $i}

I don't think that's easier to understand, or less prone to error. As for efficientcy:

#!/usr/bin/perl use strict; use warnings; use Benchmark; timethese -10, { C => 'my $sum; for (my $i = 0; $i < 1000000; $i += 2) {$sum += + $i}', AWK => 'my $sum; for my $i (map {$_ * 2} 0 .. 1000000 / 2) {$sum + += $i}' }; __END__ Benchmark: running C, AWK for at least 10 CPU seconds... C: 10 wallclock secs (10.66 usr + 0.00 sys = 10.66 CPU) @ 1.41/ +s (n=15) AWK: 10 wallclock secs (10.08 usr + 0.00 sys = 10.08 CPU) @ 0.69/ +s (n=7)

Abigail

Replies are listed 'Best First'.
Re: Re: extracting corresponding values from another array
by demerphq (Chancellor) on Dec 03, 2002 at 15:26 UTC
    Abigail,

    That was an off the cuff remark about using for(;;) instead of for ($lower..$upper). Of course there are uses of for(;;) that do not map on to for ($i..$j). However this wasnt one of them. And for this type of case I stand by my remarks.

    Furthermore comparing

    for (my $i = 0; $i < 1000000; $i += 2) {$sum += $i}
    to
    for my $i (map {$_ * 2} 0 .. 1000000 / 2) {$sum += $i}
    is a bit strange, when internally it is closer to
    { my $i=0; while ($i < 1000000) { $sum+=$i; } continue { $i+=2; } }
    As for all the other languages you listed, none (that I know of) but the C derivatives have this weird form of while loop pretending to be a for loop. For a programmer whose experience is limited to one of the ones without the equivelence the construct is particularly confusing. So from that POV I stand by calling the three arg for loop construct a dirty C trick.

    And I stand by the efficiency claims for the case to which I was primarily referring:

    use strict; use Benchmark qw(cmpthese); our $sum; cmpthese -10,{ 'foreach' => <<'CODE', 'for(;;)' => <<'MORECODE' }; $::sum=0; for my $i (0..10_000) { $::sum+=$i; } CODE $::sum=0; for (my $i=0;$i<10_000;$i++) { $::sum+=$i; } MORECODE __END__ Benchmark: running for(;;), foreach, each for at least 10 CPU seconds. +.. for(;;): 11 wallclock secs (10.61 usr + 0.00 sys = 10.61 CPU) @ 85 +.30/s (n=905) foreach: 11 wallclock secs (10.63 usr + 0.00 sys = 10.63 CPU) @ 14 +3.15/s (n=1521) Rate for(;;) foreach for(;;) 85.3/s -- -40% foreach 143/s 68% --
    Id say thats more efficient wouldnt you?

    --- demerphq
    my friends call me, usually because I'm late....

      Here's the dirty C trick in Java:
      public class Loop { public static void main (String [] argv) { for (int i = 0; i < 10; i ++) { System . out . println (i); } } }

      And here it is in AWK:

      BEGIN {for (i = 0; i < 10; i ++) {print i}}

      And here it is in LPC:

      void loop () { int i; for (i = 0; i < 10; i ++) { write (i + "\n"); } }

      It's not just C.

      Feel free to find for my $i (map {$_ * 2} 0 .. 1000000 / 2) {$sum += $i} a bit strange, because it comes closer to the quoted while statement. But then, don't say that when we change the $i += 2 to $i ++ the alternative is a foreach. That would also be closer to the while.

      I know the foreach is more efficient than the for, but only in the case of incrementing the variant by 1. The for() is far more flexible than the foreach(). The for() is a less error-prone, and easier way of writing the while.

      Abigail

        First off your listing these examples is a bit silly. In my previous node I recognized that C derivatives employ this horrible notation. Most likely to make the C programmers out there more comfortable. And AWK, LPC and Java are all C derivatives (ie they are member of the C side of the programming language family tree).

        Second for my $i (map {$_ * 2} 0 .. 1000000 / 2) {$sum += $i} is nothing like the while statement. Nothing. At bare minimum the while statment does not iterate over a list twice.

        But then, don't say that when we change the $i += 2 to $i ++ the alternative is a foreach. That would also be closer to the while.

        On an abstract level the for(;;) while()continue() and foreach ($i..$j) are identical. At a implementation level the for(;;) and while() are identical, and for($i..$j) is not. And I think few people would say that the practical alternative to for(my $i;$i<10_000;$i++) is a while() structure. Certainly any programmers familiar with the for ($i..$j) would not.

        I know the foreach is more efficient than the for, but only in the case of incrementing the variant by 1.

        And that was precisely my point, and you know it.

        The for() is a less error-prone, and easier way of writing the while.

        I dispute this statement. I do not believe it to be true AT ALL, and even less true for NON-C (like language) programmers. And frankly until you can present some studies that show that cognitively people make less errors with the for(;;) construct than they do with while() im not even going to discuss it. And for two reasons: first I never made any statements regarding these two until this very paragraph, my point was the people make less errors in the case of iterating by 1 when using foreach. Second considering that a big chunk of the programmers out there have minimal exposure to it, I am seriously in doubt as to why a perfectly clear structure analagous or equivelent to structures available in just about every imperative language would produce more errors than one that is as cryptic as for(;;).

        The only part of your last statement that I agree with is that the for(;;) form is easier to write than the while() form. And for good reason. Thats precisely why it was put in the language in the first place. A trade off of legibility for ease of use in application, especially when riduculously slow connections were the norm.

        --- demerphq
        my friends call me, usually because I'm late....

        i am still having problems with this................. say ;
        my $numbers = ('0.12', '0.35','1.34');
        the code below perfectly calculates the greatest difference between two numbers, but i can't get it to return only the two numbers between whcih the difference lies. Any ideas how I could do this? thanks again. e.g. output
        the diff between 0.35 and 1.34 is 0.99.
        for ($i = 2; $i < @numbers; $i++) { if (defined ($numbers[$i]) && defined ($numbers [$i-1])) { $d = abs ($numbers [$i] - $numbers [$i-1]); $d =~ s/-//g; $diff = $d if $diff < $d; @diff_val = "$numbers[$i]\t$numbers[$i-1]\n"; @diff_val = split ('', $testing); push (@d, $d, $diff_val[0], $diff_val[1]); } } print "Greatest difference in the first sample is $diff\n";