Beefy Boxes and Bandwidth Generously Provided by pair Networks
Keep It Simple, Stupid
 
PerlMonks  

Why is the null while-loop condition expression true?

by AnomalousMonk (Archbishop)
on Mar 28, 2016 at 17:55 UTC ( [id://1158968]=perlquestion: print w/replies, xml ) Need Help??

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

In a recent post, I saw a question about why

while () { <>; last unless /\S/; print FILE; }
produced a "Use of uninitialized value $_ in pattern match (m//) ..." warning. This is easily fixed by assigning the value returned by the  <> (diamond) operator (aka the readline function) to the appropriate variable:
c:\@Work\Perl>perl -wMstrict -le "while () { $_ = <>; last unless /\S/; print qq{>$_<}; } " qeert >qeert < ghjk >ghjk <
(This example works the same under ActiveState 5.8.9 and Strawberry 5.14.4.)

What caught my eye was the null loop condition expression in the
    while () { ...;  last unless ...;  ...; }
infinite loop. I would have thought of something along the lines of
    while (1) { ...;  last unless ...;  ...; }

I'm surprised that a null loop condition expression is accepted by the compiler or, being accepted, that it evaluates as true. Because other boolean "nullities" (undef, the empty string, 0) are false, I would have expected a null condition expression, if it compiled at all, to be false. (A B::Deparse of  while () { ... } shows it to compile to  while (1) { ... } in both Perl versions I tried.)

So, my questions:

  • Is there any documentation or discussion of this behavior? (Offhand, I can't find any in a quick scan of perlsyn.)
  • What is the rationale for this behavior? (Well, it does make a neat shorthand.)


Give a man a fish:  <%-{-{-{-<

Replies are listed 'Best First'.
Re: Why is the null while-loop condition expression true?
by Paladin (Vicar) on Mar 28, 2016 at 18:31 UTC
    From perlsyn (5.22.1 at least):
        As a special case, if the test in the "for" loop (or the corresponding
        "while" loop) is empty, it is treated as true. That is, both
    
            for (;;) {
                ...
            }
    
        and
    
            while () {
                ...
            }
    
        are treated as infinite loops.
    
Re: Why is the null while-loop condition expression true?
by kennethk (Abbot) on Mar 28, 2016 at 18:33 UTC
    Documented in For Loops in perlsyn:
    As a special case, if the test in the for loop (or the corresponding while loop) is empty, it is treated as true. That is, both
    for (;;) { ... }
    and
    while () { ... }
    are treated as infinite loops.
    Not very well placed documentation, and counter-intuitive from my perspective, but documented.

    Update:: A little Googling pulled up while () vs. while (1), particularly Re: while () vs. while (1).


    #11929 First ask yourself `How would I do this without a computer?' Then have the computer do it the same way.

Re: Why is the null while-loop condition expression true?
by hexcoder (Curate) on Mar 28, 2016 at 19:02 UTC
    The rationale might have been that in former art (in this case C) for (;;) { ... } was a common idiom for an infinite loop. While C did not allow an empty condition in a while loop, the canonical treatment of the loop condition in for and while in Perl might have led to this result. I think it is more consistent than in C.
Re: Why is the null while-loop condition expression true?
by AnomalousMonk (Archbishop) on Mar 28, 2016 at 20:58 UTC

    Paladin, kennethk and hexcoder: I sought enlightenment only in my local version 5.14 documentation and did not find it. (Neither is the  for (;;) { ... } variation mentioned.) I should have thought to consult the scrolls on-line. I have to agree the infinitude of  while () { ... } does seem a bit counterintuitive (I was aware of and comfortable with the for-loop version in both C and Perl), but I'm a programmer: I can believe three counterintuitive things before my first cup of coffee.


    Give a man a fish:  <%-{-{-{-<

      I have to agree the infinitude of while () { ... } does seem a bit counterintuitive

      I agree with your reaction, but not your conclusion. With while(1){ doing the intuitively obvious,

      I can see absolutely no justification for equivalence between that and while(){

      Seems most likely to be a bug that slipped through rather than a deliberate act; and remains because of some misguided backward compatibility justifiction; despite that no one in their right mind would code an infinite loop that way in order to save 1 character.

      A bug masquerading as a feature is my assessment.


      With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
      Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
      "Science is about questioning the status quo. Questioning authority". I knew I was on the right track :)
      In the absence of evidence, opinion is indistinguishable from prejudice.
        The source code from v1 seems to make it pretty clear it was deliberate, never a bug. I am with AnomalousMonk. While while(){} is an odd synonym at first blush for while(1){} the idea of ever writing while(){} to mean… all the enclosed code is just for laughs because I never want it to run is even sillier.
Re: Why is the null while-loop condition expression true?
by SimonPratt (Friar) on Mar 29, 2016 at 13:26 UTC

    I agree, that seems very counter-intuitive. It would make more sense to me for while(){...} to function more like while($_){...} instead of while(1){...}

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others perusing the Monastery: (5)
As of 2024-04-19 17:31 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found