Java Solaris Communities Sun Store Join SDN My Profile Why Join?
 
Bug Database
Bug Detail
Quick Lists
Top 25 Bugs
Top 25 RFE's
Recently Closed Bugs
Printable Page Printable Page


Bug Database
Bug ID: 4064105
Votes 0
Synopsis Compile-time type safety with generics (JSR-014)
Category java:specification
Reported Against 1.2 , 1.3 , 1.1.3 , 1.2.2 , 1.2beta2 , 1.2beta4 , merlin-beta
Release Fixed 1.5(tiger-beta2)
State 10-Fix Delivered, request for enhancement
Priority: 2-High
Related Bugs 4173702 , 4345822 , 4923161 , 4847959
Submit Date 11-JUL-1997
Description
Request for parameterized types. An initiative to do just this is in
progress. See 
http://www.jcp.org/jsr/detail/14.jsp


 xxxxx@xxxxx  1999-05-03
 xxxxx@xxxxx  2001-11-21

Request inclusion of JSR 014:  Add Generic Types To The Java Programming Language into J2SE 1.5 

The JSR proposal is to add generic types and methods to the Java programming
language.  The main benefit of adding genericity to the Java
programming language lies in the added expressiveness and compile-time
type safety that stems from making type parameters explicit and making
type casts implicit. This is crucial for using libraries such as
collections in a flexible, yet safe way.  The proposed extension is
designed to be fully backwards compatible with the current language,
making the transition from non-generic to generic programming very
easy. In particular, one can retrofit existing library classes with
generic interfaces without changing their code.

This is an updated description the previous description is in the comments field
Work Around





======================================================================

    Don't use built in collection classes (e.g. Vector) directly.  Make
your own correctly typed container classes that delegate to a private generic
container (e.g. Vectork, Hashtable).  This is not a terribly satisfying or efficient solution, but it's the best one can do until the language
supports some sort of parameterized classes.


 xxxxx@xxxxx  1997-07-15





A preprocesor (a la C++)
======================================================================
Evaluation
Sure. We are examining the possibility of adding parameterized types.

 xxxxx@xxxxx  1997-11-12

   I believe that a clean, simple parameterized typing facility (along the
lines of http://www.cs.bell-labs.com/who/wadler/pizza/gj/index.html )
would represent a fine addition to the language, especially when combined with
the 1.2 collections facility.

 xxxxx@xxxxx  1998-09-16


Parameterization can indeed be very useful.  In considering the various
proposals, we are particularly concerned about the impact of such a
large change on our customers, especially with respect to compatibility
and stability.

The investigation of our options is ongoing.

==============================

Generics will be available in Tiger beginning with build 14.
See 4607354 for the compiler changes.
A number of other bugIDs relate to API changes.

 xxxxx@xxxxx  2003-07-30
Comments
  
  Include a link with my name & email   

Submitted On 05-MAR-1998
HolgerK
The pizza language extension provides parameterized
classes und runs nicely in the JRE.
<a href="http://wwwipd.ira.uka.de/~pizza/">Take a
look</a>


Submitted On 14-MAY-1998
cd_smith
I'm not sure what Eiffel's "bounded" genericity is, so this may be a
repeat of ldwg's comments.
Please don't do the C++ hack where I can write a templatized method that calls
methods on an object when they may or may not be there.  A parameterizable
class should declare some kind of minimal interface or class that needs to be
extended/implemented by the actual used class.  Thus, current java.util classes
would declare themselves as parameterized on class Object, whereas I may
require that all objects in my new collection implement Cloneable (because some
operation in my collection requires that I clone them).  It could, of course,
use the class to create a collection of a more specific type when I use it.
More usefully, I could create a collection which requires that elements
implement my own interface of advanced things I need to do.
As long as this requirement were fulfilled, I could support templates in Java. 
If not, I'd rather have to downcast.


Submitted On 14-MAY-1998
ldwg
Generic classes with bound genericity (not the unbound version of C++ but
in the sense of Eiffel) is the most important feature I really miss in Java.
(Bound) generic classes would
<OL>
<LI>tremendously decrease the "conceptual overhead", because
you would not
    have to create a new interface for your XYZVector but would reuse a
    Vector(XYZ) instead.
<LI>increase performance, because many dynamic type checks during
downcasts
    become redundant (as in "a = (XYZ)myEnumerator.nextElement()")
<LI>increase type-safety, because you could rely on the fact that a
    Vector(XYZ) contains only objects which grant you the interface XYZ.
</OL>
The pizza language does provide generic classes (and other niceties like
high order functions) but it translates those constructs to plain bytecode
using the aforementioned design pattern with specialized subclasses and
downcasts. It therefore does not gain performance and does not provide
genuine type-safety if no source code is available --- after distribution
you cannot guarantee that ordinary objects are added to your Vector(XYZ)
which has been translated to a XYZVector still containing the inhomogeneous
methods to add/remove Objects. These inhomogeneous inherited methods could
be used by an application and would not be prohibited by the compiler.
What we really need is a byte code level solution. I think it is possible
to design the generics such that the old API remains source code compatible
if an omitted parameter is automatically set to the upper bound
(so "Vector" is Vector(Object)).


Submitted On 21-MAY-1998
jdmarshall
I think a good starting place for an implementation
of this would be to define a new data type that
corresponds to the parameterized type, which the
system classloader could use to quickly generate
the needed implementations of the class from a
classfile.
By tweaking a few rules of the JLS, you could
then dictate that all classes containing 
PT's must be abstract.  At instantiation
time, the appropriate (concrete) inner class
is loaded, for all situations where the need can
be predicted at compile time, or dynamically
created for code that relies on dynamic class
loading.  A simplistic implementation should have
to do little more than a search and replace-type
operation on precompiled code.



Submitted On 21-MAY-1998
cd_smith
I'm not sure anything like this would be necessary to support parameterized
types.  Maybe I'm wrong, but I think it should be simple, in the case of what I
described above, to implement parameterized types in the VM using only an
extension to the syntax of signatures.
If a generic container is written to hold only instances of Super, and
instantiated elsewhere to hold Subs, then it is compiled initially as a simple
collection of Super.  The only difference in the class file would be that the
signature of the classes and methods would be somehow altered to indicate the
parameterization.
Compilers compiling code that uses this class (and instantiates it to hold Sub
instances) would use it just like it does now with Vectors, but there would be
no need for the checkcast instruction because the compiler can guarantee that
the (implicit) cast will be valid.
This would provide a simple implementation of parameterization with minimal
changes necessary for the virtual machine.  I'm sure there are other issues,
but I can't think of them right now.


Submitted On 08-JUN-1998
ldwg
Cd_smith's definition of bounded genericity is fairly accurate ;)
The "bound" is just a class or an interface that is required for a
given
parameter, e.g. Cloneable or Ordered, e.g. in
public class OrderedSet<Ordered Element> extends Set<Element> { ...
}
But I see two problems concerning the introduction of generic classes in Java:
a) Changes of the syntax in the core libraries invalidate existing sources
b) Changes of the byte code require new byte codes and thus new run-time
   environments
While a) can be "worked around" by a convention that any missing
class argument defaults to the given bound (so "Vector" stands for
"Vector<Object>"), b) is much more difficult: One *has* to
include additional
type information into the byte code to be checked by the verifier. This is
because one *cannot* rely on the validity of the compiler - just think of
hand-written byte code. To be able to omit the superfluous downcasts (in
the example, from "Object" to "Ordered") the verifier has
to check that all
parameter types are correct and thus needs the additional type information.
So for generic classes we have to
- change the syntax, improve the parser and rewrite nearly all major packages
- change the byte code, improve the code generator and type checkers (in the
  compiler and class loader), and rewrite some parts of the interpreter
  as well as just-in-time-compilers.
These might be the reasons why Sun is not too enthusiastic about adding
genericity, which is a pity.


Submitted On 09-JUN-1998
cd_smith
You are, of course, right.  I'd forgotten about possible implications for
verifying code.  I don't really know enough about verification to understand
all the issues here, but I'm sure they are significant.


Submitted On 10-JUN-1998
jdmarshall
ldwg:
It would be possible to write a classloader that
would accept classfiles that contain parameterized 
typing information (ie, new additions to the classfile
specification, and JLS) and emit a Class object that
has been resolved to a perfectly normal JDK 1.1 standard
before the verification phase.  I don't see how B) is an 
issue, or why A) needs to be.  You need to modify the 
classloader, the classfile format, and perhaps new, but
you don't need to add new bytecodes.


Submitted On 10-JUN-1998
ldwg
jdmarshall:
Of course, A) does not need to be, that's what I am telling ;)
But Sun would have to rewrite some libraries to benefit most from
the new capabilities, e.g. Enumeration, Vector and all uses thereof.
The brand-new java.util.Collection of JDK1.2 would have to rebuilt,
too. Of course, the old sources would remain compatible, but users
would want to use the old mechanism as they are used to.
You are right in that you can produce 1.1-compliant code by
creating a class "VectorOfDummy" or "Vector$$Dummy" from an
instantiated class "Vector<Dummy>" and just use it as is.
Maybe I misused the term "byte code", I refered to the
classfile format and not the opcodes. I disagree about the
distinction between class loader and verifier since the check
of the vadility of a certain instantiation (e.g. a declaration
of a Vector<Dummy>) is clearly not a job for the class loader
which might nevertheless create any required (and approved) class
afterwards.
It is indeed not necessary to rebuild the main interpreter, my
fault :-|


Submitted On 25-JUN-1998
jdmarshall
ldwg:
I'm sure that'll really break a lot of people's hearts :)
I think it was fairly odd to even bother with a 
collections API in the absence of parameterized types.
More to the point, removing all that casting on all
the listeners, all the hashtables of Strings or Dates
or URLs, etc, scattered throughout the code will 
improve overall performance of the JDK. Frankly, I'm
amazed by how few people are voting for this one.


Submitted On 01-JUL-1998
97jaz
Well -- I did vote for this, since it seems to 
be the "parameterized types" feature request, but
I want to stress that I am *not* in favor of the
C++ system.  ML has the right idea.


Submitted On 12-JUL-1998
cd_smith
Okay, now you've got two of my votes.
22 and still counting! :-)


Submitted On 15-JUL-1998
jonathanfinn
This is a good intelligent discussion. Take a look at this MIT proposal for
Java PT's, at http://www.pmg.lcs.mit.edu/papers/popl97/popl97.html (I don't
think anyone's mentioned this). It looks well thought out.
Of course we need parameterized types and also asserts (these are my top 2
votes). For some reason there's a bit of a voting bandwagon for asserts - I
think PT's are much more important and I'm only vote no. 23! Are we the only 23
people who feel queasy having to cast every time we get an element from a
Vector??


Submitted On 16-JUL-1998
ldwg
I think the problem is not that many people do not see the need
for generic types, but that many people do not see the bug vote.
To vote for generic types, you must feel an urgent need and
actively search for the topic. Only topics in the top-25 will
remind people to deal with the problem.
I will try to convince some collegues to use their votes...
The Pizza group recently started a new project called generic java (GJ).
The project's home page is www.cis.unisa.edu.au/~pizza/gj.
Have a look at the participants, they are true experts in the field
(two of them stem from JavaSoft; nevertheless, GJ is not "official").
And no wonder, they did pretty fine, they even provide versions of
some util classes and the 1.2 collection stuff. The decision was to provide
complete compatibility with the legacy code (that is, a Vector is
byte-code-compatible with a Vector<Object>). The price to pay is the
remaining need for downcasts on byte code level and some small
inconveniences. The compiler seems to work fine, but does no optimization
(at the moment) and support tools (such as gjdoc) are still missing.
Nevertheless, a frequent and wide-spread use of GJ will probably make Sun
think faster.


Submitted On 17-JUL-1998
fbrueg
When you look at what features third party language extensions or tools provide,
 IMHO it becomes quite self-evident that parameterized classes (along with
assertions, my other vote) should really be in the language. Unnecessary
casting just feels *bad*!


Submitted On 20-JUL-1998
MichaelFranz
As soon as assertions get into the language,  PT's will get all three of my
votes.
I just happen to give asserions priority because they help trap all kinds of
programmer errors, not just casting errors.
As virtually everyone in this thread would agree, having to continuously cast
is not only dangerous, it causes unnecessary work for developers. 
It seems that the entire world has forgotten what Java was originally conceived
for: TV Remotes and washing machines.
As far as I understand it, assertions were dropped because of time constraints
(comment JGosling) and multiple inheritance (probably PT's too) was dropped in
order to keep the runtime system small.
These are simply not issues for an OS390 or even a PC.
On a more constructive note: A good Eiffel->bytecode compiler could solve
some of these problems.


Submitted On 24-AUG-1998
jdmarshall
Apparently we won't be getting anything of this
sort in JDK 1.2.  However, Hotspot does appear
to alleviate some of the run-time ugliness of 
constant casting, if not the design time ugliness
of code snippet repetition.
If you read enough of the teasers for Hotspot,
one of the purported features has to do with code
of the form:
if (reference instanceof classname)
     classname castedObject = (classname) reference;
The above code has two conditional checks to determine
if the second line of code will fail.  The dynamic
compiler in Hotspot takes the initial check as gospel
and does a (not-so-)blind cast in the second line.
(This assumes Hotspot has deigned to recompile the
code, which is not guaranteed to be the case)
It's still just a stop-gap measure, if you ask me.
If parameterized types existed in the language, 
the benefits of this little feature would diminish
greatly.


Submitted On 09-SEP-1998
IanHaggard
My votes right now are for decent Linux support,
but as soon as they address that, all my votes are
going here.  While I agree that language-level
support for assertions would be nice, it's
possible to do your own.  On the other hand,
generics/templates are a LOT harder to do without
language-level support.  Moreover, genericity has
all the benefits of assertions or design-by-
contract in addition to its other uses -- it makes
your code and interfaces clearer and it fixes bugs
(at compile time, no less!).  If you feel like I
do, I encourage you to post something to this
effect on the assertions discussion.
As far as bound/unbound genericity, I definitely
prefer bound, despite having a C++ background.
But if we're doing bound genericity, then we need
to be able to have signatures, not just
interfaces.  In other words, lets say that I have
an algorithm (such as RSA) that works only on big
numbers, such as BigInteger or BigDecimal.  How
can I genericize that algorithm so that it could
take either a BigInteger or BigDecimal? What I
want to do is create an signature like:
signature BigNum {
  public BigNum add(BigNum);
  public BigNum multiply(BigNum);
  public static BigNum valueOf(long);
  // etc.
}
generic class MyGenericAlgo
[MyNum implements Number signs BigNum]
{
   MyNum recalculate(MyNum);
}
But right now, all we have is interfaces, and
I can't make a BigInteger retroactively
"implement" the BigNum.  And moreover, there's no
way to specify a static member in an interface.
Anyway, what I'm trying to say is that while I
support bound genericity, I would prefer unbound
genericity in the absence of signatures.  While
interfaces are very nice for object-oriented
programming, they are totally inadequate
for generic programming.


Submitted On 10-SEP-1998
ldwg
The subsequently addition of superclasses (or superinterfaces)
for existing classes is a severe problem. It is, however, not
necessary to introduce new types of interfaces when we require
"structural conformance" of interfaces for type parameters.
This requirement is not as strict as proper subtypes. An example:
interface Ordered<T> { public boolean less(T); }
OrderedSet<E implements Ordered<E>> { ... }
Without structural conformance, any element type E for the
ordered set would have to implement Ordered. Structural
conformance only requires that E defines a public method
"boolean less(E)".
Unfortunately, this mechanism does not fit well with interfaces
as polymorphic types. On the other hand, the introduction of
a new type of classes leads to a huge amount of reengineering
which I doubt is appropriate.


Submitted On 16-SEP-1998
chriskl
Just extend the Vector class to make something like 'IntegerVector'.  Then keep
everything the same, just override the add methods to do type checking and then
pass the request to super.add...


Submitted On 18-SEP-1998
jdmarshall
I always worry about people who say 'why don't you just...'.
 
Besides, you're not extending Vector, you're repeating the 
contents of the class, modulo the cast checks.  If you don't see
why code repetition is bad in a software development environment,
then I'm woefully prepared to help you...
Genericity does have a useful place in a 'modern OO language',
and the most efficient and type safe way to accomplish that is
with parameterized types of some form, be it very limited or
otherwise.


Submitted On 29-SEP-1998
opinali
I want generic types, but let's lern the lesson of C++-versus-Eiffel: generic
types _demand_ stronger, sophisticated typing features (e.g. covariance,
"like" tagging).  Pushing generic types into Java's current typing
strength is creating new headaches.


Submitted On 29-SEP-1998
bram3
I would like some sort of parameterization of 
possible exceptions as well.
I have a place in my code where an interface's 
methods may or may not throw an exception. For 
the most part, creating a shared subclass which 
has abstract methods with no exceptions declared 
works fine, the problem occurs when a class uses 
the common interface and just lets all exceptions 
pass through. In that case, I have to resort to 
using two identical pieces of code, one which 
uses the more generic interface and throws 
excepitions, and one which uses the excepion-free
subclass and throws none.


Submitted On 10-OCT-1998
stuartG
I am changing my two votes for "Covariant return types" to votes for
this one.  It seems to have more support and includes covariant return types (I
believe).  I think the best transition approach is to start with a JLS change
along the lines of the "Generic Java" project.  Then start changing
the VM to make it more efficient.  


Submitted On 12-OCT-1998
jorendor
Someone said:  "...the introduction of a new type of classes leads to a
huge amount of reengineering which I doubt is appropriate."
I feel obliged to point out that the introduction of "signatures", as
defined above, would not require much reengineering.  It is a compiler-only
change.  The addition of "signatures" is much, much cleaner than
using real Java interfaces.  An interface would be reflected in the bytecode; a
signature need not be.  Also, the use of "x implements Izz" to mean
something other than "x actually explicitly implements Izz" is a very
bad idea IMHO.
The big question is whether to go the extra step and make changes to the
bytecode interpreter.  A few fairly minor changes could fight the code bloat
that generic types can cause.
I'd be happy either way.
I'm astonished nobody's pointed this out yet, but when C++ compiles templates,
it does *not* let you "call methods on an object when they may or may not
be there."  If you try and make such a call, the compiler will flag it as
an error.  If a C++ compiler is well-written, it can generate error messages
that are identical to the nice messages you'd get from a bound-generic system.
C++ templates are great, but the learning curve goes awfully high.  A bound
approach is more appropriate in Java.
I also agree that the Collections API is a joke, except inasmuch as Collections
might be incorporated into a generic framework.


Submitted On 16-OCT-1998
ldwg
Just my two cents again...
Unlike "syntactic sugar", type-related enhancements are not
"compiler-only"
if you require type-safe dynamic class loading.
Omitting signatures on the bytecode level means that the class loader cannot
dynamically check the conformance of class interfaces.
A well-written C++ compiler will indeed report errors during instantiation
of template classes. Unfortunately, they are reported rather late and can
point deeply into (inaccessible) library code. Explicite type bounds do not
only make things clearer but also allow instant checks.


Submitted On 19-OCT-1998
OlsonB
Does anyone else feel that templates mainly cause bloat
because of the code they write for you that you never see?
Interfaces are enough.  I wish I could vote against this one.


Submitted On 24-OCT-1998
puzza
I get sick of casting!  I'd like some compile-time safety.
It would be especially good to be able to specify a class and all its derived
classes in the template.


Submitted On 25-OCT-1998
sigjes
Why is not inner classes enough?
Let the generic (container) class have an inner class. The type of inner class
is set by a constructor parameter and stored in an instance variable.
Then run-time checking (essential!) is done as any run-time type checing, with
subclasses allowed. No new bytecodes !
The compile-time checking would be a pure Java Language & compiler
extension. In my opinion it is nice, but less important as stong type-checking
is always done at run-time by JVM.
An ugly version of this can be built in Java 1.2. Let the inner class be of
type Object, but check type of any new objects using operator instanceof. The
overhead is quite low. (Better implementations possible in Bytecode.)
Something similar may be done on parametric interfaces. 
Changing Bytecodes and JVM can not be justified.


Submitted On 26-OCT-1998
jorendor
I think I'm replying to several people here,
so...
> Unlike "syntactic sugar", type-related
> enhancements are not "compiler-only" if
> you require type-safe dynamic class loading.
There are two answers:  (1) have a generic class
compile into a special "generic class" file 
(not a normal Java class) which the interpreter
uses to instantiate Java classes as needed.  This
would require an upgrade of the Java runtime,
bytecode verifier and all.
(2) Compile a generic class at
compile-time into intantiations.  Give the
instantiated classes mangled names, just like
inner classes.  This is a compiler-only change,
even if signatures get involved and so
forth.  The current bytecode verifier would
verify the generated classes, because they are
normal Java classes at the bytecode level.  And
the generated classes would not have the
unnecessary casting required with Vector et al.
Type 1 avoids code bloat.  Type 2 avoids
compatibility problems.
You seem to be saying that a type 1 solution
would be an "enhancement" but a type 2 solution
is merely "syntactic sugar".  But both provide
the same functionality to the programmer!  Sun
could come up with a syntax for generics first,
and *then* decide whether to go with a #1 or #2
implementation.
Again, either one would be fine with me as long
as we got *something* in the language *soon*.
> Then run-time checking (essential!)
[snip]
No, it's not.  In the case of a Vector-like
data structure, all type checking can be done
once at compile-time and again at
bytecode-verify time, and no further checking
is necessary.  Runtime type checking is a
needless waste of time--both run time and
programmer time.
> A well-written C++ compiler will indeed
> report errors during instantiation of
> template classes. Unfortunately, they are
> reported rather late and can point deeply
> into (inaccessible) library code.
Current compilers usually say something like
"no matching method for Fooz::compare(Fooz)
at line 23481"
But the compiler could just as easily say
"can't use template 'sort' with type 'Fooz';
'Fooz' would need a method Fooz::compare(Fooz)"
...if the compiler had been written that way.
And the compiler can catch this early if it
wants to.  There's nothing in the standard
preventing a compiler from tracking what a
template requires from its parameters.
-- 
jason


Submitted On 27-OCT-1998
sigjes
>> Then run-time checking (essential!)
>[snip]
>No, it's not. 
I didn't distinguish between run-time and bytecode verify-time. The separation
is merely an optimization, although included in the spec. 
We both agree that executing bytecode should be type-safe.
I still can't see why type-checking could not be performed by bytecode in the
generic class. The same checks would need to be done 
by a modified bytecode verifyer anyway, so speed penalty may not be large.


Submitted On 28-OCT-1998
sigjes
Another viewpoint:
The original request was for strong typchecking at compile-time. It seems he is
working with mission-critical applications, where type-errors stopping
operations is unthinkable.
If so, then everything needs to be checked at compile-time. No dynamic class
loading possible. And the compiler needs full type information also from
third-party libraries, somehow. 


Submitted On 04-NOV-1998
David Silver
The MIT proposal for parameterized types shows that Java programmers would reap
a performance benefit by avoiding run-time type checking, in addition to the
inherent syntactic short-cut (no explicit down casts) and compile time type
saftey.
Also, the MIT proposal details a possible implementation without extending the
JVM.  Although the performance is not as good as extending the JVM, it provides
an easy migration path.


Submitted On 05-NOV-1998
shecter
Even more important to me than parameterized
types is an elegant solution to the Java 
Interface / MI 'problem'.  The 'Jamie' project
has a very nice solution:  multiple automatic
delegation.  With this idea, good design is made
easy, and the point about MI or not MI is
basically moot.  See:
http://www.list.org/jamie/


Submitted On 06-NOV-1998
noutram
This is similar to 4173702, could we merge the two?


Submitted On 10-NOV-1998
steveshort
I agree with the request for parameterized types.
I have been down the road suggested by the workaround,
i.e. creating my own typed container classes, but this
is a real drag.  I no longer do this simply because of
the extra work involved - and have lost the type
safety that I'd like.


Submitted On 10-NOV-1998
strachaj
GenericJava appears to provide a good migration path whilst maintaining
backward compatability so come on Sun - we need better performance!


Submitted On 11-NOV-1998
jwj
In comp.java.lang.programmer I had argued for generic types. During the
discussion, two things became clear to me:
(1) The GJ approach was nice, but not sufficient. Ground generics need to be
first class objects, one has to be able to reflect them, to downcast to them
etc. GJ does not allow this, which is why I prefer the approach of PolyJ
(www.pmg.lcs.mit.edu/polyj) in this respect.
(2) I am not sure that subtyping constraints (the way GJ does bounded
genericity) is really flexible enough. Again, for an alternative, look at
PolyJ. Or Ada, for that matter, where one has to pass the manipulation
functions along with the types when instantiating a generic package.
Introducing parametric polymorhpism to the Java type system is an important
design step. I wish that the guys at Sun look at the various implementation
alternatives more carefully than they did when they implemented the AWT.


Submitted On 16-NOV-1998
jdcjdc
Here's part of what parameterized types should
provide:
class Foo
{
 ...
}
class xxx
{
   void someMethod()
   {
      // create a vector of Foos
      Vector<Foo> vec = new Vector<Foo>();
 
      Foo temp = new Foo();
      // check at compile-time that temp
      // is of class Foo or a subclass of Foo 
      vec.addElement(temp);
      Foo temp2;
      // 1. check at compile-time that LHS, (i.e. temp2) is
      // of type (or subtype) Foo.
      // 2. explicit typecasting not needed
      temp2 = vec.elementAt(1);
   }
}
This does not need code duplication (as C++ does).
The Java compiler can thus easily assure type-safety. I
don't see what the big deal is in implementing
this feature into the compiler.
Note that C++ also allows ints, longs and other
types as parameters which cause considerable
code bloat (due to duplicate code generated by
the C++ compiler). There are some advantages to
this method (mainly speed), but the disadvantages
outweigh the advantages.
So, I'd settle for just type-safety provided
by parameterized types. Note that for this
ease of implementation, only descendents of
Object can be used for parameters. Using
primitives like 'int's or 'float's will
result in code duplication.


Submitted On 23-NOV-1998
cyrild
Check out Polyj http://www.pmg.lcs.mit.edu/polyj/
It looks really cool, although I understood
all the differences to C++ . (where clause)


Submitted On 23-NOV-1998
cyrild
You get my vote. 
I checked out
<a href="http://www.cis.unisa.edu.au/~pizza/gj/"> Gj
0.6</a> 
It's not Open-Source, and it's not a preprocessor.


Submitted On 23-NOV-1998
strachaj
Check out Virtual Types in Kresten Krab Thorups article on the subject. It's in
postscript and dvi
and postscript at: http://www.daimi.aau.dk/~krab/resume.html#Publications
It's a very elegant implementation of a form of parameterized types they call
'Virtual Types' which only changes the compiler slightly - no runtime changes
necessary. 
Let's vote for 'Virtual Types' instead!!!


Submitted On 23-NOV-1998
artlum
As far as I can see, it will be impractical to do C++ "templates" in
Java, as different object code needs to be created depending on whether you
want the template to work with objects, arrays or primitives. C++ can handle
this by using the preprocessor at compile time. Java cannot do this as it is
run time based. So before we start, I think we need to distinguish between
"templates" and "generics". Many C++ users fail to see the
difference. Generics to me means "type safety".
On this premise, perhaps we need to restict any system of generics in Java to
things which work with Objects and arrays of Objects, no primitives or arrays
of primitives.
This simplifies things greatly. At the practical level it means the compiler
can just look for references to "Object" in method parameters and
return values, performing static type checking as appropriate during the
compilation.
If we don't restrict ourselves to objects then we open a big can of worms.
Imagine a classloader trying to adapt the Vector class to accept integers and
you'll see what I mean. New code would have to be created on the fly to deal
with the integers, and this isn't pretty. You'll get massive code bloat as each
paramterised class instance makes new code for itself, you'll probably need
operator overloading to be able to write things like generic quicksort, you
might even need the source code to be able to do it at all!
Restricting ourselves to objects seems sensible and gives us the required
static type checking
with a minimum of fuss, it doesn't need any new bytecodes, just a new
classloader (and this is only needed for the case when a generic-ised class is
passed to a method).
Examples:
Suppose we declare a Vector of MyObject:
Vector<MyObject> v = new Vector();
Case 1: Calling methods of Vector which return Object.
The code:
MyObject o = v.elementAt(0);
Is converted by the compiler to the equivalent of:
MyObject o = (MyObject)v.elementAt(0);
This saves typing and makes the code look neater.

Case 2: Passing things to the Vector
The code:
v.addElement(o);
Is converted by the compiler to the equivalent of:
v.addElement((MyObject)o);
This gives us a lot of static type safety. It makes it impossible to store the
wrong sort of object in v.
case 3: Passing v as a parameter to other methods.
Suppose we call a method with v as a parameter:
foo(v);
The method needs to be defined as something like:
void foo(Vector<>) {
}
This means that foo expects a "typed Vector" as a parameter. If you
try to pass a "vanilla" vector then you'll get a compile time error.
The classloader then needs a mechanism to let foo() know the type of Vector
being passed, and foo() needs to do typechecking inside as in cases 1 & 2
above.
You could (of course) also define foo as:
void foo(Vector<MyObject>) {
}
This restricts foo to working with a Vector of type MyObject.
<hr>
I think these simple changes would give us the static type safety which is
currently missing from Java without breaking much. Trying to add generics which
can deal with both objects and primitives would appear to cause more problems
than it's worth.


Submitted On 30-NOV-1998
s871161
if KEEP debuger protocol and 64Bit addressing then able to allocate Big object
is TEMPLATED Array only.
so before 64 bit support, prease support template. 


Submitted On 10-DEC-1998
phillip2
This absolutely gets one of my votes. The 
tension between generic (and therefore resusable) 
code and compile time safety that exists in java
is really not good at all. The delegation solution
is nice enough I suppose but is only any good
if you all of your methods for affecting the
data are in the delegated class. As soon as you 
want to use code external to the delegate then
the system fails. Some method for genericity 
is vital if Java is not to throw away many of
the advantages that come with strong typing. 
I cant comment on how easy the different 
mechanisms are to implement or even very much 
which mechanism is best but Java really needs 
this badly. At the moment Java is a bit of a 
"half-way" house solution, which is what C++ was
10 yrs ago....



Submitted On 15-DEC-1998
jdcjdc
I want to point out that Java is different from
C++ in that all Java classes are derived from
a single class 'Object'. This is not so with
C++. Languages like PolyJ add complicated syntax
to Java (the 'where' clause). A much simpler (and
elegant) solution is possible.
Here is a sample:
// dots added to preserve indentation
class Base
{
.   // Base's way to add
.   int add(int a, int b)
.   { blah blah... }
}
class Descendent extends Base
{
.   // yet another way to add
.   int add(int a, int b)
.   { blah blah blah... }
}
// Note that both Base and Descendent are
//  derived from the 'Object' class
// this class allows you to only add objects
//  of type 'Base' and its derived classes
//  like 'Descendent'
template <Base T>
class MyVector
{
.   // anObject can be of type 'Base' or
.   // 'Descendent' or any derived class of 'Base'
.   // The added object will not lose its identity:
.   // a 'Base' object will remain as 'Base'
.   // a 'Descendent' object will remain as 'Descendent'
.   void add(T anObject)
.   { ... }
.   T elementAt(int index)
.   { ... }
}
class xxx
{
.  // comparision of old java and template techniques
.  void test()
.  {
.     Base base = new Base();
.     Descendent desc = new Descendent();
.     // plain old vanilla vector
.     Vector vec = new Vector();
.     MyVector<Base> vecBase = new MyVector<Base>();
.     //   similar to: MyVector vecBase = new MyVector();
.     // To use only Descendent and not Base use:
.     // MyVector<Descendent> vecDesc = new MyVector<Descendant>();
.     // compile-time check: base is of type 'Object'
.     vec.add(base);
.     // compile-time check: base of type 'Base'    
.     vecBase.add(base);
.     vec.add(desc);
.     // compile-time check: base of type 'Base'     
.     vecBase.add(desc);
.     // get objects
.     Base b;
.
.     // type-casting needed
.     b = (Base)vec.elementAt(0);
.    
.     // no type-casting needed
.     b = vecBase.elementAt(0);
.     Descendent d;
.
.     // type-casting needed
.     d = (Descendent)vec.elementAt(1);
.     // type-casting needed!
.     d = (Descendent)vecBase.elementAt(1);
}
Although type-casting has not been eliminated,
it is reduced for most of the cases. This is
better than PolyJ's method, which is slower and
breaks polymorphism.


Submitted On 30-DEC-1998
sorotokin
More specifically: I vote for PolyJ (MIT proposal).
Also I do not like casting from DerivedFromT[] to
T[]. It is nessesary in Java without parameterized
types (for things like Vector.copyInto()),
but is bad because it defers some type
checking for run time. Just realize that simple
a[i] = b almost always involves some type
checking! (In addition to boundary checks).
How can you can claim "almost C++" speeds
with that!?? PolyJ can be done very efficiently
and also "where" clause is very nice idea.


Submitted On 31-DEC-1998
duale
I think you guys are retarded.  JAVA _DOES_NOT_
need templates!!!!!  Get it through your thick
heads!!!  Templates are a hack for programmers
too damn lazy to implement interfaces on objects
and primitive date types.
The fact of the matter is that parameterized
types are so friggin complex, both to read
and write and compile and build, that they
would add a huge amount of overhead to any
compiler.  You goofballs might think polyj
and pizza are good starting implementations
of templates, but those compilers are purely
at the prototype stage!!  Upon close inspection
you will find them severely limited and broken.
JAVA does not need templates.  If class X
needs methods Y on class Z, then class X should
ask for those methods in interface I, and class
Z should explicitly implement interface I.
There should NOT be a hack such that class
Z only has to have the methods I by name and
class X could use this, thereby removing all
compiler-time checking and what not.
If you're building a huge complex data-structure
based system or whatever where templates are
a must-use, then write C++ code!!!  But don't
corrupt the clean JAVA language spec just
because you want JAVA to have every goddamned
language feature created, because then JAVA
will wind up being another ADA or even worse,
C++.
JAVA _WORKS_.  I have never had any need for
templates or multiple inheritance, and anybody
who thinks they need that garbage doesn't know
what OO truly is.




Submitted On 31-DEC-1998
jessh
Generic classes -are- sorely missing from Java.
It is, of course, important to do them -right-,
but even C++'s templates can be easy to re-use
and avoid code-bloat -- if someone carefully
designs the template classes.  Java should do
better, especially in the ease of design category.
I believe a solution that does not require VM
modifications, but could optionally benefit
from them would be ideal (e.g. an approach
designed for specialized JIT'ing of generic
classes).
A final comment: though they can certainly be
handled in a different fashion from objects and
arrays (to avoid code bloat in the latter cases),
a parameterized type mechanism for primitives -is-
necessary.  This could be purely compile time with
full code bloat as there aren't that many
primitive types in Java and the programmer is free
to factor out type-invariant code into helper or
base classes.


Submitted On 02-JAN-1999
jdcjdc
The template feature is extremely powerful and easy, 
and has spread like wild-fire to a lot of languages
(Ada, C++, Eiffel, ML etc). Java does almost
everything that C++ does with a much easier
syntax. 
  I don't think Java needs all template features,
mainly primitive data types (int, float...).
If these primitive data types are added using the
C++ compiler way, code bloat will result, else
there will be no code bloat (well, a couple more
bytes for each instance of an object). If the PolyJ
method is used compiler types, the code size will
not increase significantly, but it will be slower
(the classic time/space tradeoff). After eliminating
all primitive data types, all remaining classes
are subclasses of Object. In C++, there is no single
root class like Object. Therefore, code bloat cannot
be avoided. However, the root Object in Java
makes template implementation trivial. Look
at this oft-repeated snip:
    Vector vect;
    SomeClass inst;
    ...
    // inst is downcasted at runtime to type 'Object'
    // which wastes some time
    vect.addElement(inst);
    ...
    // the element at position 0 is upcasted
    //    from Object to SomeClass at run time
    //    thereby wasting time
    // Also, notice the irritating (and error prone)
    //    typecasting required
    inst = (SomeClass)vect.elementAt(0);
  With templates (generic types to be more specific),
type-checking is done at compile-time, and no
casting is required, making the program run faster.
   Most programmers want to avoid extensive casting 
(typecasting was intended to be used in exceptional
situations only, and not meant for common programming
pratice.)
I have found this casting 'disease' only when
using collections like Vector, Stack, HashTable.
If anyone is not already sick of casting, they
will soon be with the addition of the 'Collections'
package to the Java 2 platform. 
Bottom line:
1. Type-casting is error-prone
2. Type-casting creates ugly looking code
3. Type-casting makes code run slower
4. Generic types are definitely cool and a must
   for all modern programming languages.
5. Generic types will save us from subclassing
   every know class a million times to add type
   safety


Submitted On 11-JAN-1999
kwaclaw
Have a look at 
http://www.daimi.aau.dk/~krab/virtuals.ps


Submitted On 11-JAN-1999
yminsky
I just want to add my vote of support for generics -- ideally bound generics,
i.e., using singatures.  The lack of typesafety and excessive typecasting
require by Java is ridiculous -- and it's not just a problem for container
classes -- it's a problem for many kinds of extensible frameworks.  Please fix
this, and soon!


Submitted On 11-JAN-1999
yminsky
I just want to add my vote of support for generics -- ideally bound generics,
i.e., using singatures.  The lack of typesafety and excessive typecasting
require by Java is ridiculous -- and it's not just a problem for container
classes -- it's a problem for many kinds of extensible frameworks.  Please fix
this, and soon!


Submitted On 14-JAN-1999
dleuck
1 vote for parameterized genericity (not templates).  I would like to see a
PolyJ (MIT proposal) -like implementation.  VM spec changes are necessary to
implement this language feature efficiently.  Any hackish implementation that
object-wraps and unwraps primitives left and right is not acceptable. 
Admittedly, VM changes can be problematic and cause major headaches but
sometimes scotch tape doesn't do the trick.  Make the change now before it's
too late.  While your at it add multiple return values (I believe James Gosling
has mentioned he liked the idea).  This would also alleviate object creation
overhead (creating containers simply to hold multiple return values.) 


Submitted On 25-JAN-1999
jsando
I am happy to see so much lively discussion on what is a critical missing
feature of Java.  Each Vector or Hashtable I create makes me wince, knowing
that there's one [more] potential problem the compiler can't help me find.  Not
to mention having to cast all over the place.  Do the ideas being discussed
include something for a typed Iterator or Enumeration?


Submitted On 26-FEB-1999
kriff
I've switched my vote from assertions to templates.
This is something that would be really useful to
have.
Interfaces aren't enough. To implement a typed 
interface similar to Iterator<A> in Java today
would need a seperate interface (and implementation)
for each actual type we're interested in. For
example, you could create interfaces called
IntIterator, FooIterator, ByteIterator, etc. Each
of these would require a seperate source file
even though its the same interface with only
minor changes. Now suppose you want to add a new
method to your interface. You'd have to manually
track down each of the seperate interfaces and 
make the exact same change over and over. This
is a wasteful and boring way for a programmer to
spend his time, which certainly is not what OO
is all about.
If Sun does implement these features, it must be
done without adding unnecessary bloat. Ideally,
the runtime system (ie the JVM) would be modified
to take parameterized types into account. If that's
not possible, then the compiler should insert the
required casts and bridges (similarly to GJ)
automatically. Under no circumstances should the 
compiler generate seperate classes to implement 
each use of a parameterized type. The cost in 
file size far outweighs any performance benefit
(especially for Applets)


Submitted On 26-FEB-1999
pharmakon
This is the feature I would most like to see
added to Java.  I cringe every time I have to
write an explicit cast.


Submitted On 26-FEB-1999
Danny the Kid
In refrence to suns undated "evaluation":
I don't see why Sun is trying to make a 
compatibility issue here.  The way I see it if
you don't specify a type for the template class
then it should becomes a template for Object...
This way old code can compile with the template 
based classes.  It doesn't seem like
compatibility would be at all a problem. Am I
missing something obvious here?


Submitted On 03-MAR-1999
jdcjdc
I'm interested in your opinion about this implementation
style for generic types:
Old Java style declaration for Vector:
class Vector
{
    public void addElement(Object o) { ... }
    public Object elementAt(int index) { ... }
}
class MyInteger extends Integer
{
 ...
}
// use Vector
static void foo()
{
   Vector vect = new Vector();
   Integer i = new Integer(5);
   MyInteger mi = new MyInteger(10);
   
   vect.addElement(i);
   vect.addElement(mi);
   vect.addElement(new Double(5.0));
   // type-casting need to retrieve any object   
   i = (Integer)vect.elementAt(0);
   ni = (MyInteger)vect.elementAt(1);
}
Java with generic types included:
// T can be Object or any descendent of Object
// (i.e.) any Java class other than primitive
// data types
generic <Object T>
class Vector
{
   public void addElement(T obj) { ... }
 
   public T elementAt(int index) { ... }
}
class MyInteger extends Integer
{
 ...
}
static void foo()
{
   Vector<Integer> vect = new Vector<Integer>();
   Integer i = new Integer(5);
   MyInteger mi = new MyInteger(10);
  
   vect.addElement(i);
   vect.addElement(mi);
   // can't do this: only Integer and classes
   // derived from Integer can be added
   vect.addElement(new Double(5.0)); // compiler error   
   // type-casting needed only to get a descendent
   // of Integer
   i = vect.elementAt(0);
   ni = (MyInteger)vect.elementAt(1);
 
}
Not only does this eliminate some type-casting,
it allows the creation of a vector that holds
only integers.


Submitted On 03-MAR-1999
AWKay
This one gets all three of my votes. In addition,
I would like to vote for the GJ implementation, 
since it fixes the most horrendous problems for
generic containers (instanceof and casting) 
without changing anything but the compiler. I 
also particularly like the fact that existing 
_binary_ classes can be generalized by 
changing the internal attributes in a JVM
compatible fashion.
My only gripe with the current GJ compiler is 
that is doesn't have a command line switch that
allows the programmer to turn unchecked warnings
into errors.


Submitted On 06-MAR-1999
ins
From my point of view Java clearly does not need any parameterize type or such
a stupid things like template a la C++! Please, keep Java the Language clean
and simple – the most valuable asset it has. For those who very needs
parameterized facilities I would recommend mostly concentrate on design with
Java, rather than trying to use your old C/C++ tricks in new environment. Wake
up!


Submitted On 11-MAR-1999
Unland
Why donīt write a little Java-tool wich creates
classes-source from a template before compile-time?
Classes build this way are also typesafe and no
change in the Java-standard is necessary.


Submitted On 21-MAR-1999
tbreuel
Please do NOT add C++-style templates or
Eiffel-style bound genericity.  I believe
both of them are ad-hoc designs with limited
expressiveness and serious technical problems.
I'd strongly recommend looking at the
SML module language for an approach to
genericity that has minimal impact on the
base language, does not instantiate templates
haphazardly, and allows for type-safe separate
compilation.


Submitted On 25-MAR-1999
tovj
Yuck!
The intensions (Compiletime type safety) of the original poster cannot be
solved. You'll need
to check type at runtime anyway, so this feature will only be bloat since you
cannot depend on it
in any reusable class design.
It is quite possible today to make an extension of any Collection class to
demand the use of Integer only.
This feature is bloat in it's purest form. People
who want generics can use pizza.
Please don't turn Java into C++.




Submitted On 30-MAR-1999
AWKay
I am appalled at the lack of understanding of many
of the individuals posting comments here. Parameterized
types _are_ important in _good_ object-oriented
programming, and they need not be C++ templates.
If you are truly an intellectual, and have an
objection to parameterization, read on and hear
me out. Otherwise, I take it you are an individual
who is simply posting comments as an emotional
response to change (the "all change is bad" 
mentality).
Quick example:
void draw(LinkedList shapes)
{
   ListIterator i = shapes.listIterator();
   while(i.hasNext()) {
      Shape s = (Shape)i.next();
      gr.draw(s);
   }
}
Where is the type safety in this call??? Someone 
modifying this program can easily
add some instance of Foo to the LinkedList 
and throw the whole thing out of whack 
_at runtime_! The only way to fix it is with
a check like:
   while(i.hasNext()) {
      Object obj = i.next();
      if(obj instanceof Shape) {
         Shape s = (Shape) obj;
         gr.draw(s);
      } else {
         System.err.println("Internal error: bad list entry");
      }
   }
...
Which adds significant overhead and complexity
to the routine. Also, bugs in the program are
discovered at run-time perhaps weeks after a
change is made elsewhere in the program.
A very simple, compiler-only solution to this problem
is parameterization by erasure (as is done in GJ,
see the pizza web site). This code can then be 
changed to:
void draw(LinkedList<Shape> shapes)
{
   ListIterator<Shape> i = shapes.listIterator();
   while(i.hasNext()) {
      Shape s = i.next();
      gr.draw(s);
   }
}
Easier to read? definitely.
Implementation? Read on:
Only one copy of LinkedList is needed, since Java
has an ultimate supertype (Object) that can be
used for that implementation at run-time. The 
compiler can enforce these rules purely at
compile-time according to the stated rules of
the source code:
- You must pass a LinkedList that contains only
  Shapes, or subclasses of Shape
- Elsewhere, the LinkedList will also have to 
  be declared as a list of Shapes, and the 
  compiler will dis-allow insertion of
  anything except Shapes.
This has the following benefits over the first
one:
- Adds type safety at run-time with a _compiler_ fix.
  The compiler complains about a Foo being put
  in the list.
- Eliminates the need for most instanceof and casting
  operations, which speeds up algorithms and makes
  code easier to read.
- NO extra code is generated
Good parameterization need not create the nasty 
code bloat of C++, and it need not be difficult to
use or understand.
If you want more information, read the information
on GJ, pizza, etc.
We are NOT asking for C++ complications. I personally
_hate_ C++ templates, but from an implementation
standpoint. From a design standpoint I see parameterization
as absolutly critical to good programming.
All three of my votes are on this feature request.


Submitted On 31-MAR-1999
jdcjdc
In case some numb skulls did not get the point, I'm
restating the previous article:
...
static void main(String[] args)
{
   ListIterator<Shape> shapes;
   ListIterator<Point> points;
   ListIterator<Integer> integers;
}
In C++, the compiler will create 3 classes from
above code and compile them:
  ListIterator$Shape, ListIterator$Point, ListIterator$Integer
All the 3 classes have the same code except that
the template type is replaced by Shape, Point or Integer.
This is the main reason for the code bloat.
Java does not have to follow this style - there will
be a single class, ListIterator.
Since all the parameter types (Shape, Point and Integer) are
descendents of Object, all calls are handled by polymorphism.
The compiler can ensure at compile-time that
objects added to the iterator belong to parameter type.
Thus there is no need for run-time checking (although it
can be provided optionally.)


Submitted On 09-APR-1999
aelberg
I totally agree that this is the biggest flaw
in the present language spec. I am not familiar with
the CS terminology; I just know that I want typesafe
collections. 


Submitted On 26-APR-1999
Ray Burns
I am strongly in favor of adding parameterized types (but not templates) to
Java.
For a related issue, see bug ID 4222792.


Submitted On 12-MAY-1999
steelman
A proposal for this has begun.
Look here:
http://java.sun.com/aboutJava/communityprocess/jsr/jsr_014_gener.html


Submitted On 18-MAY-1999
jdcjdc
I hope the JSR gets approved.
IMHO, the last constraint, C8, is most
important for wide-spread acceptance.
<start C8>
C8) Good performance of generic code. 
Code written to use the generics
feature should not be a lot slower 
or a lot more memory-intensive than
non-generic code. Using ten percent 
more space or time than  
non-generic code may be acceptable; 
using twice the space or time is not.
<end C8>
As far as space is concerned, there could be
hidden data members for each parametric type.
Eg:
generic <Integer X, Boolean Y>
class Foo
{
  // compiler adds one member per parameter type
  private Class XParameterType;
  private Class YParameterType;
...
}
class MyBoolean extends Boolean
{
  ...
}
Now, when an instance of the class is created,
the hidden members are automatically assigned
values by the compiler code.
void main()
{
   Foo<Integer, MyBoolean> f =
      new Foo<Integer, MyBoolean>();
   // behind the scenes, in the constructor
   //  of Foo, f.XParameterType is set to 
   //  Class("Integer") and f.YParameterType is
   //  set to Class("MyBoolean")
  
}
This information does not require too much space;
4 bytes for each parameter type.
So when is this information useful? Usually never.
1) It is useful only when casting from an 'Object' or
an ascendant of Foo to 'Foo<Integer, MyBoolean>'. 
2) It is useful when serializing/deserializing 
an object. 
3) It is useful for supporting the Java reflection
mechanism.
Other than these circumstances, checking can be
done at compile-time. In old Java, all objects
are converted to 'Object' and then casted back
to some class which wastes time. With generics,
there is no run-time casting check.
In other words, the generic class code will
execute at full speed, 99.9% of the time.



Submitted On 03-JUN-1999
jtr
So, what's going on with the generics JSR?  It looks like
it failed.  Can it be restarted?


Submitted On 10-JUN-1999
jdcjdc
They seem to have no problem approving silly 
proposals. When it comes to major changes, it 
takes them forever. I wonder if generics or
design by contract will ever make it into Java


Submitted On 14-JUN-1999
MichaelFranz
According to...
http://java.sun.com/aboutJava/communityprocess/jsr.html
...parameterized types have been "approved". Anyone know what this
means (if it means anything at all)?
I just hope they provide for Eiffel-style constrained generic types.


Submitted On 15-JUL-1999
vnitsch
Not quite sure - there is javacc wich seems "easy"
able to extend java-grammar.
instead of some predefined syntax using kind of a extendible compiler-compiler?
must be able to mix different grammars, of course :-)


Submitted On 15-JUL-1999
vnitsch
for syntax: dont hide generics in the body! no "void x(){
Vector<int> a;..}"!
take something like:
import awt.*;//and so on
import dynamic Vector {int} IntVector;
import dynamic Vector FloatVector {float};//like the "int[] x" &
"int x[]"
and then java!
by the way, since MS would like it: hold the
"(MyClass)a.elementAt(5)" option 
even where not needed! Much better readable than
"m_plxvzA.elementAt(5)" !!
compiler can drop it, no runtime-overhead; I hope they hear me!
--- syntax-features of my approach (1) ---
- syntax not possible  in old java, so unused.
- imports more readable, cleaner.
- rest of code is old java.
- today "easy" possible with prepros, perl, help of classloaders
and finally new compilers.
- once created, no new creator-runs needed 
(faster ecl than c++, ide's without preprocessor happy :-)
---> ! using java really for templates could look like this:
(may the forth be with you :-) 
--- (2) ---
import dynamic Lookup{ int, {"one",1,"two",2,
"three",3} } ThreeValues;
// ^ clever "LookupGenericCreator" can create 3 if's.. 
import dynamic LongStrings SomeLines { 
header till END
-HTML-
-TITLE-
END
footer till END-
-/BODY
-/HTML-
END //are spikes allowed in the reply?
} ; //all this bean-source-makers like it :-)
//hear i XML?
--- features of (2): ---
- Cloning the way of Beans:
"GenVector" has "GenVectorGenericCreator.class", 
which is called by the compiler on import. 
- free syntax in arguments possible. Dynamic Creation. 
- Can do its own stuff: 
hyper-clever recursive c++ template-metaprogramming for optimized matrices?
when you can do the source-creation with some println() and normal java?
or JPHYTON :-) 
- no source-changes, if we use simple "import" also for dynamics:
if there is a *GenericCreator available, it is used, so old *.class 
can be extended simply be dropping a file.
- Cloning the way of activation framework :-)
- the needed classes can also be createt with GJ, PolyJ?!
- and javacc will like it :-)
problems i see:
- flexible but inconsistent Syntax of parameters. also features
- all Creators isles, no global analysis like eiffel.
but at least strong typechecks by compiler&loader.
- and the long LongString's in imports :-)
--- i prefer seperate classes, instead of automatic casts, ---
which then call the generic base.
-- as mentioned, no changes to java after the imports!!
-- space: 
--- in memory they should be a few vtable-pointers more, code can be shared,
--- for the files there is a specialized ClassLoader, which can pretty compress
(name of the base and the replace-parameters).
-- speed should be better than casting.
-- hotspot
-- hotspot will inline heavy, so if you have methods with much casts
you will get one code-version for each combination. 
blows code like more classes, i think.
I expect hotspot is more optimized for method-invocation than for casting.

*(classloaders? good idea! hi jdmarshall, would suggest similar. 
"keyname.dynamic.smartloader.replacein.mypackage.GenVector$MyElement$Integer"

with a mypackage.GenVector as base for the smart 
and additional an imp of the full name on the web-page for old loaders.
(i allways feel classloaders should have an option which 
dumps its really loaded classes somewhere for minimal distribution)
also there is a plugin-way for old vm's & applets,
where the ClassLoader is not changeable: a proxy.
i've seen a proxy somewhere, which translates names in applets (not testet).
(thinks like awt.Window to safer.MyWindow, which is restrictet to max 5 open). 



Submitted On 16-AUG-1999
derbyshire16
One use for parametrization besides type safe genericity without loads of
dynamic casts, is policy parametrization -- which can be a a performance boost
to certain kinds of code, including algorithm type code.
It should also be easy to implement since Java already supports and always has
supported run-time *class creation* as well as dynamic linking. In C++ the
manner of template instantiation is a serious stumbling block and a major area
where implementations differ incompatibly. Multiple or missing definition link
errors tend to pour out of the linker like water out of Niagara Falls. java can
neatly dodge those problems. The biggest work would be adding the syntax,
standardizing and specifying it, and fixing up javac. The lesser work would be
instantiation, there'd just have to be a special classloader. And flexible
class loading is already in Java too -- ClassLoader, SystemClassLoader,
URLClassLoader, user-defined ClassLoaders, resource bundle classes that are
manufactured on the fly using text properties files that have nothing to do
with .java files or bytecode... Most of the underlying framework is already
there, unlike when templates were added to the evolving C++ and it totally
couldn't fit the original linking paradigm inherited from C without all kinds
of crufty crocks and glue used to make templates work with the linker... I've
seen how several compilers do this and man is it ugly, compile, link, catch
unresolveds, compile, slow, slow, swap, swap, out of memory, out of memory ...
another forces you to use pragmas to specify one .cc file to instantiate a
template in ... evil pragma evil pragma no no NONPORTABLE CODE! ... another
uses a repository and this must be managed somehow... then we have namespacing
problems and other difficulties ... All rwquire different ways of deploying the
code...some the templates in .h; some in .cc; some in both and with pragmas...
so much for C++'s Write once, Compile anywhere.
Java has it beat.
I vote for this one.


Submitted On 16-AUG-1999
adam@organic.com
Please be sure to generics as they relate to
exceptions (not just return types).


Submitted On 20-OCT-1999
CvR
The main flaw in proposals like GJ is that they don't allow primitive
types. Surely a Vector of doubles is only useful if the doubles
don't have to be wrapped in Double class instances!
The main objection seems to be that this causes code bloat,
but I wonder if this is really so significant? I haven't seen figures
from real life, but I suspect that in many programs this is not
as significant as people suggest. Also, a smart compiler
could prevent most code bloat by only generating separate
copies for the primitive types, and one for all reference types.
Although I vote for generics, I am against the current versions
of GJ and PolyJ. Both lack support for primitive types. GJ looks
more like a hack to minimize the inpact on Java as much as
possible instead of a well-designed language extension.
PolyJ (and Pizza, in for that matter) look better designed.


Submitted On 28-OCT-1999
Jwong
I have another suggestion.  Allow type-checking to be turned off and simply
rely on
method/signature matching to determine the correctness of messaging.  (Ala
Smalltalk.)
Optimize toward the positive, not the negative!


Submitted On 04-NOV-1999
dkf
CvR: The problem is that adding support for primitive type
parameterisation is much nastier than just supporting it over
objects.  It also leads to wanting to parameterise over methods
and stuff like that.  C++ went down that road, and it leads to
a place that we *really* don't want to go...
Jwong:  No.  Type-checking is important.  It is one of the
reasons why we do not write everything in assembler with a
macro preprocessor.  You might not care about the security
and correctness of the code you use, but I sure know that I do!


Submitted On 12-NOV-1999
tipparam
I agree with CvR. Parameterized types would be more useful if they 
supported primitive types. For example, look at Arrays.java of new collection
classes in JDK1.2. It has almost identical implemention of sort1() method
for each primitive array, int[], short[], long[], ...etc. This wouldn't be
necessary
if parameterized type (when they are available!) supported primitive types.
(BTW I am not criticizing the implementation of the collecion classes!)


Submitted On 16-NOV-1999
dkf
The problem with permitting parameterisation with primitive types
is that the primitive types are not related to any other types.
There is no type-containment relation with them on either side,
whereas the class hierarchy gives us a nice set of relations that
are pre-existing and fairly intuitive in practise (with the general
lack of surprise involved being a Good Thing.)
The result of this is that it permits an implementation of param.
classes that is pre-compiled (primitive types require the source
file to be rewritten by the compiler each time you use a param.
class) and it also means that you can leverage the existing
idiom of passing callbacks via implemented Interfaces.  (This
keeps the change to the language small.)
Allowing parameterisation over primitive types is klunky by
comparison (since the bytecode you need to emit is utterly
different) and stems from the fact that the primitive types are
pretty clunky themselves.  I can understand why they are in
there, but they make the type-system of the language much
more complex and less orthogonal.
C++ templates pretty much require completely different
implementations for each instantiation of a template, and that
is very messy.  Java should, where possible, avoid C++'s
mistakes (and make its own!) and a non-blecherous param.
class mechanism is one which is actually fairly easy, since you
can do all the stitch-up work you need (not very much either)
at class-load time.


Submitted On 02-DEC-1999
gusw
Parameterized classes for compile-time type safety is something I always missed
in Java.  This run-time up-casting is a catastrophe! It gets especially bad
since inerited methods are not allowed to return extended types. So consider
this a vote for adding parameterized types into Java.


Submitted On 03-DEC-1999
dkf
Just to add grist to the mill, failure to restrict the type of keys
to a hashtable cost me several weeks work, because I had one
spot where I'd exchanged the key and the value in an insert.
There were no checked errors, and the basic integrity of the
program was maintained; it just produced the wrong answer.
(Well, in fact it never terminated, since the termination condition
depended on a hash-lookup that always failed...)  This little
story just serves to illustrate why type parameterisation leads
to significantly higher quality code; because it helps all us
programmers to say what we *mean* and have the computer
check it for at least some sanity...  :^)


Submitted On 15-DEC-1999
jdcjdc
Primitives are a nightmare to implement in generics (the C++ template fiasco).
In C++, you have to have the C++ source code for a class to use it in a program,

the binary (.obj object) file won't do.
It's easy to support primitives using the wrapper classes: Integer, Double...
Vector<Double> v = new Vector<Double>();
v.add( new Double(1.5) );
v.add( new Double(3.0) );
double d;
d = v.elementAt(0).doubleValue();  // element # 0
d = v.elementAt(1).doubleValue(); //  element # 1
This does require a bit of typing... but that is a small price to pay for 
simple and clean design.


Submitted On 15-DEC-1999
sch1
No, jdcjdc, using wrappers like Integer does not qualify as support for
primatives.
Heap allocations are around 1000 times more costly than an int assignment, and
everytime you want to change the value of a single array element will require a

heap allocation ( and garbage collection of the old value ), since the wrapper
objects
are immutable.  This cost is unnacceptable for a large variety of applications.
If primatives are not supported then the (many) people unwilling to pay this
price will
have to hand code or macro-generate the source for the primative collections, 
then will have to maintain all versions independently or else continuously
regenerate 
them.
That is silly.  I am not the only one who thinks the cost of the wrapper
solution is
exhorbitant.  My class named "IntVector" always has a name collision
whenever I use
it in a JComponent subclass.  Guess what the Sun IntVector does?


Submitted On 29-DEC-1999
ray
The URL no longer works.


Submitted On 07-JAN-2000
dkf
I think you're out of luck since it is an order or two of magnitude
more complex to create a ClassLoader that will perform the
rewriting necessary to handle primitive types.  That's the way
the JVM is implemented.  Furthermore, primitives don't have
methods and are not part of any non-reflexive type relations,
so you would also require the addition of parameterisation
over arbitrary methods, etc.  This is going down the same
road that lead to C++ generics, and that is a real mess.  The
far more restrictive version proposed for Java does not suffer
from these other problems, but it incurs the cost of only
allowing parameterisation over Object types.  There's no easy
way round this so far as I can see.


Submitted On 11-JAN-2000
hwc
Generic types will be useful even if they don't allow you to use primitive
types
but I don't see why they shouldn't.

Given the GJ model, the author specifies class X< A implements Fre