You should consider that alternative systems can also be acceptable design decisions.
Shells: 0 exit status is true, non-zero is false
The example of shells treating a 0 exit status as true has already been mentioned.
$ ( exit 0 ) && echo "0 is true" || echo "0 is false" 0 is true $ ( exit 1 ) && echo "1 is true" || echo "1 is false" 1 is false $ ( exit 0 ) && echo "0 is true" || echo "0 is false" 0 is true $ ( exit 1 ) && echo "1 is true" || echo "1 is false" 1 is false The rationale there is that there is one way to succeed, but many ways to fail, so using 0 as the special value meaning "no errors" is pragmatic.
Ruby: 0 is just like any other number
Among "normal" programming languages, there are some outliers, such as Ruby, that treat 0 as a true value.
$ irb irb(main):001:0> 0 ? '0 is true' : '0 is false' => "0 is true" The rationale is that only false and nil should be false. For many Ruby novices, it's a gotcha. However, in some cases, it's nice that 0 is treated just like any other number.
irb(main):002:0> (pos = 'axe' =~ /x/) ? "Found x at position #{pos}" : "x not found" => "Found x at position 1" irb(main):003:0> (pos = 'xyz' =~ /x/) ? "Found x at position #{pos}" : "x not found" => "Found x at position 0" irb(main):004:0> (pos = 'abc' =~ /x/) ? "Found x at position #{pos}" : "x not found" => "x not found" However, such a system only works in a language that is able to distinguish booleans as a separate type from numbers. In the earlier days of computing, programmers working with assembly language or raw machine language had no such luxuries. It is probably just natural to treat 0 as the "blank" state, and set a bit to 1 as a flag when the code detected that something happened. By extension, the convention developed that zero was treated as false, and non-zero values came to be treated as true. However, it doesn't have to be that way.
Java: Numbers cannot be treated as booleans at all
In Java, true and false are the only boolean values. Numbers are not booleans, and cannot even be cast into booleans (Java Language Specification, Sec 4.2.2):
There are no casts between integral types and the type
boolean.
That rule just avoids the question altogether — all boolean expressions have to be explicitly written in the code.