Thursday, February 2

truth values

I program in J, and one thing I like there is that "true" is represented by 1 and false is represented by 0.

This corresponds to the concept of an "Iverson Bracket".

Currently, for some reason or another, there is a distinct concept [in many other programming languages] of a "Boolean data type".  Specifically, there is a lot of opposition for the idea of the comparison 2=2 giving a result of 1 and the comparision 2=3 giving a result of 0.

One phrasing of this opposition is that "integers are not boolean".

What I think is really meant, here, is: some languages have "boolean operators" which treat "integers" in a non-boolean fashion.  If so, "integers are not boolean" would be expressing a basic ignorance about what boolean algebra means.  But, I could be mistaken about what this "integers are not boolean" quip means.

But... there's a bigger problem, with the languages which I have looked at, which implement boolean results as a type which is not numeric.

I'll use == for a moment, to represent the test for two values being equal, since this seems to be popular for languages which use non-numeric truth values.  I'm also going to introduce an abstract operator op to help sneak up on my point.

Consider:
    A == a
true
    B == b
true

    (A op B) == (A op B)
true
    (A op B) == (a op B)
false
    (A op B) == (a op b)
false
    (a op B) == (a op b)
true

This is a pervasive feature of many languages.  Here we have the "same" operator operating on the "same" data and giving different truth values.  And this is not a consequence of side-effects or nor is this a case where the test for equality is doing the wrong thing.  These really are different values.

This is, instead, [in my opinion] polymorphism gone wrong.

Here's the expressions again, with "real data":

A: 1
B: 2
a: 1.0
b: 2.0
op: /

   1.0 == 1
true
   2.0 == 2
true

    (1 / 2) == (1 / 2)
true
    (1 / 2) == (1.0 / 2)
false
    (1 / 2) == (1.0 / 2.0)
false
    (1.0 / 2) == (1.0 / 2.0)
true


What's happening here is that / is a different operation from /, depending on the "type" of the data on one side or the other.  It's "really" a whole family of operations only some of which are equivalent.

And, in my opinion, this is a deep flaw in the language because this kind of thing makes reading difficult.  You do not know what operation is being performed when you do not know exactly what machine types are being used.

In a well designed language, the 1/2 operation (which has the result 0) should use a different symbol from the 1/2.0 operation (which has the result 0.5).

And, in my opinion, this is a much bigger issue than the issue of operations which are permissible on a "true" value.

That said... boolean algebra works on integers.  The boolean "AND" operation and the "Least Common Multiple" operation are both the same kind of operation from the viewpoint of boolean algebra.  Likewise, the boolean "OR" operation and the "Greatest Common Denominator" are both the same kind of operation for boolean algebras.  These are sort of classic examples in classes which teach about boolean algebras...

That true and false do not span the full realm of integers is not really an issue, in my opinion.  Nothing on a computer can use fully general integers -- computers are finite and integers are an infinite set.

Anyways, I am inclined to go looking for expressions of the idea that "boolean values cannot be integers" both so I can see if I can refute the arguments, to see if I can find an argument worth considering, and also to see if anyone arguing for the "mathematical purity" of "true" and "false" even considered the language flaw evident where a comparison for equality between 1/2 and 1/2.0 gives a false result