Java’s Broken Booleans

  • Thread starter Lawrence D'Oliveiro
  • Start date
L

Lew

Peter said:
So?  That's only because Java doesn't have object-oriented primitives.

So, you have to be aware of that.
For all intents and purposes, Boolean and boolean are equivalent.

Not true. For *some* intents and purposes they are equivalent. For
the intent and purpose of ordering, they are not equivalent.
Therefore they are not equivalent for all intents and purposes.
Q.E.D.

Anyone who wants to order their booleans can just use Booleans in their
stead.

They will have to something, that or something else, because they
can't order 'boolean's without special work, such as boxing them into
'Boolean's.
 
A

Andreas Leitgeb

Lew said:
Not true. For *some* intents and purposes they are equivalent. For
the intent and purpose of ordering, they are not equivalent.

For the intent of three-valued logic, they're not equivalent,
either: boolean=true|false, Boolean=TRUE|FALSE|null
Therefore they are not equivalent for all intents and purposes.
Q.E.D.
yep
 
J

Jim Janney

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.

In Pascal booleans are a predefined enumerated type

type boolean = (false, true);

and thus have the same characteristics as any other Pascal enumerated
type: ordering, the ord, next, and prev functions, and the ability to
act as an array index. I consider these to be more artifacts of the
language definition than anything the working programmer is likely to
use regularly.

For better or worse, enums weren't part of the original definition of
Java, so defining booleans as enums wasn't an option.
 
L

Lew

Andreas said:
For the intent of three-valued logic, they're not equivalent,
either: boolean=true|false, Boolean=TRUE|FALSE|null

Andreas said:

For the intent and purpose of a base type for a collection or other
generic class or method they are not equivalent. For the intent and
purpose of upcasting, say to 'Comparable' or 'Serializable', they are
not equivalent. For the intent and purpose of reflective operations
they are not equivalent. For the intent and purpose of extracting the
value from a variable they are not equivalent.

Come to think of it, I cannot think of one intent or purpose for which
they are equivalent. They don't even have the same value domain, as
Andreas showed! Maybe we're dealing with a Humpty-Dumpty definition
of "equivalent" as "hardly at all similar".
 
L

Lew

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.

In Pascal booleans are a predefined enumerated type

   type boolean = (false, true);

and thus have the same characteristics as any other Pascal enumerated
type: ordering, the ord, next, and prev functions, and the ability to
act as an array index.  I consider these to be more artifacts of the
language definition than anything the working programmer is likely to
use regularly.

For better or worse, enums weren't part of the original definition of
Java, so defining booleans as enums wasn't an option.

But type-safe enumerations were available, so defining 'boolean' as a
type-safe enumeration was an option, one which Java eschewed. No
doubt they would have done the same had 'enum' been part of the
language, since after all it's merely syntactic sugar for a particular
kind of 'class' declaration.

Otherwise we'd've had expressions like 'if ( Boolenum.TRUE ) { ... }',
which would've required special handling so that 'if ( Color.RED )'
would be rejected. So a boolean 'enum' would still be fundamentally
different from other classes. That'd be no better than what we have
now.

I conclude that 'enum' would never have been an option to implement
'boolean' for Java. At best it would've been an option to implement
'Boolean', but that would not differ significantly from what we have
now.
 
A

Andreas Leitgeb

Lew said:
In Pascal booleans are a predefined enumerated type
   type boolean = (false, true);
[...]
For better or worse, enums weren't part of the original definition of
Java, so defining booleans as enums wasn't an option.
But type-safe enumerations were available, so defining 'boolean' as a
type-safe enumeration was an option, one which Java eschewed.

huh? What pre-"enum" feature of Java are you referring to?
 
L

Lew

Andreas said:
huh?  What pre-"enum" feature of Java are you referring to?

Classes.

See /Effective Java/, 1st edition. 'enum' is syntactic sugar for a
regular class with specially-defined 'public static final' member
constants. Of course, hand-rolled type-safe enumerations lack
language support for things like 'switch' values, but they provided
the major benefits of 'enum's otherwise.
 
A

Andreas Leitgeb

Lew said:

Ah, ok, just thought I missed something in the primitives-domain.

PS: your attribution style is ... "sub-ideal". Not so much for
moving the attribution line to the respective paragraph (which is
quite ok), but for not correctly ">"-indenting them.
In Usenet something like
implicitly means, that Xyz quoted someone who quoted someone who
quoted someone who wrote "bla bla", not that Xyz himself wrote it.
 
A

Arne Vajhøj

But type-safe enumerations were available, so defining 'boolean' as a
type-safe enumeration was an option, one which Java eschewed. No
doubt they would have done the same had 'enum' been part of the
language, since after all it's merely syntactic sugar for a particular
kind of 'class' declaration.

Note that this does not give ordering!

Arne
 
A

Arne Vajhøj

Lew said:
In Pascal booleans are a predefined enumerated type
type boolean = (false, true);
[...]
For better or worse, enums weren't part of the original definition of
Java, so defining booleans as enums wasn't an option.
But type-safe enumerations were available, so defining 'boolean' as a
type-safe enumeration was an option, one which Java eschewed.

huh? What pre-"enum" feature of Java are you referring to?

Joshua Bloch described a mechanism in his book Effective Java
1st edition, which he then obsoleted in Java 1.5 by
introducing the enum syntactic sugar for the same solution.

Arne
 
A

Arne Vajhøj

Not true. For *some* intents and purposes they are equivalent. For
the intent and purpose of ordering, they are not equivalent.
Therefore they are not equivalent for all intents and purposes.
Q.E.D.

Not very much D in that.

Arne
 
A

Arne Vajhøj

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.

If one does not like the ?: operator then just use if
statement.

Arne
 
A

Arne Vajhøj

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?

In general allowing array index to be of a type with only
the valid values is good for the reliability of the program,
because it converts runtime errors to compile time errors.

Allowing those values to be the natural values for the
problem domain makes the program more readable.

Pascal/Modula-2/Ada is pretty good in that regard.

Java chose a different route.

Arne
 
L

Lew

Peter said:
First try:

boolean[] values = new boolean[10];

// init values

// oops, how do I sort these?

Second try:

Boolean[] values = new Boolean[10];

// init values

// cool. I can call compareTo()

Yes, that's what I said.
I don't think it's really that hard to change the lower-case b to an
upper-case B when you decide you need an ordering on your true/false values.

But, if you do think that's a huge problem to use Boolean instead of boolean,
then you really ought to look into those fancy reified generics. That way you
can put booleans into your generic types instead of Booleans, since the latter
is such a problem.

Whom are you addressing with that "you"?

I for one do not find it a huge problem to use Boolean where it's useful.

The post to which I was replying referred to, "being able to order things by a
boolean in a simple way (i.e. by just sorting them)". I was simply pointing
out that in Java, the ordering would be on Boolean, since boolean doesn't
support ordering.
 
J

Jim Janney

Peter Duniho said:
The ordering is on 'Boolean', not 'boolean'.

First try:

boolean[] values = new boolean[10];

// init values

// oops, how do I sort these?

For sorting booleans I prefer to use a custom algorithm that runs in
O(n) time :)
 
A

Arved Sandstrom

That is an excellent proposal. But some people are apparently more
concerned with a generalized solution. :p

(And in any case, if the boolean value is but one of a group of
properties that are participating in the sort, I think having a
readily-available compareTo() method is handy).

Handy being the operative word. I hope that nobody using the capability
actually starts thinking that Booleans have a natural ordering.

For my part I use Boolean compareTo when having to sort result sets in
JSF/JPA scenarios, where a Boolean sort column is involved. Neither JPA
1.0 (JSR 220) nor JPA 2.0 (JSR 317) officially support MIN/MAX/ORDER BY
in JPQL for anything other than numeric/string/character/date types. Yet
it's not uncommon to want to sort on a column which is naturally
Boolean. Although many JPA persistence providers do add an enhanced JPQL
capability to do this (e.g. EclipseLink 2.x, but not EclipseLink 1.x),
if you happen to be using a version that doesn't then a Collections.sort
Comparator that incorporates Boolean compareTo is definitely handy - not
necessary, but handy. (*)

AHS

* This problem is a non-issue if using (a) a later version persistence
provider (mileage varies), (b) persistence provider native expressions
APIs, and (c) JPA 2.0 Criteria API (I think).
 
I

Ian Shef

On 15-02-2011 07:48, Andreas Leitgeb wrote:

If one does not like the ?: operator then just use if
statement.

Arne

Try doing this with an if statement:



public class ExampleSub extends Example {
ExampleSub() {
super((System.currentTimeMillis()&1)==0?"Even":"Odd");
}
}

class Example {
String s;
Example(String t) {
s = t;
}
}



A static method or a static factory might be preferable, but this is an
example where ?: cannot easily be transformed into an if statement.

The ugliness of this example may even be an argument to shun the ?: operator.
 
L

Lew

Try doing this with an if statement:

public class ExampleSub extends Example {
  ExampleSub() {
    super((System.currentTimeMillis()&1)==0?"Even":"Odd");
    }

}

class Example {
  String s;
  Example(String t) {
    s = t;
  }

}

A static method or a static factory might be preferable, but this is an
example where ?: cannot easily be transformed into an if statement.

The ugliness of this example may even be an argument to shun the ?: operator.

I see an argument in favor of its use here. I don't see how the
evidence you provided points to shunning it at all.
 
A

Andreas Leitgeb

Lew said:
I see an argument in favor of its use here. I don't see how the
evidence you provided points to shunning it at all.

This subthread is bogus anyway. If I dislike the ?: operator
in the specific context of boolean->(0,1) conversion, for it's
introduction of conditional jumps, then suggesting "if" cannot
be taken seriously, can it?
 
I

Ian Shef

opera
tor.

I see an argument in favor of its use here. I don't see how the
evidence you provided points to shunning it at all.

The argument to super(...) could be a call to a static method. A static
method can be used to handle this case (with ?: or with "if") and can
handle much more complex cases where an expression is insufficient. Since
a static method can handle the general case and (if properly written) can
be quite clear, it should be the accepted idiom for handling such
situations. The availability of ?: encourages an alternate solution that
may be unclear (especially if one starts nesting ?: with ?: ) and that may
be a dead end if the expression becomes too complex.

Several expert authors encourage providing static factories and preventing
the use of "new" (e.g. by making constructors private). Static factories
also provide a general solution without requiring the use of ?: . The
existence of ?: , while a convenient shortcut sometimes, could be viewed as
encouraging poor coding practices.

In any case, I have drifted from the original thread. I suggest: If you
like ?: , go ahead and use it. Just be judicious.
 

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

No members online now.

Forum statistics

Threads
473,774
Messages
2,569,599
Members
45,175
Latest member
Vinay Kumar_ Nevatia
Top