Zero is true ... whoda thunk?

Hi,

I can’t find anything in Programming Ruby to suggest why zero is treated as
true, as happens in lines and 12 in the following toy program. Is it
perhaps because Ruby has no boolean type, so zero gets converted to a
string, or something? Aside from an explantion, can you cite a relevant
page in the Thomas&Hunt book?

Thanks in advance,
Richard

def count_exes(l)
n = l.count "x"
end

DATA.each_line do |line|
print line.chomp
if n = count_exes(line) then print "\t(#{n} exes in line) [Pgm line 7]"
end
if (n = count_exes(line)) > 0 then print “\t(additional note for
ex-lines)” end
puts
end

puts “0 is " + (0?“true”:“false”) + " [Pgm line 12]”

END
Two 'xx’s
Three 'xxx’s
No ekses

···

Outgoing mail is certified Virus Free.
Checked by AVG anti-virus system (http://www.grisoft.com).
Version: 6.0.687 / Virus Database: 448 - Release Date: 5/16/2004

don’t know the page, but you can safely assume that every object is
true in ruby, excluding nil and false. And, well, false and true seem
booleans to me :slight_smile:

···

il Tue, 18 May 2004 17:15:26 -0400, “Richard Lionheart” NoOne@Nowhere.com ha scritto::

Hi,

I can’t find anything in Programming Ruby to suggest why zero is treated as
true, as happens in lines and 12 in the following toy program. Is it
perhaps because Ruby has no boolean type, so zero gets converted to a
string, or something? Aside from an explantion, can you cite a relevant
page in the Thomas&Hunt book?

Richard Lionheart wrote:

Hi,

I can’t find anything in Programming Ruby to suggest why zero is treated as
true, as happens in lines and 12 in the following toy program. Is it
perhaps because Ruby has no boolean type, so zero gets converted to a
string, or something? Aside from an explantion, can you cite a relevant
page in the Thomas&Hunt book?

The page you want is 223. The relevant passage is

“Ruby predefines the globals false and nil. Both of these values are
treated as being false in a boolean context. All other values are being
true.”

So zero isn’t being converted into anything but it is considered to be
true since the only values which are considered to be false are nil
values and values that are explicitly false.

One advantage of this is performance. Both NilClass and FalseClass are
singleton classes so checking whether an object is nil or false is very
easy, while allowing 0 to be false would require testing the type and
value of the object.

···


Mark Sparshatt

Hi,

Thanks for your responses. Thanks especially to you, Mark, for the
reference in Programming Ruby.

You folks are great.

Regards,
Richard
“Richard Lionheart” NoOne@Nowhere.com wrote in message
news:4oudnTkSkNU64DfdRVn-hA@comcast.com

Hi,

I can’t find anything in Programming Ruby to suggest why zero is treated
as
true, as happens in lines and 12 in the following toy program. Is it
perhaps because Ruby has no boolean type, so zero gets converted to a
string, or something? Aside from an explantion, can you cite a relevant
page in the Thomas&Hunt book?

Thanks in advance,
Richard

def count_exes(l)
n = l.count “x”
end

DATA.each_line do |line|
print line.chomp
if n = count_exes(line) then print “\t(#{n} exes in line) [Pgm line
7]”

···

end
if (n = count_exes(line)) > 0 then print “\t(additional note for
ex-lines)” end
puts
end

puts “0 is " + (0?“true”:“false”) + " [Pgm line 12]”

END
Two 'xx’s
Three 'xxx’s
No ekses


Outgoing mail is certified Virus Free.
Checked by AVG anti-virus system (http://www.grisoft.com).
Version: 6.0.687 / Virus Database: 448 - Release Date: 5/16/2004


Outgoing mail is certified Virus Free.
Checked by AVG anti-virus system (http://www.grisoft.com).
Version: 6.0.687 / Virus Database: 448 - Release Date: 5/16/2004

The Pickaxe Book reference has been given, but I’d like to point you to
another book which deals brilliantly with this sticky issue:

Why’s (Poignant) Guide to Ruby (Chapter 4)
http://www.poignantguide.net/ruby/chapter-4.html

“Richard Lionheart” NoOne@Nowhere.com wrote…

I can’t find anything in Programming Ruby to suggest why zero is treated
as
true, as happens in lines and 12 in the following toy program. Is it
perhaps because Ruby has no boolean type, so zero gets converted to a
string, or something? Aside from an explantion, can you cite a relevant
page in the Thomas&Hunt book?

Also of note are the methods #nil? and #zero? Naturally the later only
works on Numerics.

···

gabriele renzi (surrender_it@rc1.vip.ukl.yahoo.com) wrote:

il Tue, 18 May 2004 17:15:26 -0400, “Richard Lionheart” > NoOne@Nowhere.com ha scritto::

Hi,

I can’t find anything in Programming Ruby to suggest why zero is treated as
true, as happens in lines and 12 in the following toy program. Is it
perhaps because Ruby has no boolean type, so zero gets converted to a
string, or something? Aside from an explantion, can you cite a relevant
page in the Thomas&Hunt book?

don’t know the page, but you can safely assume that every object is
true in ruby, excluding nil and false. And, well, false and true seem
booleans to me :slight_smile:


Eric Hodel - drbrain@segment7.net - http://segment7.net
All messages signed with fingerprint:
FEC2 57F1 D465 EB15 5D6E 7C11 332A 551C 796C 9F04

Richard Lionheart wrote:

One advantage of this is performance. Both NilClass and FalseClass
are singleton classes so checking whether an object is nil or false
is very easy, while allowing 0 to be false would require testing
the type and value of the object.

Actually, since 0 is an immediate value (like nil and false), it could be tested just as easily (as I understand it). I would guess that the reason has more to do with elegance and simplicity. In any case, aside from the “C does it that way” camp (whom we are obviously not catering to), why should 0 or any number be false? (Why should “” or any string be false? Why should or any array be false?) Well, they aren’t.

Chris

···

On Wed, 19 May 2004 06:34:54 +0900, Mark Sparshatt wrote:

I believe the behavior was borrowed from Smalltalk (or was it Scheme?
one of them). Basically, “Everything is true except false”. And nil.
You get to the point though - what makes zero so special that it would
warrant being false? I recall some vague memories from my Systems
Programming class about the professor saying that in C this is because
zero is an integers, and integers can be fit nicely into one
byte/word/unit thingee. A boolean doesn’t, so it’s a waste of
allocation space, which not so long ago was a quite precious resource.
An integer on the other hand could do all these other nifty things (be
added to, substracted from, etc.), and of all integers zero may as
well be the easiest one to represent bitwise. Now in Ruby the whole
aforementioned train of thought is irrelevant, because integers are
objects just like any other. Why should an existing object be false?
It exists. And as said first, “everything is true except false”. Nil
is not “everything” (it’s not even “something”) so it it out of that
definition, and may thus be false.

···

On Wed, 19 May 2004 10:01:42 +0900, Chris Pine cpine@hellotree.com wrote:

On Wed, 19 May 2004 06:34:54 +0900, Mark Sparshatt wrote:

Richard Lionheart wrote:

One advantage of this is performance. Both NilClass and FalseClass
are singleton classes so checking whether an object is nil or false
is very easy, while allowing 0 to be false would require testing
the type and value of the object.

Actually, since 0 is an immediate value (like nil and false), it could be tested just as easily (as I understand it). I would guess that the reason has more to do with elegance and simplicity. In any case, aside from the “C does it that way” camp (whom we are obviously not catering to), why should 0 or any number be false? (Why should “” or any string be false? Why should or any array be false?) Well, they aren’t.

Chris

Claus Spitzer wrote:

I believe the behavior was borrowed from Smalltalk (or was
it Scheme? one of them). Basically, “Everything is true except
false”. And nil. You get to the point though - what makes zero
so special that it would warrant being false?

Because in the real world, zero means false.

Suppose you have zero quarts of milk in your refrigerator. I am visiting and
I ask:

Got milk?

What’s your answer, yes or no?

No, of course.

It’s fairly unlikely that you would say, “Yes, I’ve got milk. I have zero
quarts of milk. There’s nothing special about the number zero; it’s just
like any other number. So, I’ve got milk.”

Is there any real-life situation where an answer like that would make the
slightest bit of sense? People would think you were either trying to annoy
them or had lost your grip on reality.

That’s why Ruby’s interpretation of zero as “true” seems extremely peculiar
to me. There’s a geeky kind of logic to it, but it doesn’t map onto the real
world at all.

-Mike

p.s. Don’t get me wrong, I like Ruby. :slight_smile: But, it has its warts just like
every programming language.

Because in the real world, zero means false.

Following your logic there should be a to_bool() method for every
class , say:
an empty string, and empty array, an empty set, are clearly false.
When is a regex false? Maybe never ? What about an Hash ? what is the
behaviour you do espect ?

Note that I know that some languages have an equivalent of
to_bool()[1],
but it just makes, imo, the thing harder to grasp: when I use a new
class can I expect that
if myobj
would fail cause ZeroableObj(0 , ‘’) will appear as false while
MyOthjerObj(0, ‘’) does not ?

Suppose you have zero quarts of milk in your refrigerator. I am visiting and
I ask:

Got milk?

What’s your answer, yes or no?

No, of course.

I agree, and I think that having a to_bool makes sense. Still, I
prefer the way it is now.

···

il Tue, 18 May 2004 20:32:41 -0700, “Michael Geary” Mike@DeleteThis.Geary.com ha scritto::

“Michael Geary” Mike@DeleteThis.Geary.com schrieb im Newsbeitrag
news:10allar4vlk2092@corp.supernews.com

Claus Spitzer wrote:

I believe the behavior was borrowed from Smalltalk (or was
it Scheme? one of them). Basically, “Everything is true except
false”. And nil. You get to the point though - what makes zero
so special that it would warrant being false?

Because in the real world, zero means false.

Suppose you have zero quarts of milk in your refrigerator. I am visiting
and
I ask:

Got milk?

What’s your answer, yes or no?

No, of course.

It’s fairly unlikely that you would say, “Yes, I’ve got milk. I have
zero
quarts of milk. There’s nothing special about the number zero; it’s just
like any other number. So, I’ve got milk.”

Is there any real-life situation where an answer like that would make
the
slightest bit of sense? People would think you were either trying to
annoy
them or had lost your grip on reality.

That’s why Ruby’s interpretation of zero as “true” seems extremely
peculiar
to me. There’s a geeky kind of logic to it, but it doesn’t map onto the
real
world at all.

milk_bottles = nil

until milkBottles
milk_bottles = fridge.try_to_figure_number_of_milk_bottles
end

puts “Finally found #{milk_bottles} milk bottels in the fridge.”

while ( value = some_number_data_source_stream.read )
puts “Current value: #{value}”
end

These are the kinds of situations where you want 0 to be treated as
‘true’.

p.s. Don’t get me wrong, I like Ruby. :slight_smile: But, it has its warts just
like
every programming language.

True. And in this case it’s especially true for people coming from perl.

Regards

robert

Hi –

That’s why Ruby’s interpretation of zero as “true” seems extremely
peculiar to me. There’s a geeky kind of logic to it, but it doesn’t
map onto the real world at all.

The real world is highly overrated as a template for programming
languages and the concepts underlying them. Consider that the
following expression evaluates to true in Ruby (and others):

“The earth is flat.”

Of course one could explore and discuss this example in various ways,
but the point is that there’s no self-evident, semantically-based
mapping between natural language and programming language here. The
same is true of comparing the statements “I have zero of X” and “The
expression ‘I have non-zero of X’ is false” and so forth.

p.s. Don’t get me wrong, I like Ruby. :slight_smile: But, it has its warts
just like every programming language.

Perhaps… but this isn’t one of them. Really – it may not be
identical to C, Perl, etc. in this respect, but the implication that
this is a design glitch is really off the mark and potentially
misleading to people trying to understand how it works.

To the other explanations or glosses on this design decision you can
add: everything of a given class has the same Boolean value as
everything else of that class. Fixnum objects (all of them) are true.
There are no special cases, no legacy treatment, nothing thrown in “to
make the people feel at home”. It’s utterly smooth
and consistent in design, and it’s designed carefully with full and
deep awareness of how the same issue is handled in antecedent
languages.

David

···

On Wed, 19 May 2004, Michael Geary wrote:


David A. Black
dblack@wobblini.net

Michael Geary wrote:

Because in the real world, zero means false.

Sorry to change the subject, but for some reason this thread of
conversation reminded me of the old Prolog joke:

Q. How many Prolog programmers does it take to change a lightbulb?

A. no.

“Michael Geary” Mike@DeleteThis.Geary.com wrote in message
news:10allar4vlk2092@corp.supernews.com

what makes zero
so special that it would warrant being false?

Because in the real world, zero means false.

Suppose you have zero quarts of milk in your refrigerator. I am visiting
and
I ask: Got milk?

I just wanted to note that I agree with you 100% and find any other
interpretation baffling. This is a common error for me - 99% of my Ruby
programming errors stem from runtime NoMethodErrors on nil because of Ruby’s
failure to correctly interpret some boundary condition. If numbers always
evaluate to true, it seems absurd to allow them to be used in conditionals
predicating on truth - we should at least get a good diagnostic, IMHO.
Arguments about the elegance or uniformity of zero’s truth are pretty weak
in my opinion, due to the fact that Ruby does not exist in a vacuum. LOTS
of external libraries, extensions, interfaces, etc, implicitly and
explicitly require zero to be false. Personally, I think that the semantics
of the spaceship operator (<=> a <=> a → -1, 0, +1 ) lend credence to the
notion of correlation between the syntax and semantics of numeric values
(especially zero).

-regards,
mm

Michael Geary wrote:

Suppose you have zero quarts of milk in your refrigerator. I am visiting and
I ask:

Got milk?

if (milk_qty > 0)
puts “yes”
else
puts no"
end

Wouldn’t that be the ruby translation of what you’re asking?

Or maybe you don’t care if milk_qty is negative:

if (milk_qty == 0)
puts “no”
else
puts “yes”
end

What you’re asking is “as a general rule, when I convert a number into a
boolean, what value should it have”. And why is it natural that zero be
naturally ‘false’ while every other number be naturally ‘true’.

This is the sort of thing you can’t give a general rule for that will
always work. Zero as false makes sense for converting from the number
of bottles of milk to answer the question “do you have any milk?” On
the other hand, it doesn’t make as much sense for translating the score
of a sports game to “has the game started”. In this case, any number
means that the game as started. What about “Are we doing better than
last time?” In this case, if the number is positive, then the answer is
‘true’, if the number is negative, then the answer is ‘false’. Does
that mean that the boolean representation of ‘-1’ should be false, as
well as every other negative number?

Converting numbers to boolean values is a problem-specific issue, and
shouldn’t have a general case. What’s so difficult about using tests
like (foo == 0) and (foo > 0) anyhow?

Ben

Hi –

That’s why Ruby’s interpretation of zero as “true” seems extremely
peculiar to me. There’s a geeky kind of logic to it, but it doesn’t
map onto the real world at all.

The real world is highly overrated as a template for programming
languages and the concepts underlying them.

how right you are - see below.

Consider that the following expression evaluates to true in Ruby (and
others):

“The earth is flat.”

Of course one could explore and discuss this example in various ways,
but the point is that there’s no self-evident, semantically-based
mapping between natural language and programming language here. The
same is true of comparing the statements “I have zero of X” and “The
expression ‘I have non-zero of X’ is false” and so forth.

p.s. Don’t get me wrong, I like Ruby. :slight_smile: But, it has its warts
just like every programming language.

Perhaps… but this isn’t one of them. Really – it may not be
identical to C, Perl, etc. in this respect, but the implication that
this is a design glitch is really off the mark and potentially
misleading to people trying to understand how it works.

To the other explanations or glosses on this design decision you can
add: everything of a given class has the same Boolean value as
everything else of that class. Fixnum objects (all of them) are true.
There are no special cases, no legacy treatment, nothing thrown in “to
make the people feel at home”. It’s utterly smooth
and consistent in design, and it’s designed carefully with full and
deep awareness of how the same issue is handled in antecedent
languages.

David

i’m in agreement with you. IHMO the whole problem (or concept of one) here
stems from trying to put true, false, and ‘empty’ into the same two boxes -
but this is not really required and, in fact, it is more accurate to have the
notion of true, false, and something else; gÃd¶el showed this:

“Gödel is best known for his proof of “Gödel’s Incompleteness Theorems”. In
1931 he published these results in über formal unentscheidbare Sätze der
Principia Mathematica und verwandter Systeme. He proved fundamental results
about axiomatic systems, showing in any axiomatic mathematical system there
are propositions that cannot be proved or disproved within the axioms of the
system. In particular the consistency of the axioms cannot be proved. This
ended a hundred years of attempts to establish axioms which would put the
whole of mathematics on an axiomatic basis. One major attempt had been by
Bertrand Russell with Principia Mathematica (1910-13). Another was Hilbert’s
formalism which was dealt a severe blow by Gödel’s results. The theorem did
not destroy the fundamental idea of formalism, but it did demonstrate that any
system would have to be more comprehensive than that envisaged by Hilbert.
Gödel’s results were a landmark in 20th-century mathematics, showing that
mathematics is not a finished object, as had been believed. It also implies
that a computer can never be programmed to answer all mathematical questions.”

from

http://www-groups.dcs.st-and.ac.uk/~history/Mathematicians/Godel.html

cheers.
Ã

-a

ps. vim is having a problem with some of these chars… hopefully this msg
isn’t too badly formatted…

···

On Wed, 19 May 2004, David A. Black wrote:

On Wed, 19 May 2004, Michael Geary wrote:

EMAIL :: Ara [dot] T [dot] Howard [at] noaa [dot] gov
PHONE :: 303.497.6469
ADDRESS :: E/GC2 325 Broadway, Boulder, CO 80305-3328
URL :: Solar-Terrestrial Physics Data | NCEI
“640K ought to be enough for anybody.” - Bill Gates, 1981
===============================================================================

EMAIL :: Ara [dot] T [dot] Howard [at] noaa [dot] gov
PHONE :: 303.497.6469
ADDRESS :: E/GC2 325 Broadway, Boulder, CO 80305-3328
URL :: Solar-Terrestrial Physics Data | NCEI
“640K ought to be enough for anybody.” - Bill Gates, 1981
===============================================================================

Honestly, I think that the comparison operator is a counter-example for
zero being false. should (“a”<=>“a”) == false? Breaking it down into
english:

compare the string “a” to the string “a” and determine if the
comparison is false.

In this case, the comparing two equal strings would yield false. I
remember this from a C++ class. The teacher was explaining str_compare
(i think that’s the name) and she mentioned that a common error for
students was to compare two strings and use the returned value as a
boolean; since equal strings return false, that tended to confuse the
student. She recommended never using the result of a comparison of that
type as a boolean, since you might remember wrongly which was true.

cheers,
–Mark

···

On May 19, 2004, at 8:43 AM, Mary M. Inuet wrote:

“Michael Geary” Mike@DeleteThis.Geary.com wrote in message
news:10allar4vlk2092@corp.supernews.com

what makes zero
so special that it would warrant being false?

Because in the real world, zero means false.

Suppose you have zero quarts of milk in your refrigerator. I am
visiting
and
I ask: Got milk?

I just wanted to note that I agree with you 100% and find any other
interpretation baffling. This is a common error for me - 99% of my
Ruby
programming errors stem from runtime NoMethodErrors on nil because of
Ruby’s
failure to correctly interpret some boundary condition. If numbers
always
evaluate to true, it seems absurd to allow them to be used in
conditionals
predicating on truth - we should at least get a good diagnostic, IMHO.
Arguments about the elegance or uniformity of zero’s truth are pretty
weak
in my opinion, due to the fact that Ruby does not exist in a vacuum.
LOTS
of external libraries, extensions, interfaces, etc, implicitly and
explicitly require zero to be false. Personally, I think that the
semantics
of the spaceship operator (<=> a <=> a → -1, 0, +1 ) lend credence
to the
notion of correlation between the syntax and semantics of numeric
values
(especially zero).

Hi,

Arguments about the elegance or uniformity of zero’s truth are pretty weak
in my opinion, due to the fact that Ruby does not exist in a vacuum. LOTS
of external libraries, extensions, interfaces, etc, implicitly and
explicitly require zero to be false.

Perhaps that’s because most libraries, extensions end interfaces are
written in C, where zero is (used to be) the one and only false value?

Please note that even in assembler zero is not a false value. In fact in
assembler there isn’t even a false value. If you perform a conditional
jump, that jump will be based on a condition, which can be “equal to 0”,
“less than zero”, “greater than O”, etc.

The thing is that boolean values (false and true) are a totally different
thing than other objects. They show the correctness of an expression. If
you would say zero means false, than you would say (5 - 5) is false.
From a mathmaticians point of view (which I am not …), (5 - 5) is a
completely valid expression. It makes sense that any expression which
gives just an object is true (valid).
Nil may be an exception, but nil is normally used to mean “not a valid
object”, so it’s value as false is quite logical.

Regards,
Kristof

···

On Wed, 19 May 2004 11:40:36 -0400, Mary M. Inuet wrote:

Ben Giddings wrote:

Converting numbers to boolean values is a problem-specific issue, and
shouldn’t have a general case. What’s so difficult about using tests
like (foo == 0) and (foo > 0) anyhow?

Beautiful and well-thought-out explanation. Thanks!

I’ve had to fight uphill against people that want 0 to mean false for a
long time. The absolute WORST abuse of 0==false is with strcmp in C
(which we use extensively at work):

if( !strcmp( string1, string2 ) ) { … }

I’m SO glad that Ruby forces you to compare numbers explicitly, instead
of implicitly converting to bool. It makes code that much more readable.

···


Jamis Buck
jgb3@email.byu.edu
http://www.jamisbuck.org/jamis

ruby -h | ruby -e
‘a=;readlines.join.scan(/-(.)[e|Kk(\S*)|le.l(…)e|#!(\S*)/) {|r| a <<
r.compact.first };puts “\n>#{a.join(%q/ /)}<\n\n”’

I prefer:

unless milk_qty.zero? then
puts “Darn-tootin!”
else
puts “Shucks, all out!”
end

Ruby provides nice explicit “boolean-test” methods for you, thinks like
#nil?, File.exists?, Numeric#zero?, #respond_to?, Array#include?, etc.
that give you something nice and readable.

···

Ben Giddings (bg-rubytalk@infofiend.com) wrote:

Michael Geary wrote:

Suppose you have zero quarts of milk in your refrigerator. I am visiting
and
I ask:

Got milk?

if (milk_qty == 0)
puts “no”
else
puts “yes”
end


Eric Hodel - drbrain@segment7.net - http://segment7.net
All messages signed with fingerprint:
FEC2 57F1 D465 EB15 5D6E 7C11 332A 551C 796C 9F04