Poor Man's Genericity?

G

gbmvdd

Is anyone else disappointed with the approach that Java 1.5 has taken
to generic programming? I prefer Java's maturity and openness compared
to C#, but the generic types offered by .NET 2 seem vastly superior to
those offered by Java 1.5. It seems to me that by using erasures, javac
takes all the useful information you've given about the types your code
will use and throws it away. I think having to add the @unchecked
annotation is clunky, and more importantly the compiler is also missing
out on the opportunity to optimise by removing boxing and casts in
collection-related code.

With this in mind, I began to wonder whether Java 1.5 source code could
be compiled in a way similar to .NET 2, so as to be able to take
advantage of the benefits of the latter's approach. I found a paper by
Boris Bokowski and Markus Dahm called "Poor Man's Genericity", but no
remaining Web presence. Can anyone tell me what became of this? Perhaps
it would be possible and useful to adapt it to conform to Java 1.5
syntax.

I suppose the main semantic difference you would get is that
List<int>.class == List<bool>.class in Java 1.5, but that's not the
case if you generate your specialised classes at run-time. To my mind
you actually wouldn't want above expression to be true anyway. Maybe
I've been writing too much C++, so can anyone give me an example where
it's helpful that the types compare equal? Am I missing something, or
is "Poor Man's Genericity" in fact much richer than the genericity Java
has to offer today?

George
 
T

Thomas Hawtin

Is anyone else disappointed with the approach that Java 1.5 has taken
to generic programming? I prefer Java's maturity and openness compared
to C#, but the generic types offered by .NET 2 seem vastly superior to
those offered by Java 1.5. It seems to me that by using erasures, javac
takes all the useful information you've given about the types your code
will use and throws it away. I think having to add the @unchecked
annotation is clunky, and more importantly the compiler is also missing
out on the opportunity to optimise by removing boxing and casts in
collection-related code.

This has been done to death. If you don't want unchecked warnings, write
code that doesn't produce them, rather than attaching a sticking
plaster. Unchecked warning are necessary for code with low-level
optimisations, but that's about it.

Tom Hawtin
 
B

Benji


Well, on the unchecked exceptions front, "I don't like catching exceptions"
is a bad excuse. If you are a *good* programmer, the method of using
caught exceptions is usually a better one in the long run. The problem
is that if you're a bad programmer who doesn't really know what to do when
an exception is caught, sometimes it can result in really bad code - e.g.
try {
...
} catch(Exception e) {}

This is the reason that c# does not have checked exceptions; because of
bad programmers (not good ones). I wouldn't be looking for ways to
dodge caught exceptions. I would be looking for ways to handle exceptions
correctly.
 
G

gbmvdd

Benji said:
Well, on the unchecked exceptions front, "I don't like catching exceptions"
is a bad excuse. If you are a *good* programmer, the method of using
caught exceptions is usually a better one in the long run. The problem
is that if you're a bad programmer who doesn't really know what to do when
an exception is caught, sometimes it can result in really bad code - e.g.
try {
...
} catch(Exception e) {}

This is the reason that c# does not have checked exceptions; because of
bad programmers (not good ones). I wouldn't be looking for ways to
dodge caught exceptions. I would be looking for ways to handle exceptions
correctly.

I completely agree with you. I prefer checked exceptions (and I also
like to think I'm a good programmer). What I was getting at is that
there are situations where you can't avoid getting compiler warnings
because of using generics, other than by marking your method unchecked.
And I don't like that, because I want to write code that doesn't give
compiler warnings and I don't want to mark my methods unchecked!

George
 
P

pkriens

This is quite nonsense ... The reasons C# does not have checked
exceptions is that they learned from Java that checked exceptions are
hard to use.

Exceptions are one of the best inventions in software, but checked
exceptions put the burden of handling the exceptions on the wrong
persons. Most code should just fail (and if necessary cleanup) but NOT
handle the specifics of the exception. The checked exceptions have
caused the deeply nested cause syndrome. In most cases, there is just
NOTHING you can reasonably do with an exception, except passing it to
your caller. When encrypt a file, what can I reasonably do with a file
error? If I log it, I get unnecessarily connected to some log
subsystem, if I print it, it is likely to get lost or frustrates my
caller. So the usual solution is to create a totally unnecessary
EncryptionException that takes another exception. For the caller, the
real cause (the file error) is now hidden. In large systems, the only
interesting exception is often 3 to 5 layers deep.

Exceptions can take the error path away from the main code. Checked
exceptions often cause you to write code that becomes unreadable
because of the try/catch clauses. In my (very long) experience, the
most reliable code is code that handles the exceptions as high as
possible. How often can you really do something useful with an
Exception, except assume failure?

Notice also that checked exception increase the coupling, which is bad.
If a called module would introduce a new checked exception, while
mostof the time I am not really interested in that exception.

Again, exceptions are a great idea. Checked exceptions was a mistake.
They give a false sense of being in control.

Kind regards,

Peter Kriens
 
M

megagurka

pkriens skrev:
This is quite nonsense ... The reasons C# does not have checked
exceptions is that they learned from Java that checked exceptions are
hard to use.

They are hard to use if you don't know how to use them.
Exceptions are one of the best inventions in software, but checked
exceptions put the burden of handling the exceptions on the wrong
persons.

I don't agree.
Most code should just fail (and if necessary cleanup) but NOT
handle the specifics of the exception. The checked exceptions have
caused the deeply nested cause syndrome. In most cases, there is just
NOTHING you can reasonably do with an exception, except passing it to
your caller. When encrypt a file, what can I reasonably do with a file
error?

If you write a function that encrypts a file, you obviously declare
that the function can throw a file error exception. What's wrong with
that?
Exceptions can take the error path away from the main code. Checked
exceptions often cause you to write code that becomes unreadable
because of the try/catch clauses.

So, it's better to not handle the errors that can occur?
In my (very long) experience, the
most reliable code is code that handles the exceptions as high as
possible. How often can you really do something useful with an
Exception, except assume failure?

Don't know what you mean with "assume failure", an exception obviously
indicates failure to perform the requested operation. There are lots of
things you can do when an exception is thrown, for example present the
error to the user requesting the operation, log the error, try some
other operation, rethrow it, ignore the error. The important thing with
checked exceptions is that you are forced to handle the error, and thus
think about what you should do when it occurs.
Notice also that checked exception increase the coupling, which is bad.

Correctly used, it doesn't increase coupling.

/JN
 
C

Chris Uppal

megagurka said:
If you write a function that encrypts a file, you obviously declare
that the function can throw a file error exception. What's wrong with
that?

At a later date you decide that it would be better to compress the file before
encryption (which it often is, provided you strip off any compression headers).
So you add in a compression step. But that can throw errors too. Your design
options are then very limited, and none are appealing:

You can't suppress the compression exception -- obviously.

You can't allow the exception to escape, because that would break the contact
with your callers.

You can wrap your compression error in an /unchecked/ exception and throw that.
I presume you don't like that idea.

Otherwise, about all you /can/ do is try to wrap the compression exception in a
file error exception of some kind. And that's just plain dumb.

If you had thought of it early enough, you could have declared your encryption
routine to throw a (checked) custom error (not a file error) which /contained/
another error. In the early version of the code that would always have been a
file error, in the later version it could also be an encryption error. OK,
fine, that works and is pretty flexible. But then you end up creating hosts of
custom error types for every operation that could conceivably have an error
mode either in its current implementation /or in any future version/. Those
"hosts" of custom error types can be avoided by using a very bland generic
error for everything, but then the you've lost the benefits of declared
exceptions, and most of the benefits of checking them...

That's why quite a few respected observers feel that checked exceptions are
often a bad idea.

-- chris
 
M

megagurka

Chris Uppal skrev:
At a later date you decide that it would be better to compress the file before
encryption (which it often is, provided you strip off any compression headers).
So you add in a compression step. But that can throw errors too.

This is a very contrieved (and badly designed) example, you typically
don't add totally unrelated functionality to an existing function, you
would create a new function that performs compression and encryption.
Besides, a compression algorithm shouldn't usually throw checked
exceptions because it's usually not dependent on an external device, it
will work the same every time given the same input parameters.
If you had thought of it early enough, you could have declared your encryption
routine to throw a (checked) custom error (not a file error) which /contained/
another error. In the early version of the code that would always have been a
file error, in the later version it could also be an encryption error. OK,
fine, that works and is pretty flexible. But then you end up creating hosts of
custom error types for every operation that could conceivably have an error
mode either in its current implementation /or in any future version/.

Of course, if you want forward compatibility you have to design for it.
But this is not unique for checked exceptions, the same applies to
parameters and return values. They are all part of the method
signature.

/JN
 
B

Benji

pkriens said:
This is quite nonsense ... The reasons C# does not have checked
exceptions is that they learned from Java that checked exceptions are
hard to use.

You just said exactly what I said.
possible. How often can you really do something useful with an
Exception, except assume failure?

Error logging, to name one thing. But it depends on the code.
Again, exceptions are a great idea. Checked exceptions was a mistake.
They give a false sense of being in control.

Well, my stated reason for why they chose to only use unchecked exceptions
in c# was an interview that I read with the guy who write the language.
Argue with him. =P
 

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,999
Messages
2,570,247
Members
46,844
Latest member
JudyGvh32

Latest Threads

Top