First of all, I come from C, Java, Python background. Recently, I started learning Perl for my new job and I got curious about \'0\'
(0-string) being false.
Internal storage format, ideally, should never matter in Perl. Zero is zero is zero, no matter whether it's stored in an IV, UV, NV, PV, etc.
In fact, because it can, Perl will change the format in which values are stored in ways that might surprise you. If string 0
was true, the following would print "true":
$x = 0;
print("$x\n");
if ($x) {
print("true\n");
} else {
print("false\n");
}
Perl has no explicit typing, and its interpretation of type is highly context-dependent. For example:
$a = "2b";
$b = "3a";
$c = $a + $b;
print $c;
yields 5.
on the other hand...
$a = "b2";
$b = "3a";
$c = $a + $b;
print $c;
yields 3.
and...
$a = "b2";
$b = "3a";
$c = $a.$b;
print $c;
yields b23a
So "'0' (string)" is not a string, or a number, or a bool, until you use it, and then it can be any of those things, determined by its use. Type is not determined until you try to operate. Then Perl assesses the context to endeavour your intention and acts accordingly. This is a Feature, and why there are Many Ways to Do Things in Perl. It can of course lead to a plenty of confusing code but is excellent for 1-liners, obfuscation and Perl golf.
Perl has a number of values that are considered "false": undef
, zero, the string "0"
, the empty string, a special boolean value that morphs into the empty string or the empty list depending on context, and objects that are overloaded for boolean context.
Most of these (undef, zero, empty string, the special value, objects) are actually pretty useful. The string "0"
being false stems from the way perl implements scalars and falseness: A scalar contains both a string portion and a numeric portion. To determine, if a value is false, the string portion is consulted first. Why is this necessary?
my $false_ish = 0; # the scalar contains only a number
'' . $false_ish; # force stringy context. the scalar now contains stringy portion.
if ($false_ish) { ... } # string portion is consulted first...
Without this, the number zero would lose its falseness once you use it where a string is needed. On the other hand, this allows "0 but true"
, a true string wich is the number zero, and "0E0"
, which is scientific notation for zero, but also evaluates to true.
If you read that it has anything to do with <>
, you are reading bad sources; I can't imagine where that claim would come from.
'0' is false because almost everywhere perl doesn't distinguish between numbers stored in numeric form and in string form; doing so in boolean tests would run against this grain.
In languages (Python, Javascript?) where '0' is true, I find it odd that '' is false; why make an exception for one string but not the other?
0 equates to false in C, as well - it equates to false in several "legacy" programming languages, perhaps due to 0's inherent tie to binary and circuits, where 0 can mean "no charge".
In any case, newer languages often inherit behaviors and interpretations of languages before. The binary meaning of 0 being "no charge" or "it is false that there is a charge" has been long since abstracted out of any high-level programming language, but the tidbit of semantic still remains even through the most modern programming languages.
Also - to the best of my knowledge, it has nothing to do with <> - where did you read that?
Perl steals inherits features from a number of other languages, including C, awk, Bourne shell, and a number of others.
In C, any 0 value is false, and any non-zero value is true. Perl just uses the same semantics.
The fact that Perl has more things that can be used in scalar or boolean context than C does, particularly strings, means that Perl has multiple false values.
Making the integer 0
false makes perfect sense to C programmers. Making the empty string ""
false also makes sense. Since Perl can treat the same scalar either as a number or as a string, making the string "0"
false was nearly inevitable.
For example:
$x = 2;
$x -= 2;
print "x = $x\n"; # prints "x = 0"
if ($x) {
print "A C programmer would be surprised to see this\n";
}
$x = "";
$x .= chr(48);
# Now $x eq "0", a string value that was built without reference to
# the number zero -- but it's nearly the same thing as the number 0.
print "\$x = $x\n"; # pritn "x = 0"
if ($x) {
print "A C programmer would be equally surprised to see this\n";
}
If Perl had been designed from scratch without borrowing so many features from other languages, it might have made a stronger distinction between strings and numbers, rather than grouping them together as scalars. Given such a hypothetical Perl-like language, quite possibly the empty string and the number 0
would be false, but the string "0"
would be true -- and you'd need an explicit conversion to convert from the number 0
to the string "0"
.
But Perl is as it is.