Raku / old-design-docs

Raku language design documents
https://design.raku.org/
Artistic License 2.0
124 stars 36 forks source link

"0" in boolean context evaluates to False #87

Closed grondilu closed 9 years ago

grondilu commented 9 years ago

While looking at http://rosettacode.org/wiki/Temperature_conversion#Perl_6, it occurred to me that it's a bit unfortunate that the string "0" (and not the integer) evaluates to False. It's not much consistent either, considering that other strings of null numerical value (e.g. "-0" or "0+0i") evaluate to True.

If "0" was evaluating to True, the loop could be written:

while my $temperature = prompt "Temperature: " {
    ...
}

with no risk of ending the program prematurely if the user enters "0".

See also IRC backlog of this day.

polettix commented 9 years ago

I daresay it's what I would expect according to the principle of least surprise as a Perl5 hacker.

IIRC, in Perl5 there is "0 but true" that evaluates to a true value in boolean context (or "0E0" for what that matters), but it becomes the integer 0 when evaluated as a number (I'm completely ignorant about Perl6 number system).

Ciao,

Flavio.

2015-03-11 10:48 GMT+01:00 grondilu notifications@github.com:

While looking at http://rosettacode.org/wiki/Temperature_conversion#Perl_6, it occurred to me that it's a bit unfortunate that the string "0" (and not the integer) evaluates to False. It's not much consistent either, considering that other strings of null numerical value (e.g. "-0" or "0+0i") evaluate to True.

See also IRC backlog of this day.

— Reply to this email directly or view it on GitHub https://github.com/perl6/specs/issues/87.

retupmoca commented 9 years ago

+1 to the string "0" being True, and the number 0 being false.

If I have a statement if $value I typically want either Str.Bool ("Does this string have characters"), OR Num.Bool ("Is this number non-zero"), not some combination of the two. Perl 5's behavior ("0" false) has caused dumb bugs in a number of my Perl 5 programs, and at least one bug in Rakudo's CORE.setting (see https://github.com/rakudo/rakudo/commit/dd4a0e6f066308f5cdac0f85d21d9cc046025f3b)

zoffixznet commented 9 years ago

:-1: for me. Testing a string for length is more explicit. Having different behavor based on the type of the argument would produce action-at-a-distance bugs that are much harder to nail down than the examples mentioned above.

FROGGS commented 9 years ago

@zoffixznet what do you mean by "different behavor based on the type"? I mean, that is hat types are for, encapsulate behaviour. For me a "0" being a string but boolifying like a number is pretty weird.

zoffixznet commented 9 years ago

@FROGGS , I gues it's a difference of backgrounds. I'm very new to Perl 6, but have been coding Perl 5 for years. For me, this code/result would be pretty weird, especially if that sub is from some module about whose innards I should not care.

zoffix@~:/tmp$ perl6 -e 'sub foo ($x) { if ( $x ) { say "Self-destruct sequence activated"; } else { say "We get to live another day" } };  foo(0); foo("0");'
We get to live another day
Self-destruct sequence activated
zoffix@~:/tmp$ 

But you do bring up a good point that types encapsulate behaviour and the above should probably be sub foo ( Str $x ) { ...

FROGGS commented 9 years ago

Or even sub foo ( Str() $x ) { ... or sub foo ( Real() $x ) { ...

zoffixznet commented 9 years ago

I'm changing my opinion to :+1: then. The bugs would still be possible, but for a different reason, and conceptually _string_ "0" is not false.

labster commented 9 years ago

I have very mixed feelings about this, coming from a Perl 5 background. I'm used to not caring about the data type (and having it be unknowable), and I have thought falsy "0" to be convenient. At the same time, I've been tripped up on bugs like the 0° temperature (even though real programmers use Kelvin).

Anyway, changing Str.Bool in Rakudo only generates 5 spectest failures, 4 of which are direct tests of 0.Str's truthiness (S03-operators/context-forcers.t, /S32-str/bool.t). The only interesting failure is in S26-documentation/09-configuration.t, on the sheep test.

Additionally, Str.Bool seems about 9% faster without checking for "0" in my primitive A/B test. Common op, but marginal gain.

FROGGS commented 9 years ago

This issue can be considered fixed: https://github.com/perl6/specs/commit/befb20c3bf

Now we just need to align rakudo+roast.