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


in reply to Re: If I was forced to use only one kind of loop for the rest of my days it would be a
in thread If I was forced to use only one kind of loop for the rest of my days it would be a

If I program C, I'd definitely go with for. (That's what I've voted for.) It's just much more general than while. To tell the truth, just about any looping construct is more general than while.
Now I'm curious. Could you give an example of a loop you could write with "for" that you couldn't write with "while"?
#include<stdio.h> int main(int argc, char** argv) { int a = 0; while(a++,a<10) { printf("%d\n",a); } }
  • Comment on Re^2: If I was forced to use only one kind of loop for the rest of my days it would be a
  • Download Code

Replies are listed 'Best First'.
Re^3: If I was forced to use only one kind of loop for the rest of my days it would be a
by Roger_B (Scribe) on Oct 01, 2005 at 13:35 UTC
    While it's true you can do anything you can do with a for loop with a while loop, I picked for.

    I really like the capability that for gives you to keep all the operations controlling the loop - initialisation, incrementing and testing - in one place. In C99 (and Perl) you can declare variables in the for statement, and they will have a scope of precisely the for loop. You'll need an extra block to do that with while. So taking the example above, I assume this is intended to synthesise (updated:) ambrus noted that this is equivalent to:

    // UNTESTED for(int a = 1; a<10; a++) { printf("%d\n",a); }

    In fact, you'll need an extra block to get the correct scope:

    // UNTESTED // UPDATED: de-obfuscated { int a = 1; while(a<10) { printf("%d\n",a); a++; } }

    Which is starting to look rather messy.

    Context switch back to Perl here!

    Synthesising while and foreach from for seems reasonably intuitive to me on the other hand.

    # UNTESTED for (;EXPR;) BLOCK # leave first and third EXPRs blank to be # equivalent to while (EXPR) BLOCK # UNTESTED for (my @list = LIST, VAR = shift @list; # iterate manually through @list; # LIST in "for" to be VAR = shift @list) BLOCK # somewhat like # foreach VAR (LIST) BLOCK # without the usual aliasing

    OK, the foreach is starting to look a bit funny, but a foreach from while will be worse, and spread into the block, rather than be confined to the statement itself.

    One issue is that for doesn't have a continue block, but as I come from C I don't tend to use those. continue blocks also split up code that happens every time round the loop, which puts me off. for's third expression is roughly equivalent I suppose, but stuffing a large continue block there could hardly be called good style.

    Recursion is another story but I don't think I could live with it as the only looping mechanism. I'd rather have the reverse issue of synthesising recursion, say with a list of hashes, on the rare occasions I really needed it.

    updated in response to ambrus's comments.

    Also, note:

    perl -MO=Deparse -e "for (;<>;){print}" while (defined($_ = <ARGV>)) { print $_; } -e syntax OK

    the for deparses as a while!

      In fact, I belive

      for(int a = 0; a<10; a++) { printf("%d\n",a); }
      is equivalent to
      { int a = 0; while(a<10) { printf("%d\n",a); a++; }
      Your other code,
      { int a = 0; while(a++,a<10) { printf("%d\n",a); } }
      doesn't run the printf statement with a = 0.
Re^3: If I was forced to use only one kind of loop for the rest of my days it would be a
by ambrus (Abbot) on Sep 30, 2005 at 16:21 UTC

    In C, there's no such loop. But that's true to goto and most other constructs as well, you know. It's just that I like the foreach version of the loop more.