Generics - good, bad or indifferent?

T

TechBookReport

Does anybody have a good word to say about generics in J2SE 5.0? I can't
help thinking it's a sledgehammer to crack a nut. Casting into and out
of collections wasn't such a big deal. Sure type-safety is important,
but the implementation is intrusive and ugly (aesthetics seem important
to me). If anything surely the class cast problem is something that
intelligent tools like Eclipse or NetBeans could have solved without
resorting to language changes. Particularly as erasure means that it's
only at compile time that generics provide a benefit.

Am I missing something or did we just add complications to the language
for little real benefit?

Pan
 
I

iamfractal

TechBookReport skrev:
Does anybody have a good word to say about generics in J2SE 5.0? I can't
help thinking it's a sledgehammer to crack a nut. Casting into and out
of collections wasn't such a big deal. Sure type-safety is important,
but the implementation is intrusive and ugly (aesthetics seem important
to me). If anything surely the class cast problem is something that
intelligent tools like Eclipse or NetBeans could have solved without
resorting to language changes. Particularly as erasure means that it's
only at compile time that generics provide a benefit.

Am I missing something or did we just add complications to the language
for little real benefit?

Pan

"Intrusive and ugly," seems rather strong. I'm just glad that they used
the angle brackets that C++ already uses for templating; no point in
re-inventing a symbol when there's already heritage.

And as for generics being part of the language, well, yes you have to
know them in case you're using code that uses them, but they are still
optional for your own, original work. Generics should be used when the
following two conditions hold:
A) There are a significant number of casting errors caused by mxing
types in collections.
B) Identifying the errors introduced in (A) is significantly
time-consuming.

..ed
 
M

megagurka

TechBookReport skrev:
Does anybody have a good word to say about generics in J2SE 5.0? I can't
help thinking it's a sledgehammer to crack a nut. Casting into and out
of collections wasn't such a big deal. Sure type-safety is important,
but the implementation is intrusive and ugly (aesthetics seem important
to me). If anything surely the class cast problem is something that
intelligent tools like Eclipse or NetBeans could have solved without
resorting to language changes. Particularly as erasure means that it's
only at compile time that generics provide a benefit.

Am I missing something or did we just add complications to the language
for little real benefit?

The benefit is big. Genericity is a fundamental building block of a
type safe programming language (which, I hope, Java is meant to be), so
generic types and methods should have been included in Java from day
one. The implementation, as you mention, is lacking. Not changing the
JVM to support generic types was a mistake and the cost of this mistake
will only increase with time until it's rectified. The .NET
implementation of generics has VM support, which is a big plus, but the
implementation of type contraints is better in the Java version.

The awkwardness of using generic types could be mitigated by
introducing type inference of field and local variable types, for
example:

let v = new Vector<Point<Integer>>();

which would be equivalent to:

Vector<Point<Integer>> v = new Vector<Point<Integer>>();

Replace "let" with your favourite keyword. Maybe this could be filed as
an RFE, if it hasn't been already. It probably won't be approved,
because the Sun engineers are probably busy implementing the XML
language syntax. *shiver*

/Jesper Nordenberg
 
C

Chris Uppal

TechBookReport said:
Am I missing something or did we just add complications to the language
for little real benefit?

That's my opinion.

The benefits gained are two-fold. We significantly reduce (but not eliminate)
the risk of casting errors. We gain better self-documentation of the code.

The first of these is (IMO) completely negligible. It just wasn't worth the
effort. It doesn't even justify the small effort of typing in the <>s. Let
alone the massive complications to the javac implementation; to the java
specification (which is now essentially unreadable, while it /used/ to be a
valuable resource); and to all Java-aware tools such as Eclipse. (Just think
what valuable improvements to Eclipse we are missing because the programmers'
time was spent on the changes needed to support generics -- and God knows,
Eclipse could do with a bit of improvement...)

The second is (IMO) a lot more valuable. Certainly I'd rather know that some
method answers a List<Point> than just a List. However, when you factor in the
"wildcard" notation, the generic type definitions quickly become unreadable.
And, in my limited experience, so far, that happens more often than not. So
you end up ignoring the spec, and assuming that it's "correct" and does in fact
mean what logic and experience suggest it /should/ mean. So the documentary
value is compromised.

I think they blew it.

-- chris
 
O

Oliver Wong

Chris Uppal said:
TechBookReport said:
Am I missing something or did we just add complications to the language
for little real benefit?

That's my opinion.

The benefits gained are two-fold. We significantly reduce (but not
eliminate)
the risk of casting errors. We gain better self-documentation of the
code.
[...]

The second is (IMO) a lot more valuable.

Strongly agreed. We've got multiple programmer working on this project
where collections (e.g. Vector, ArrayList, etc.) are being passed around a
lot. Prior to generics, someone would write code that puts stuff into a
Vector, and someone else would write code that gets the stuff out of the
Vector.

Once we had generics, we decided to actually document what the Vector
contains (i.e. change Vector to Vector<String>). This generated quite a few
compilation errors because apparently there was some miscommunication going
around as to what actually belonged in a given collection.

What generics does is takes some of the runtime errors (mainly casting
errors), and changes them to compilation errors, and that's usually a good
thing.

The concept of generics itself is good, but it's implementation in Java
isn't all that great. As megagurka mentioned, Sun really should have
modified the JVM so that the type information isn't erased at runtime. As it
stands now, generic feels like a feature hacked onto Java rather than part
of the original design (probably because that's exactly what happened).

- Oliver
 
T

Thomas Hawtin

TechBookReport said:
Does anybody have a good word to say about generics in J2SE 5.0?

It appears that most of those spouting off about the evilness of
generics are dynamic typing fans. If you don't like static typing, then
you aren't going to want more of it. If you do like static typing, it
might as well be done properly.
I can't
help thinking it's a sledgehammer to crack a nut. Casting into and out
of collections wasn't such a big deal.

No it's not a big deal. Although it is ugly, tends to lead to
unnecessary code and the source is complicated precisely where you want
it as simple as possible.
Sure type-safety is important,
but the implementation is intrusive and ugly (aesthetics seem important
to me). If anything surely the class cast problem is something that
intelligent tools like Eclipse or NetBeans could have solved without
resorting to language changes.

ClassCastException is a red herring. Searching through the Bug Parade
brings up seven times more bugs with NullPointerException than
ClassCastException.
Particularly as erasure means that it's
only at compile time that generics provide a benefit.

Given that we have such good static type checking, runtime type checking
is an obscure feature. Having said that, as 1.4- isn't targeted, I would
have preferred a JVM level implementation, particularly for covariant
return types (which still have outstanding bugs).

It's not a valid criticism coming at it from a dynamic typing point of
view, anyway. You can't, as I understand it, take a Smalltalk collection
and ask what shapes will all its contents, past and future, will conform to.



The real issue, assuming you welcome static typing into your life, is
documentation. It's much easier to understand what is in Set<EmployeeID>
than Set with the element type hidden amongst the JavaDocs if at all and
if kept in sync.

For instance, modifying a JRoller Velocity template, many of the methods
return Lists. But the documentation (often) doesn't (didn't) say what
they contain. I've inherited code that accidentally used the same map
for two different mappings. That only became apparent because, coming
from C++, I used to put type information within /*< >*/.

I find JavaDoc Use pages useful in understanding how a piece of code
fits together. In olden days, if you didn't use arrays, you didn't get
to see a lot of important relationships. In one case, I was witting the
public API documentation to a product and wrote in on the type
description the missing uses. Shortly after that the PSE changed the
Collections to arrays. But really, we would like to encourage the use of
interfaces over nasty arrays.

While some people coming to generics might find them confusing, if they
push their minds back far enough, they probably found polymorphism
confusing too. They are essentially the same thing, just with a layer of
indirection. Perhaps it will take a while for texts to become stable.

Tom Hawtin
 
R

Roedy Green

Once we had generics, we decided to actually document what the Vector
contains (i.e. change Vector to Vector<String>). This generated quite a few
compilation errors because apparently there was some miscommunication going
around as to what actually belonged in a given collection.

But then people work very hard to hide that information again in the
declaration and put it only in the constructor to help restore the
confusion. This is considered the adult way to program.
 
R

Roedy Green

It appears that most of those spouting off about the evilness of
generics are dynamic typing fans.

I think the reasons are more the complexity of the code required for a
fairly trivial end, and the way type erasure causes so much code that
makes perfect sense to humans, not legal.

It is a implementation driven syntax.
 
O

Oliver Wong

Larry Barowski said:
Using the angle brackets in this way added a lot of mess to
the language grammar (because, for one thing, <x <y <x>>> ,
<x <y <z>> > , <x <y <z> >> , and <x <y <z> > > are
four different token sequences that all mean the same thing).

To me, this is like complaing the following 4 lines are 4 different
token sequences that all mean the same thing (note I'm assuming your first
example is a typo and the second x should be a z):

<4tokenSequences>
int x;
int x;
int x;
int x;
Some priority must be given to keeping the grammar clean
and keeping a good separation between grammar and
lexical specification. Of course, there are only so many
available symbols, and I can't think of a symbol pair that
would look good and lead to a clean grammar. <#x<#y#>#>
just doesn't look right.

Because you can nest generic type information, you need an a pair of
symbols: an "open" symnol and a "close" symbol. With ASCII, you're pretty
much restricted to one of the four (), [], {} or <> (any other pair, e.g. $%
or ~/, would probably look unnatural), and of those 4, <> really does seem
like the least confusing one to use.

- Oliver
 
T

Thomas Hawtin

Oliver said:
Using the angle brackets in this way added a lot of mess to
the language grammar (because, for one thing, <x <y <x>>> ,
<x <y <z>> > , <x <y <z> >> , and <x <y <z> > > are
four different token sequences that all mean the same thing).


To me, this is like complaing the following 4 lines are 4 different
token sequences that all mean the same thing (note I'm assuming your first
example is a typo and the second x should be a z):[/QUOTE]

To the programmer, yes (so long as they aren't a C++ programmer). To the
lexer, >> and >>> is shift arithmetic and logical shift right operators.
The lexer needs to be fudged so that it returns a series of individual
symbols if the grammar state is within a generic declaration.
Because you can nest generic type information, you need an a pair of
symbols: an "open" symnol and a "close" symbol. With ASCII, you're pretty
much restricted to one of the four (), [], {} or <> (any other pair, e.g. $%
or ~/, would probably look unnatural), and of those 4, <> really does seem
like the least confusing one to use.

You can naturally nest " and ', as INTERCAL does. Also Java uses
Unicode, so it wouldn't be too awful to use other symbols. Might make
some poor character set handling clean up its act.

Tom Hawtin
 
L

Larry Barowski

"Intrusive and ugly," seems rather strong. I'm just glad that they used
the angle brackets that C++ already uses for templating; no point in
re-inventing a symbol when there's already heritage.

Using the angle brackets in this way added a lot of mess to
the language grammar (because, for one thing, <x <y <x>>> ,
<x <y <z>> > , <x <y <z> >> , and <x <y <z> > > are
four different token sequences that all mean the same thing).
Some priority must be given to keeping the grammar clean
and keeping a good separation between grammar and
lexical specification. Of course, there are only so many
available symbols, and I can't think of a symbol pair that
would look good and lead to a clean grammar. <#x<#y#>#>
just doesn't look right.
 
B

Bent C Dalager

You can naturally nest " and ', as INTERCAL does.

Now, that's a first: "That's how INTERCAL does it" used as an argument
in favour of a feature :)

Cheers
Bent D
 
L

Larry Barowski

Oliver Wong said:
To me, this is like complaing the following 4 lines are 4 different
token sequences that all mean the same thing (note I'm assuming your first
example is a typo and the second x should be a z):

<4tokenSequences>
int x;
int x;
int x;
int x;
</4tokenSequences>

Those are 4 identical token sequences.
 
L

Larry Barowski

Thomas Hawtin said:
To the programmer, yes (so long as they aren't a C++ programmer). To the
lexer, >> and >>> is shift arithmetic and logical shift right operators.
The lexer needs to be fudged so that it returns a series of individual
symbols if the grammar state is within a generic declaration.

That kind of parser-lexer interaction makes me queasy.
Sun provided a grammar solution, but it isn't pretty.
Humans will naturally interpret the generics grammar as
a lexer state change, so the fact that there is a grammar
solution isn't entirely satisfying.
 
C

Chris Stiles

Roedy Green said:
I think the reasons are more the complexity of the code required for a
fairly trivial end, and the way type erasure causes so much code that
makes perfect sense to humans, not legal.

It is a implementation driven syntax.

One implementation detail that I'm not clear about. Both javac and
JDTCompiler appear to allow inner classes inside generics. However javac will
barf over use of the unqualified inner class name inside the generic in which
it is declared, JDTCompiler appears not to.
 
T

Tor Iver Wilhelmsen

TechBookReport said:
Does anybody have a good word to say about generics in J2SE 5.0?

They allow even more errors to be caught at compile time.
Casting into and out of collections wasn't such a big deal.

Nor is catching Exception instead of specific exceptions. But it's
still bad practice compared to the alternative.
Sure type-safety is important, but the implementation is intrusive
and ugly (aesthetics seem important to me).

No, it doesn't, otherwise you would be using a good-looking language
like Eiffel or Smalltalk instead of *any* member of the fugly C
family.
If anything surely the class cast problem is something that
intelligent tools like Eclipse or NetBeans could have solved without
resorting to language changes.

You want to make IDE-dependent languages? I thought that idea died
with Smalltalk?
Particularly as erasure means that it's only at compile time that
generics provide a benefit.

And that is good enough reason to have it.
 
I

Ian Pilcher

Roedy said:
I think the reasons are more the complexity of the code required for a
fairly trivial end, and the way type erasure causes so much code that
makes perfect sense to humans, not legal.

The latter reason is certainly my biggest frustration. I actually think
that parameterized types are a big forward ... theoretically. The
current implementation, however, verges on being unusable.

<rant>
The current state of the Java compiler is a travesty. I can't figure
out how Sun thinks its acceptable that there is no way to, for example,
create an array of parameterized objects without generating a warning.
Tiger is feeling a lot like an extended beta test for Mustang.
</rant>
 
S

Stefan Ram

Ian Pilcher said:
how Sun thinks its acceptable that there is no way to, for
example, create an array of parameterized objects without
generating a warning.

What is a parameterized object?
 
T

Thomas Hawtin

Ian said:
<rant>
The current state of the Java compiler is a travesty. I can't figure
out how Sun thinks its acceptable that there is no way to, for example,
create an array of parameterized objects without generating a warning.

The problem there is arrays. It's arrays that should be avoided. In the
same way you prefer String/StringBuilder over char[], you should prefer
Tiger is feeling a lot like an extended beta test for Mustang.
</rant>

Perhaps Mustnag will fix a few bugs, but don't expect language changes.

Tom Hawtin
 

Members online

No members online now.

Forum statistics

Threads
473,756
Messages
2,569,535
Members
45,008
Latest member
obedient dusk

Latest Threads

Top