Java’s Broken Booleans

  • Thread starter Lawrence D'Oliveiro
  • Start date
L

Lawrence D'Oliveiro

Java gets points for including a boolean type, but loses them for putting
barriers between booleans and other discrete types that other languages do
not. True, they didn’t want to play fast and loose with the distinction
between booleans and integers in the way that C and C++ do. But that’s still
no excuse for a) not providing easy conversion between false/true and 0/1,
b) not allowing ordering comparisons on booleans, and c) not allowing
booleans as array index types.

Consider clunky old Pascal, the epitome of an utterly anal-retentive
language that carried type-safeness to the irritating extreme, the butt of
jokes by C programmers back in the day (and I remember that day). Even that
allowed you to write things like

var
buf : array [boolean] of buffertype;
curbuf : boolean;

and then do all the usual stuff you might do with double buffers:

while not_yet_finished do
begin
...
... do something involving buf[curbuf] ...
... you could even reference buf[not curbuf] if you needed to ...
...
curbuf := not curbuf
end {while}

For another example, most programming languages don’t have an “impliesâ€
operator. I can live with that; in all those languages you can write “A
implies B†(A and B being boolean values) as “not A or B†(or “!A || Bâ€,
depending on your notation). In all of them that I’m aware of except one,
you can also write this as “A <= Bâ€. That exception is Java.
 
A

Arne Vajhøj

Java gets points for including a boolean type, but loses them for putting
barriers between booleans and other discrete types that other languages do
not. True, they didn’t want to play fast and loose with the distinction
between booleans and integers in the way that C and C++ do.

Exactly - good choice by Java.
But that’s still
no excuse for a) not providing easy conversion between false/true and 0/1,

b = (i != 0);
i = b ? 1 : 0;

is pretty easy.
b) not allowing ordering comparisons on booleans,

There are no logical ordering of booleans.
and c) not allowing
booleans as array index types.

That was a design choice that Java inherited from C/C++.

It keeps the language simple but loose a bit of type safeness.

It is as it is.

Arne
 
A

Arved Sandstrom

Java gets points for including a boolean type, but loses them for putting
barriers between booleans and other discrete types that other languages do
not. True, they didn’t want to play fast and loose with the distinction
between booleans and integers in the way that C and C++ do. But that’s still
no excuse for a) not providing easy conversion between false/true and 0/1,
b) not allowing ordering comparisons on booleans, and c) not allowing
booleans as array index types.
[ SNIP ]

a) as Arne pointed out, one can convert easily enough. I suspect however
that if someone is going down that road they are already making design
mistakes. For me a proper truth value is ternary, with an opaque TRUE,
an opaque FALSE, and an opaque UNKNOWN. A Java Boolean with
Boolean.TRUE, Boolean.FALSE and null serves that purpose reasonably
well. Not in 30+ years of coding have I encountered a situation where I
truly needed corresponding integers...unless the language had no boolean
type to start with.

b) I can see that ordering complaint with SQL (where it comes up often
enough with some RDBMS's), but I don't understand the requirement for
TRUE to be greater than FALSE in any programming language whatsoever. If
you need to sort/group a list of objects by a Boolean field that's easy
enough to arrange with an adhoc comparator.

c) boolean array index types: instruct me, I'm feeling stupid tonight -
what's the motivation for this one? If you really needed something close
to this why not a 2-key map? You could even use that for your false/true
=> 0/1 converter...

AHS
 
J

Joshua Cranmer

Java gets points for including a boolean type, but loses them for putting
barriers between booleans and other discrete types that other languages do
not. True, they didn’t want to play fast and loose with the distinction
between booleans and integers in the way that C and C++ do. But that’s still
no excuse for a) not providing easy conversion between false/true and 0/1,

val = bool ? 1 : 0;

Was that hard?
b) not allowing ordering comparisons on booleans

Is true less than or greater than false? Why or why not?
> c) not allowing
booleans as array index types.

arr[bool ? 1 : 0], or bool ? arr[1] : arr[0] if you prefer that style.
For another example, most programming languages don’t have an “impliesâ€
operator. I can live with that; in all those languages you can write “A
implies B†(A and B being boolean values) as “not A or B†(or “!A || Bâ€,
depending on your notation). In all of them that I’m aware of except one,
you can also write this as “A<= Bâ€. That exception is Java.

And `A <= B' smells very heavily of code that will make most people go
"WTF?" on first sight, and anyone who uses it in production code should
be shot. If you want a language that's very terse, you get APL, which is
notable for being a language where comprehension is nearly impossible.
 
L

Lawrence D'Oliveiro

Patricia said:
On 2/14/2011 6:14 PM, Lawrence D'Oliveiro wrote:
...
Consider clunky old Pascal, the epitome of an utterly anal-retentive
language that carried type-safeness to the irritating extreme, the butt
of jokes by C programmers back in the day (and I remember that day). Even
that allowed you to write things like

var
buf : array [boolean] of buffertype;
curbuf : boolean;

and then do all the usual stuff you might do with double buffers:

while not_yet_finished do
begin
...
... do something involving buf[curbuf] ...
... you could even reference buf[not curbuf] if you needed to
... ...
curbuf := not curbuf
end {while}

Why do you prefer boolean to integer for buffer indexing?

Double buffer <=> two values.
 
K

Kevin McMurtrie

Lawrence D'Oliveiro said:
Java gets points for including a boolean type, but loses them for putting
barriers between booleans and other discrete types that other languages do
not. True, they didn’t want to play fast and loose with the distinction
between booleans and integers in the way that C and C++ do. But that’s still
no excuse for a) not providing easy conversion between false/true and 0/1,
b) not allowing ordering comparisons on booleans, and c) not allowing
booleans as array index types.

Consider clunky old Pascal, the epitome of an utterly anal-retentive
language that carried type-safeness to the irritating extreme, the butt of
jokes by C programmers back in the day (and I remember that day). Even that
allowed you to write things like

var
buf : array [boolean] of buffertype;
curbuf : boolean;

and then do all the usual stuff you might do with double buffers:

while not_yet_finished do
begin
...
... do something involving buf[curbuf] ...
... you could even reference buf[not curbuf] if you needed to ...
...
curbuf := not curbuf
end {while}

For another example, most programming languages don’t have an “impliesâ€
operator. I can live with that; in all those languages you can write “A
implies B†(A and B being boolean values) as “not A or B†(or “!A || Bâ€,
depending on your notation). In all of them that I’m aware of except one,
you can also write this as “A <= Bâ€. That exception is Java.


I have used the ordinal value of booleans in Pascal but I didn't notice
it missing from Java until now. Java's lack of unsigned math and arrays
of structures has been more of a pain.

I recall Pascal having problems with booleans acquiring an ordinal value
other than 0 or 1. Maybe proper data cleansing was difficult when the
ordinal value is accessible directly or through compiler optimizations.
 
L

Lawrence D'Oliveiro

Kevin McMurtrie said:
Java's lack of unsigned math ...

That too.
... and arrays of structures has been more of a pain.

At least you can construct arrays of pointers to structures. One annoying
thing about Java structures is having to list all the fields three times,
once in the field declarations and twice in the constructor definition.
I recall Pascal having problems with booleans acquiring an ordinal value
other than 0 or 1. Maybe proper data cleansing was difficult when the
ordinal value is accessible directly or through compiler optimizations.

Sounds like implementation bugs. Sometimes these could be aggravated by
hardware misfeatures, like the Motorola 68000 instruction set having
“conditional set†instructions, which did a comparison and returned what was
supposed to be a boolean, only the value for true was -1, not +1.
 
L

Lawrence D'Oliveiro

Patricia said:
Of course, but why two boolean values rather than two integer values?

Because the boolean “not†operator provides a convenient way of flipping
between them.
I think of double buffering as a special case of N-way buffering.

It’s the most important case. Two buffers are commonly used wherever you
pass data between two asynchronous processes, e.g. file I/O, network I/O,
graphics rendering ... loads of situations.
 
L

Lawrence D'Oliveiro

b) I can see that ordering complaint with SQL (where it comes up often
enough with some RDBMS's), but I don't understand the requirement for
TRUE to be greater than FALSE in any programming language whatsoever.

Well, guess what, they all do—except Java.

Also go look up the mathematics of Boolean algebra, and consider why the
“or†and “and†operators are also described as “addition†and
“multiplication†(e.g. in the use of Galois fields and their application to
computations like CRCs).
 
A

Arved Sandstrom

Well, guess what, they all do—except Java.

Also go look up the mathematics of Boolean algebra, and consider why the
“or†and “and†operators are also described as “addition†and
“multiplication†(e.g. in the use of Galois fields and their application to
computations like CRCs).

For Boolean algebra any domain of 2 values will do, Larry. The nature of
Boolean values is that they're logical, not numeric. If you sincerely
believe that any understanding of Boolean algebra _requires_ a concrete
representation as {0,1} then I submit that perhaps _you_ should look up
the mathematics of Boolean algebra.

AHS
 
R

Roedy Green

Consider clunky old Pascal, the epitome of an utterly anal-retentive

Anal retentive IS GOOD in computer programs. Sloppy means the compiler
cannot detect bugs. It means there are several ways of doing things
which makes programs harder to follow.
--
Roedy Green Canadian Mind Products
http://mindprod.com
Refactor early. If you procrastinate, you will have
even more code to adjust based on the faulty design.
..
 
A

Andreas Leitgeb

Peter Duniho said:
You must _really_ hate having to write "i = i > 0 ? 0 : 1" or "i = (i +
1) % 2" or "i = b ? 1 : 0"

I would, too, but there's also "i = 1 - i;" for flipping an int between
0 and 1.

PS: I do have some sympathy for the sentiment that "bool?1:0" sucks, though.
 
S

Silvio

Java gets points for including a boolean type, but loses them for putting
barriers between booleans and other discrete types that other languages do
not. True, they didn’t want to play fast and loose with the distinction
between booleans and integers in the way that C and C++ do. But that’s still
no excuse for a) not providing easy conversion between false/true and 0/1,
b) not allowing ordering comparisons on booleans, and c) not allowing
booleans as array index types.

Consider clunky old Pascal, the epitome of an utterly anal-retentive
language that carried type-safeness to the irritating extreme, the butt of
jokes by C programmers back in the day (and I remember that day). Even that
allowed you to write things like

var
buf : array [boolean] of buffertype;
curbuf : boolean;

and then do all the usual stuff you might do with double buffers:

while not_yet_finished do
begin
...
... do something involving buf[curbuf] ...
... you could even reference buf[not curbuf] if you needed to ...
...
curbuf := not curbuf
end {while}

For another example, most programming languages don’t have an “impliesâ€
operator. I can live with that; in all those languages you can write “A
implies B†(A and B being boolean values) as “not A or B†(or “!A || Bâ€,
depending on your notation). In all of them that I’m aware of except one,
you can also write this as “A<= Bâ€. That exception is Java.

All Basic variants I have touched in the 80s used -1 for true and 0 for
false. Visual Basic still does it that way.

A <= B will equate to A || !B there.

Any way it seems quite stupid to write A <= B if you actually mean !A ||
B. If any programmer in my team did such a thing I would certainly kick
his butt.

Silvio
 
L

Lew

[...]
Of course, but why two boolean values rather than two integer values?

Because the boolean “not†operator provides a convenient way of flipping
between them.

Wow. You must _really_ value your "convenience" to consider that such an
important issue so as to ignore all the other benefits of avoiding the mixing
of booleans and numerics (especially the classic missing-equals-character bug,
"if (i = 0)...").

You must _really_ hate having to write "i = i > 0 ? 0 : 1" or "i = (i + 1) %
2" or "i = b ? 1 : 0" (where "b" is your beloved toggling boolean value) or
any of the other reasonably concise alternatives that one is forced into using
when you can't index using a boolean value. Those extra half-dozen or so
characters must really kill you.

Why anyone continues to respond to your obvious trolling is beyond me. You
pretend to justify your complaints of the language on the thinnest of
rationales, and yet people are still taking you seriously?

I'll admit it: your troll skills are definitely highly refined. Other than
that? Well…

By the way, the JLS points out, "An integer x can be converted to a boolean,
following the C language convention that any nonzero value is true, by the
expression x!=0. An object reference obj can be converted to a boolean,
following the C language convention that any reference other than null is
true, by the expression obj!=null."

It pays to read the documentation.
 
A

Andreas Leitgeb

Lew said:
It pays to read the documentation.

To me it seemed obvious from his post, that he was pretty well
aware of these idioms, but that he complained about their
necessity.

I'm quite comfortable with Java's restrictive way for conversion
towards boolean, but a bit unhappy about the other direction -
maybe this feeling was triggered by the truely moronic looking
byte code generated for the "bool?1:0" idiom.
 
A

Andreas Leitgeb

Andreas Leitgeb said:
I'm quite comfortable with Java's restrictive way for conversion
towards boolean, but a bit unhappy about the other direction -
maybe this feeling was triggered by the truely moronic looking
byte code generated for the "bool?1:0" idiom.

Btw., in the bytecode, there's nothing to identify a particular
stack-position as having been a boolean, so hotspot doesn't
have the necessary information available to know that:
11: iload_1
12: ifeq 19
15: iconst_1
16: goto 20
19: iconst_0
20: istore_2
is really guaranteed to be equivalent to iload_1,istore_2
 
J

Joshua Cranmer

Btw., in the bytecode, there's nothing to identify a particular
stack-position as having been a boolean, so hotspot doesn't
have the necessary information available to know that:
11: iload_1
12: ifeq 19
15: iconst_1
16: goto 20
19: iconst_0
20: istore_2
is really guaranteed to be equivalent to iload_1,istore_2


Well, to be fair, there is nothing in the JVM that actually guarantees
that true == 1; the typical connotation is that nonzero is true
(extrapolating from C), so this is "safer" than just converting them and
hoping that your true value is actually 1. In any case, I suspect the
JIT would rip all those checks out, so it probably doesn't matter all
that much in terms of performance...

Incidentally, this discussion recalled me of a point noted in another
project I worked on, where people discovered bugs as a result of values
other than 0 and 1 being placed in a boolean variable.
 
A

Andreas Leitgeb

Joshua Cranmer said:
I'm quite comfortable with Java's restrictive way for conversion
towards boolean, but a bit unhappy about the other direction -
maybe this feeling was triggered by the truely moronic looking
byte code generated for the "bool?1:0" idiom.
Btw., [...]
11: iload_1
12: ifeq 19
15: iconst_1
16: goto 20
19: iconst_0
20: istore_2
Well, to be fair, there is nothing in the JVM that actually guarantees
that true == 1; the typical connotation is that nonzero is true [...]
In any case, I suspect the JIT would rip all those checks out,

How could it, when it doesn't even know the concept of "boolean"?
 
J

Joshua Cranmer

Joshua Cranmer said:
I'm quite comfortable with Java's restrictive way for conversion
towards boolean, but a bit unhappy about the other direction -
maybe this feeling was triggered by the truely moronic looking
byte code generated for the "bool?1:0" idiom.
Btw., [...]
11: iload_1
12: ifeq 19
15: iconst_1
16: goto 20
19: iconst_0
20: istore_2
Well, to be fair, there is nothing in the JVM that actually guarantees
that true == 1; the typical connotation is that nonzero is true [...]
In any case, I suspect the JIT would rip all those checks out,

How could it, when it doesn't even know the concept of "boolean"?

Assuming that the JIT does tracing, it can observe that the result of
var1 is always 0 or 1, which would cause the statement to become
equivalent to var2 = var1. From there, it can further do elimination to
remove var2. It's possible, but I do not know if the JVM does it.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,768
Messages
2,569,574
Members
45,048
Latest member
verona

Latest Threads

Top