12

This is a piece of common example code:

while (1) { 
    print "foo\n"; 
}

which prints 'foo' forever.

perl foo.pl
foo
foo
foo
...

and

while (0) { print "foo\n"; } 

dies quietly as you expect:

perl test.pl

Can someone explain why this is a useful implementation of while? This works on 5.10 at least, Unix and MacOS X:

while (-1) { print "foo\n"; }

which gives

foo
foo
foo
...
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
shigeta
  • 1,791
  • 3
  • 19
  • 32
  • 12
    `-1` is considered to be a true value in many languages. – Quentin Oct 03 '11 at 17:02
  • 5
    In Perl, 0 is false; anything that isn't false is true. – Kristofer Hoch Oct 03 '11 at 17:02
  • 4
    I'm curious as to what led to this question. Is there a language that considers -1 false? – ikegami Oct 03 '11 at 17:11
  • I looked at several example articles and none of them mention negative integers. Seems like something they would have pointed out. – shigeta Oct 03 '11 at 17:19
  • 3
    They did point it out. In toolic's answer there is a quote from perlsyn that clearly states that any non-zero value is considered "true". Question is, why did you think that negative integers were excluded? – TLP Oct 03 '11 at 17:22
  • 10
    Stop downvoting these kind of questions! Answers and explanations here may still be valuable to beginners. – Leonardo Herrera Oct 03 '11 at 17:32
  • 2
    Just by way of comparison, here's what K&R say in The C Programming Language (second edition, p. 223): "In both forms of the `if` statement, is evaluated, including all side-effects, and *if it compares unequal to 0*, the first substatement is executed." (Emphisis added). So this is the standard way of doing things in any language. – frezik Oct 03 '11 at 18:19
  • 5
    @Leonardo To be fair, in its current form this *is* a poor question (sorry, OP!). It starts from an unfounded, unreasonable and unexplained false assumption and throws around several misconceptions without getting to the point. I agree that a related question (“what values are considered `true`, and why?”) is worth asking. The downvotes here, I assume, are because this is precisely *not* asked. – Konrad Rudolph Oct 03 '11 at 19:41
  • @KonradRudolph - I see what you mean. But false and poor assumptions will remain the same until they are asked about and answered by those who know better. – Leonardo Herrera Oct 04 '11 at 18:01
  • 1
    Just change the title of the question. Perl "thinks" its true because it is true. If you had title the question "Why is -1 defined as true in Perl" you would have gotten what you were looking for faster – frankc Jan 10 '12 at 22:39
  • Duplicate an answer, that will work best here is to specify a [real perl true/false expression hack](http://stackoverflow.com/a/21135349/257319) –  Jan 15 '14 at 10:53

7 Answers7

19

Every non-zero integer evaluates to true. And 0 is always false

Foo Bah
  • 25,660
  • 5
  • 55
  • 79
RiaD
  • 46,822
  • 11
  • 79
  • 123
  • 3
    these answers are tautological. i was not asking whether this is true, i can see that. the question is WHY this is true. I looked at a few articles before i posted this and actually this fact is not mentioned that I can see. positive integers are all the examples usually given. – shigeta Oct 03 '11 at 17:13
  • 2
    11 upvotes.. =) It's the really easy answers that gives the biggest reputation rewards. – TLP Oct 03 '11 at 17:15
  • @shigeta - That's an easy answer: it is what it is by definition. As for the reason it was decided this way, there are many explanations, but it was mostly for convenience (pseudocode: if val = 0 then else ) – Leonardo Herrera Oct 03 '11 at 17:30
  • 9
    @shigeta "I looked at a few articles....and actually this fact is not mentioned that I can see." This is a common beginner mistake: Looking for answers in the wrong place. Read the Perl documentation that comes with Perl. http://perldoc.perl.org/perlsyn.html#Truth-and-Falsehood – DavidO Oct 03 '11 at 17:50
  • 2
    @shigeta - because Larry said so way back when. – Bill Ruppert Oct 03 '11 at 19:19
  • None of this provides a serious answer to the question. – reinierpost Oct 04 '11 at 08:07
  • 1
    @reinierpost, the question is somewhat incoherent, or, at best, hopelessly ambiguous. Furthermore, I'd challenge the OP to find a single programming language out there where the final example in the question doesn't hold. – Richard Simões Oct 04 '11 at 10:32
  • @reinierpost - this is a serious answer. Care to elaborate why do you think it is not? – Leonardo Herrera Oct 04 '11 at 18:02
  • It's serious, and relevant, but not an answer to the question. – reinierpost Oct 06 '11 at 11:17
18

If anything, one could say -1 is more likely to be true than 1 since -1 (111..111b) is the bitwise negation of zero (000..000b). BASIC and GW-BASIC used -1 when they needed to return a true value.

Regardless, Perl decided that values that mean "empty" or "nothing" are false. Most languages take a similar view. Specifically, integer zero, floating point zero, the string zero, the empty string and undef are false.

This is documented, although the documentation is poorly worded. (It lists () as a value that's false, but there is no such value.)

Aside from consistency, it's very useful to take this approach. For example, it allows one to use

if (@x)

instead of

if (@x != 0)
ikegami
  • 367,544
  • 15
  • 269
  • 518
  • 1
    In list context there is a value for the empty list, compare `if (($x) = (undef)) { #true` vs `if (($x) = ()) { #false`. In both cases `$x` is set to undef, but the truth of the expression is determined by the number of elements in the list, not by the values of those elements. – Ven'Tatsu Oct 03 '11 at 19:07
  • 1
    @Ven'Tatsu, No, there isn't. The code you posted tests the return value of the assignment, not the return value of `()`. – ikegami Oct 03 '11 at 19:55
  • 1
    @Ven'Tatsu, In case you're curious, list assignment in scalar context returns the number of elements returned by the RHS. e.g. `say scalar( ($x)=(4,5) );` prints `2` and `say scalar( ($x)=() );` prints `0`.) – ikegami Oct 03 '11 at 19:57
16

From perldoc perlsyn (Truth and Falsehood):

The number 0, the strings '0' and '' , the empty list () , and undef are all false in a boolean context. All other values are true.

-1 is considered true.

toolic
  • 57,801
  • 17
  • 75
  • 117
  • I have always considered that when testing a list in boolean context, I am really implicitly testing it in scalar context, which when empty gives zero, thus false. Is it really true that a list has a boolean context evaluation that doesn't get first the scalar treatment? – Joel Berger Oct 03 '11 at 21:38
  • This doesn't answer the question. – reinierpost Oct 04 '11 at 08:07
  • @Joel: More likely, the empty list is just mentioned to avoid confusion. In scalar context, an empty array evaluates to `0` (the number of elements) and an empty list evaluates to `undef` (its final element), both of which are already false without requiring any special-case logic to handle it. – Dave Sherohman Oct 04 '11 at 09:14
  • 2
    @reinierpost - The question states "why Perl thinks -1 is true", and this answer says "only a, b, and c are true, and everything else is false." *Entailment* makes this answer a perfect valid one. – Leonardo Herrera Oct 04 '11 at 18:10
  • I know computer geeks have problems with why questions and only ever get taught about material implication - I am one myself. But they are really different things. – reinierpost Oct 06 '11 at 11:15
4

Only a 0 integer is considered false. Any other non-zero integer is considered true.

Kirk
  • 16,182
  • 20
  • 80
  • 112
4

The question is 'why does perl think -1 is true?'.

The answer is when perl was developed it was decided that certain values would evaluate to false. These are:

  • 0
  • undef
  • '' (empty string)

That is all I can think of a a suitable answer as to why. It was just designed that way.

cubabit
  • 2,527
  • 3
  • 21
  • 34
2

any integer <> 0 is true. 0 is always false.

apollosoftware.org
  • 12,161
  • 4
  • 48
  • 69
  • 1
    Zero but true: perl -E 'say "0e0" ? "True" : "False"' A distinction has to be made in a language that doesn't have a strict typing system between strings and numbers. 0e0 can be a number, it can be a string (which even evaluates to zero), and it can be a true string (because of the e). One minor point of occasional confusion. – DavidO Oct 03 '11 at 17:53
  • 1
    @DavidO, True, but `"0e0"` doesn't return an integer in the CS sense. – ikegami Oct 03 '11 at 18:17
1

Perl took this behavior from awk and C.

Why C does it is explained here.

Community
  • 1
  • 1
reinierpost
  • 8,425
  • 1
  • 38
  • 70