Beefy Boxes and Bandwidth Generously Provided by pair Networks
Problems? Is your data what you think it is?
 
PerlMonks  

while () vs. while (1)

by perl5ever (Pilgrim)
on Jan 21, 2011 at 22:48 UTC ( [id://883635]=perlquestion: print w/replies, xml ) Need Help??

perl5ever has asked for the wisdom of the Perl Monks concerning the following question:

I just ran into while ()

Couple of questions:

Besides saving a character is it preferable to while (1)?

When did it get added to the language?

Update: Here are some instances of it from Google Code Search:

http://www.google.com/codesearch?hl=en&lr=&q=lang:perl+while\+\(\)&sbtn=Search

Replies are listed 'Best First'.
Re: while () vs. while (1)
by jwkrahn (Abbot) on Jan 22, 2011 at 00:04 UTC

    It is derived from the C idiom  for (;;) where nothing in the conditional is an infinite loop.

      Interestingly though, C doesn't seem to allow an empty condition for while.

      $ cat a.c int main() { while () { break; } return 0; } $ gcc a.c a.c: In function ‘main’: a.c:2: error: expected expression before ‘)’ token

      It is well known to allow it for for. I read "for (;;)" as "for ever", and use it where some use while (1).

      It could very well be unintentional, but fixing it could break code at no benefit.

Re: while () vs. while (1)
by syphilis (Archbishop) on Jan 22, 2011 at 01:30 UTC
    When did it get added to the language?

    Oldest perl that I have at my disposal is 5.005_05, and while() works there just the same as while(1).
    Looks like it's the same for the subsequent releases of perl, too - though I can't claim to have checked *all* of them.

    Cheers,
    Rob

      I did ...

      perl-xxx -wle 'my$x;while(){$x++==100 and exit 0}exit 1' rank elapsed cuser csys pass perl perl + rank ==== ========== ======= ======= ==== ================= ============== +=== ==== 1 0.00116 0.000 0.000 PASS base/perl5.00405 /pro/bin/perl + 13 2 0.00116 0.000 0.000 PASS base/perl5.00504 /usr/bin/perl + 69 3 0.00128 0.000 0.000 PASS base/perl5.6.2 base/perl5.003 +07 29 4 0.00131 0.000 0.000 PASS base/perl5.8.1 base/perl5.004 +05 1 5 0.00131 0.000 0.000 PASS base/tperl5.6.2 base/perl5.005 +03 23 6 0.00133 0.000 0.010 PASS base/tperl5.6.1 base/perl5.005 +04 2 7 0.00135 0.000 0.000 PASS base/perl5.8.0 base/perl5.6.0 + 67 8 0.00135 0.000 0.000 PASS base/perl5.8.9 base/perl5.6.1 + 14 9 0.00136 0.000 0.000 PASS base/perl5.8.7 base/tperl5.6. +1 6 10 0.00138 0.000 0.000 PASS base/perl5.8.8 base/perl5.6.2 + 3 11 0.00139 0.010 0.000 PASS base/perl5.8.6 base/tperl5.6. +2 5 12 0.00139 0.000 0.000 PASS base/perl5.8.4 base/perl5.8.0 + 7 13 0.00139 0.010 0.000 PASS /pro/bin/perl base/tperl5.8. +0 19 14 0.00142 0.000 0.000 PASS base/perl5.6.1 base/perl5.8.1 + 4 15 0.00143 0.000 0.000 PASS base/tperl5.8.7 base/tperl5.8. +1 37 16 0.00144 0.000 0.000 PASS base/perl5.8.2 base/perl5.8.2 + 16 17 0.00148 0.000 0.010 PASS base/perl5.10.0 base/tperl5.8. +2 31 18 0.00149 0.000 0.000 PASS base/perl5.11.3 base/perl5.8.3 + 36 19 0.00149 0.000 0.000 PASS base/tperl5.8.0 base/tperl5.8. +3 30 20 0.00150 0.000 0.000 PASS base/perl5.12.3 base/perl5.8.4 + 12 21 0.00150 0.000 0.000 PASS base/perl5.12.2 base/tperl5.8. +4 24 22 0.00150 0.000 0.000 PASS base/perl5.8.5 base/perl5.8.5 + 22 23 0.00150 0.000 0.000 PASS base/perl5.00503 base/tperl5.8. +5 46 24 0.00151 0.000 0.000 PASS base/tperl5.8.4 base/perl5.8.6 + 11 25 0.00151 0.010 0.000 PASS base/tperl5.8.9 base/tperl5.8. +6 72 26 0.00151 0.000 0.000 PASS base/perl5.13.4 base/perl5.8.7 + 9 27 0.00151 0.000 0.000 PASS base/perl5.11.0 base/tperl5.8. +7 15 28 0.00151 0.000 0.000 PASS base/perl5.13.2 base/perl5.8.8 + 10 29 0.00151 0.000 0.000 PASS base/perl5.00307 base/tperl5.8. +8 39 30 0.00151 0.000 0.000 PASS base/tperl5.8.3 base/perl5.8.9 + 8 31 0.00152 0.000 0.000 PASS base/tperl5.8.2 base/tperl5.8. +9 25 32 0.00152 0.000 0.000 PASS base/perl5.13.3 base/perl5.10. +0 17 33 0.00152 0.000 0.000 PASS base/perl5.13.5 base/tperl5.10 +.0 43 34 0.00153 0.000 0.000 PASS base/perl5.12.1 base/perl5.10. +1 42 35 0.00154 0.000 0.000 PASS base/perl5.12.0 base/tperl5.10 +.1 50 36 0.00154 0.000 0.000 PASS base/perl5.8.3 base/perl5.11. +0 27 37 0.00154 0.000 0.000 PASS base/tperl5.8.1 base/tperl5.11 +.0 58 38 0.00154 0.000 0.000 PASS base/perl5.13.8 base/perl5.11. +1 40 39 0.00154 0.000 0.000 PASS base/tperl5.8.8 base/tperl5.11 +.1 60 40 0.00155 0.000 0.000 PASS base/perl5.11.1 base/perl5.11. +2 41 41 0.00156 0.000 0.000 PASS base/perl5.11.2 base/tperl5.11 +.2 61 42 0.00156 0.000 0.000 PASS base/perl5.10.1 base/perl5.11. +3 18 43 0.00158 0.000 0.000 PASS base/tperl5.10.0 base/tperl5.11 +.3 57 44 0.00159 0.000 0.000 PASS base/perl5.11.4 base/perl5.11. +4 44 45 0.00161 0.000 0.000 PASS base/perl5.13.0 base/tperl5.11 +.4 54 46 0.00161 0.000 0.000 PASS base/tperl5.8.5 base/perl5.11. +5 51 47 0.00162 0.000 0.000 PASS base/perl5.13.6 base/tperl5.11 +.5 75 48 0.00163 0.000 0.000 PASS base/tperl5.13.0 base/perl5.12. +0 35 49 0.00164 0.000 0.000 PASS base/perl5.13.7 base/tperl5.12 +.0 63 50 0.00164 0.000 0.000 PASS base/tperl5.10.1 base/perl5.12. +1 34 51 0.00165 0.000 0.000 PASS base/perl5.11.5 base/tperl5.12 +.1 64 52 0.00165 0.000 0.000 PASS base/tperl5.13.7 base/perl5.12. +2 21 53 0.00166 0.000 0.000 PASS base/tperl5.12.3 base/tperl5.12 +.2 62 54 0.00166 0.000 0.010 PASS base/tperl5.11.4 base/perl5.12. +3 20 55 0.00167 0.000 0.000 PASS base/tperl5.13.3 base/tperl5.12 +.3 53 56 0.00168 0.000 0.000 PASS base/tperl5.13.2 base/perl5.13. +0 45 57 0.00168 0.000 0.000 PASS base/tperl5.11.3 base/tperl5.13 +.0 48 58 0.00170 0.000 0.000 PASS base/tperl5.11.0 base/perl5.13. +1 74 59 0.00170 0.000 0.000 PASS base/tperl5.13.1 base/tperl5.13 +.1 59 60 0.00170 0.000 0.000 PASS base/tperl5.11.1 base/perl5.13. +2 28 61 0.00170 0.000 0.000 PASS base/tperl5.11.2 base/tperl5.13 +.2 56 62 0.00171 0.000 0.000 PASS base/tperl5.12.2 base/perl5.13. +3 32 63 0.00171 0.000 0.010 PASS base/tperl5.12.0 base/tperl5.13 +.3 55 64 0.00172 0.000 0.000 PASS base/tperl5.12.1 base/perl5.13. +4 26 65 0.00173 0.000 0.000 PASS base/perl5.13.9 base/tperl5.13 +.4 70 66 0.00173 0.000 0.000 PASS base/tperl5.13.9 base/perl5.13. +5 33 67 0.00173 0.000 0.000 PASS base/perl5.6.0 base/tperl5.13 +.5 71 68 0.00173 0.000 0.000 PASS base/tperl5.13.8 base/perl5.13. +6 47 69 0.00174 0.000 0.000 PASS /usr/bin/perl base/tperl5.13 +.6 73 70 0.00177 0.000 0.000 PASS base/tperl5.13.4 base/perl5.13. +7 49 71 0.00178 0.000 0.000 PASS base/tperl5.13.5 base/tperl5.13 +.7 52 72 0.00180 0.000 0.000 PASS base/tperl5.8.6 base/perl5.13. +8 38 73 0.00183 0.000 0.000 PASS base/tperl5.13.6 base/tperl5.13 +.8 68 74 0.00191 0.000 0.000 PASS base/perl5.13.1 base/perl5.13. +9 65 75 0.00196 0.000 0.000 PASS base/tperl5.11.5 base/tperl5.13 +.9 66

      Enjoy, Have FUN! H.Merijn
Re: while () vs. while (1)
by JavaFan (Canon) on Jan 22, 2011 at 10:48 UTC
    I've known about this behaviour for a long time. I think it's because while (EXPR) { } is treated as if it were for (;EXPR;) { }. And for (;;) { } is, just as in C, an infinite loop.

    Note that Deparse turns both while () {} and for (;;) {} into while (1) {}.

      Note that Deparse turns both while () {} and for (;;) {} into while (1) {}.

      All three are identical in the optree, but it's closer to while () {}. No "1" constant exists. All C-style for loops, while loops and bare loops ("{ ... }") are implemented using the same loop op. The condition of "while (1)" is completely optimised away.

Re: while () vs. while (1)
by cdarke (Prior) on Jan 22, 2011 at 05:33 UTC
    And it is strange that the statement modifier has a different effect:
    print "Here\n" while();
    does not produce an infiinite loop, whereas:
    while(){print "Here 2\n"}
    does, which is a bit inconsistent.

    Update: I just tried the following in Rakudo*:
    # perl6 while () { say "Hello" }
    and it did not give an infinite loop, it dropped straight through. That might be an effect of () being an empty list (false), so I tried
    while {say "Hello 2"}
    but that would not compile. The bare loop statement is specifically for infinite loops in p6 SFAIK, but
    while 1 {say "Hello 2"}
    also works as expected.

      You seem to have forgotten that statement modifiers don't use parens.

      # EXRP while EXPR; print "Here\n" while ();

      is the equivalent of

      # while (EXPR) { EXPR; } while ( () ) { print "Here\n" }

      Both behave identically.

        perl -e"warn foo, last while;" syntax error at -e line 1, near "while;"

        - tye        

Re: while () vs. while (1)
by Anonymous Monk on Jan 21, 2011 at 23:41 UTC

      Seeing how it is not documented

      You could even say it's documented to behave differently than it does. Empty lists* evaluate to false, but while () {} loops endlessly.

      $ perl -E'while (()) { say("foo"); last }' $ perl -E'say("foo"), last while ();' $ perl -E'while () { say("foo"); last }' foo

      Intentionally or otherwise, it's definitely related to for (;;).

      * — Parens don't create lists. Parens are sometimes required to indicate the presence of an empty list (e.g. "my $x = ;" and "= f();" are invalid), but not always (e.g. "print;" and "for () {}" are valid).

Re: while () vs. while (1)
by merlyn (Sage) on Jan 24, 2011 at 22:27 UTC
    When did it get added to the language?
    Pretty sure Perl 1 worked that way so, like, 1987? :)
    edit: Yes, so saith the grammar in perl.y from Perl-1.0
    loop : label WHILE '(' texpr ')' compblock { $$ = wopt(add_label($1, make_ccmd(C_WHILE,$4,$6) )); } ... texpr : /* NULL means true */ { scanstr("1"); $$ = yylval.arg; } | expr ;

    -- Randal L. Schwartz, Perl hacker

    The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119.

Re: while () vs. while (1)
by sundialsvc4 (Abbot) on Jan 23, 2011 at 22:47 UTC

    Just make what you are writing “abundantly clear.”   Let there be no doubt in the reader’s mind as to exactly what, whatever you have written, will actually do.   That is the one, and only, important thing, in my humble.

      1) you only control your own thought/doubts 2) use documented syntax only
Re: while () vs. while (1)
by nif (Sexton) on Jan 24, 2011 at 09:31 UTC

    As already mentioned by JavaFun, "B::Deparse" shows that perl compiles "while(){}" and "for(;;){}" to the same code, so "1" and "2" behave different, "3" and "4" are equal, "5" and "6" are also equal ...

    #!/usr/bin/perl use B::Deparse; my $deparse = B::Deparse->new(); my $sub0 = sub { for(;;) {print}; }; my $sub1 = sub { while () {print}; }; my $sub2 = sub { while ( () ) {print}; }; my $sub3 = sub { print while (); }; my $sub4 = sub { print while ( () ); }; my $sub5 = sub { print until (); }; my $sub6 = sub { print until ( () ); }; foreach ( $sub0, $sub1, $sub2, $sub3, $sub4, $sub5, $sub6 ) { print $count++,":\nsub ", $deparse->coderef2text($_), "\n\n"; }

    Program output:

    0: sub { while (1) { print $_; } } 1: sub { while (1) { print $_; } } 2: sub { while (()) { print $_; } } 3: sub { print $_ while (); } 4: sub { print $_ while (); } 5: sub { print $_ until (); } 6: sub { print $_ until (); }

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://883635]
Approved by roubi
Front-paged by ikegami
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others making s'mores by the fire in the courtyard of the Monastery: (5)
As of 2024-03-28 23:54 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found