problems with Java

E

ender

Hi everyone.

Don't get me wrong there are many great reasons to program with Java
but there are also some things that I wonder about. And from what
I've heard the reasoning behind them involves abuse by other
programmers. I do not understand why Sun believes that by denying the
programmer powerful tools they are keeping us "safe". I realize that
many of these tools have been misused by programmers in other
languages but such misuse disadvantages the programmer and if they
don't know what they are doing they shouldn't be using those tools.

The three design decisions that bug me the most all revolve around
data structure. First is the lack of operator overloading. I have
seen many arguments for why operator overloading was not included
however to me operator overloading seems an important part of OOP.
The core of OOP is being able to make customized data types with built
in processing. With operator overloading the user defined types
become much more the primitive types they emulate and can represent
the real world better.

The second thing is that you should have more control over how objects
are passed. Although pass by reference is preferable in most cases
there are many instances when pass by value is required, having to
constantly use clone() is not a very efficient, or safe way. It would
be beneficial to have some form of data type. If a data type is added
however it should not follow the mistake of c# and restrict
inheritance as there are many times when data types should inherit.

The third and most important issue deals with consistency. There is a
huge gap between primitive types and user defined types where there
doesn't need to be. Operator overloading solves much of the problem
and user defined data types more so, but the fact is the primitive
types do not seem OO at all. They do not have any members and they do
not exhibit any polymorphism. They just stick out like a sore thumb.
Furthermore if user defined objects don't have object overloading then
primitive types shouldn't either, and especially not strings. Why
should you have to write fraction1.add(fraction2) for fractions but
not integer1.add(integer2)?

Some other features I would like, but are not quite as sever are
Multiple Inheritance, better support for properties, and some form of
function pointer.

In most cases no more than one class must be inherited from but in
some very specialized instances multiple inheritance is called for.
For example, a square is both a rectangle and a rhombus. However a
rhombus is not a rectangle and a rectangle is not a rhombus. The Java
solution would be to create rhombus and rectangle interfaces and apply
them to the square and to their corresponding rhombus and rectangle
classes. Unfortunately you do not always have access to the classes
you want to inherent. The biggest problem with multiple inheritance
is ambiguity. The best solution I can see is to require specific
implementations of overridden methods when names conflict and
optionally provide an implementation for the current class. (note:
this uses explicit inheritance as used by C#).

The last two are just slight annoences. There is no real need for
these feature other than convenience.
 
M

Mark Rafn

ender said:
I do not understand why Sun believes that by denying the
programmer powerful tools they are keeping us "safe".

Then you've never had to support someone else's code, I suspect. There is not
a direct correspondence between power and abusability, and I fully support
leaving out features that are
1) abused more often than not
2) not a hardship to do without
In almost all cases, features left out of Java have more easily-understood
idioms to get the job done.
First is the lack of operator overloading. I have
seen many arguments for why operator overloading was not included
however to me operator overloading seems an important part of OOP.

I agree with you here. A _LIMITED_ form of operator overloading would make
the language clearer. Something like hardcoded operators, such that
Object has an implementation of
Object operator(Operator, Object)
And operators are just shorthand for calling this method. Override at will.

Simply having == call equals() and a DIFFERENT method for
object identity would save a ton of bugs.
The second thing is that you should have more control over how objects
are passed. Although pass by reference is preferable in most cases
there are many instances when pass by value is required, having to
constantly use clone() is not a very efficient, or safe way.

Here I disagree. Making the Clone() explicit is a fine workaround, and makes
the programmer know what's happening.
It would be beneficial to have some form of data type. If a data type is
added however it should not follow the mistake of c# and restrict
inheritance as there are many times when data types should inherit.

I'm unclear what this means. How is a data type different from a final
immutable object?
The third and most important issue deals with consistency. There is a
huge gap between primitive types and user defined types where there
doesn't need to be.

I don't think anyone disagrees here.
Some other features I would like, but are not quite as sever are
Multiple Inheritance

I'm torn on this. There's a LOT of complexity for not very much power, but
it's a power there's no good workaround for.
better support for properties

Fully agree.
and some form of function pointer.

Disagree. Better syntax for anonymous inner classes, sure. Pure function
pointers aren't needed.
 
M

Matt Humphrey

Mark Rafn said:
....


Disagree. Better syntax for anonymous inner classes, sure. Pure function
pointers aren't needed.

I agree function pointers themselves would be bad, but I would really like
to see C# style delegates and events in Java--I think they're clearer than
having to build up an anonymous inner class just to delegate one method.

Matt Humphrey (e-mail address removed) http://www.iviz.com/
 
L

Lew

ender said:
The second thing is that you should have more control over how objects
are passed. Although pass by reference is preferable in most cases
there are many instances when pass by value is required, having to
constantly use clone() is not a very efficient, or safe way.

Huh? I never use clone(), and Java doesn't pass by reference, it passes by value.

I'm not sure what you are claiming to accomplish, but I am sure there are
Java-idiomatic ways to whatever it is.

-- Lew
 
P

Patricia Shanahan

Lew said:
Huh? I never use clone(), and Java doesn't pass by reference, it passes
by value.

I'm not sure what you are claiming to accomplish, but I am sure there
are Java-idiomatic ways to whatever it is.

Probably give the callee its own copy of the caller's object. If so,
there has to be a copy operation, so I don't see the efficiency issue.

Patricia
 
T

Tom Hawtin

Lew said:
Huh? I never use clone(), and Java doesn't pass by reference, it passes
by value.

Technically it passes references by value, but the effect is to pass a
reference. I think it's splitting hairs, rather than showing anyone's
misunderstanding of the language.

You probably don't use clone, but you do use constructors that copy.
I'm not sure what you are claiming to accomplish, but I am sure there
are Java-idiomatic ways to whatever it is.

I believe what the original poster is referring to is the need to copy
your arguments and return values. There's a bit of a problem, in that
the type doesn't give you enough information. I want to return a Set<K>,
should I make a copy? Well, no, not if the method is keySet(). Suppose I
did make a copy, what implementation should I use? Do I always want to
make a copy, even from private methods? It's a problem, but I think if
you wanted to solve it in the language, there are better ways to go
about it.

Tom Hawtin
 
B

blmblm


[ snip ]
Simply having == call equals() and a DIFFERENT method for
object identity would save a ton of bugs.

Is this mistake really made often by programmers beyond the
beginner stage with Java? If it is, maybe you have a point,
but if it's made mostly be people new to Java, it seems to
me that there are some downsides:

It would further obscure the fact that all non-primitive variables
are references, not objects.

It also would introduce one more way in which references and
primitives are different. As it is now, "x == y" evaluates to
true if variables x and y are equal, and this is true no matter
whether x and y are primitives or references.

And it seems to me that unless you made a similar change to
the assignment operator (so that "x = y" copies the object
contents if x and y are references), again you'd have something
that feels inconsistent. (I haven't thought this part through
very carefully, though.)

[ snip ]
 
M

Mark Rafn

Is this mistake really made often by programmers beyond the
beginner stage with Java?

All the Effing Time! I make it myself annoyingly often, especially when
converting code from some other usage.
It would further obscure the fact that all non-primitive variables
are references, not objects.

If that's a problem, then please just remove all the operators for reference
types. Solved!
It also would introduce one more way in which references and
primitives are different.

You misspelled "the same".
As it is now, "x == y" evaluates to true if variables x and y are equal

Wrong. It evaluates to true if they are the same value or reference. If
they're different objects in memory, but are equal(), == returns false.
 
M

Mark Thornton

Mark said:
Wrong. It evaluates to true if they are the same value or reference. If
they're different objects in memory, but are equal(), == returns false.

There is also the curious fact that Float.NaN == Float.NaN returns false
(and the same is true of Double.NaN)!

Mark Thornton
 
L

Lew

Mark said:
There is also the curious fact that Float.NaN == Float.NaN returns false
(and the same is true of Double.NaN)!

That has absolutely nothing to do with operator overloading but with the
definition of NaN.

Pop quiz: is Float.Nan a reference?

-- Lew
 
L

Lew

Mark said:
There is also the curious fact that Float.NaN == Float.NaN returns false
(and the same is true of Double.NaN)!

That has absolutely nothing to do with operator overloading but with the
definition of NaN.

Pop quiz: is Float.NaN a reference?

-- Lew
 
B

blmblm

All the Effing Time! I make it myself annoyingly often, especially when
converting code from some other usage.

Huh. I can easily imagine this being a problem if "from some other
usage" means "from some other language". Otherwise, I guess your
mileage varies, as they say, because I'm pretty sure I don't make
this mistake, and I'd call myself an intermediate-level (not expert)
Java programmer. No offense meant. People differ.
If that's a problem, then please just remove all the operators for reference
types. Solved!

I dunno. If x and y are references, how would you express the idea
currently expressed as "x == y"? Writing "x.anything" doesn't really
seem to me to make sense, because the "." means you're doing something
to the object pointed to by x, not to x, no?
You misspelled "the same".


Wrong. It evaluates to true if they are the same value or reference. If
they're different objects in memory, but are equal(), == returns false.

My point is that x and y are *NOT* objects in memory, they are
*references to* objects in memory. To me it makes perfect sense that
if x and y are references, "x == y" is true if x and y point to the
same object -- what else should equality mean, for references? --
and that if one wants to compare the contents of the objects pointed
to, one needs another syntax. You apparently have some other view,
which I'm not able to get my head around, and maybe we should leave
it at that.
 
B

blmblm

That has absolutely nothing to do with operator overloading but with the
definition of NaN.

Pop quiz: is Float.NaN a reference?

Indeed. It's a little counterintuitive, maybe, that NaN != NaN,
but that appears to be what the IEEE standard for floating-point
numbers requires.
 
E

ender

I'm unclear what this means. How is a data type different from a final
immutable object?


By data type I am refering to a C# style struct, a type that is always
passed by value. However this is ever implemented data types should
always be accompanied by a reference wrapper similar to the wrappers
for similar types. A n but in most cases an imutable type will work
fine. This was just my solution to passing by value.
 
L

Lew

ender said:
By data type I am refering to a C# style struct, a type that is always
passed by value. However this is ever implemented data types should
always be accompanied by a reference wrapper similar to the wrappers
for similar types. A n but in most cases an imutable type will work
fine. This was just my solution to passing by value.

All Java variables that point to objects are references, which in turn are
passed by value to methods. Objects live on the heap, never on the stack.
Objects /per se/ are never passed as method parameters.

The sentence "data types should always be accompanied by a reference wrapper"
makes no sense with the generally-accepted definition of "data type" (the type
of the data) - a "data type" would not be accompanied by another type,
although an object might be accompanied by another object.

An immutable type is a data type, as is an immutable one. A reference would
be of a particular data type. Passing a reference (by value) to either a
mutable or immutable object is still passing a reference of that type. The
notion of "data type" is orthogonal to whether an object is passed by value,
as in the C constellation, or by reference, as can happen in C++ / #, or by
value of the reference, as in Java.

That said, I do not understand the point you were making about immutable vs.
mutable types. I do understand that the question of passing by value is moot,
as all non-primitive Java variables are references and references are always
passed by value in Java. I do not understand how that requires a "solution".
It isn't a problem to begin with.

-- Lew
 
?

=?ISO-8859-1?Q?Arne_Vajh=F8j?=

Mark said:
There is also the curious fact that Float.NaN == Float.NaN returns false
(and the same is true of Double.NaN)!

That is what IEEE mandate.

And I think it make sense.

NULL=NULL return false in SQL too.

Arne
 
T

Tom Hawtin

Arne said:
That is what IEEE mandate.

And I think it make sense.

NULL=NULL return false in SQL too.

IIRC, NULL=NULL IS UNKNOWN in SQL. Does that make sense? I don't know.

Tom Hawtin
 
?

=?ISO-8859-1?Q?Arne_Vajh=F8j?=

Tom said:
IIRC, NULL=NULL IS UNKNOWN in SQL. Does that make sense? I don't know.

Sorry. I forgot they have some extra finesse.

"NULL=NULL does not return true in SQL"

Arne
 
L

Lew

Sorry. I forgot they have some extra finesse.

"NULL=NULL does not return true in SQL"

It makes perfect sense. SQL embodies a consistent 3-valued logic, with NULL as
the cognate for UNKNOWN. (UNKNOWN = UNKNOWN) must be UNKNOWN. (UNKNOWN = x)
must be UNKNOWN. (UNKNOWN AND x) must be UNKNOWN. (UNKNOWN OR x) must be
UNKNOWN. (where x is one of {FALSE, TRUE, UNKNOWN})

(The SQL standard apparently permits use of the literal UNKNOWN as a synonym
for NULL.)
 
E

Esmond Pitt

ender said:
By data type I am refering to a C# style struct, a type that is always
passed by value.

Can we please stick to standard terminology? That is is a completely
non-standard use of the term 'data type'. Practically everyone in CS
would understand that to mean e.g. a class.
 

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,770
Messages
2,569,584
Members
45,075
Latest member
MakersCBDBloodSupport

Latest Threads

Top