Forum Stats

  • 3,853,788 Users
  • 2,264,269 Discussions
  • 7,905,444 Comments

Discussions

Covariance vs. Generics

843793
843793 Member Posts: 41,732 Green Ribbon
edited Sep 20, 2002 5:21PM in Generics
I've been seeing a lot of discussion about covariance and generics around the forums and it seems to me that generics and covariant return types totally separate concepts. It seems to me that covariance and generics can be used to achieve some of the same goals but that they are not inherently tied to each other. Is this a correct assesment? It also seems to me the covaraince would be much easier to add to Java than generics and I can't really think of a reason not to add it. Any comments?
«1

Comments

  • 843793
    843793 Member Posts: 41,732 Green Ribbon
    I agree. Generics and covariant return types, while they achieve the same thing (the compiler hides the casts from you), are totally independent.

    Adding covariant return types is backwards compatible and seems a fairly easy change (compiler change?). I think covariant return types are a good idea compared to generics (which will require a JVM change) which I think is overkill.

    So I think Sun should change their RFE evaluation for covariant return types from "Maybe as part of a generic types proposal we could deal with this" - They are not the same!
  • 843793
    843793 Member Posts: 41,732 Green Ribbon
    There are no JVM changes required for generics. But you're right: the two ideas are separate, and generics are a much heavier and more complicated idea than covariance.

    Covariance is harmless. It really should have been there from the beginning, because it just makes sense. The fact that it requires the compiler to generate extra hidden method signatures points to a flaw in java bytecode, since the language really should have been designed for it from the beginning.

    Generics are a new feature (at least for Java). The limited implementation we have right now doesn't include primitives, which again reflects the fact that the language wasn't originally designed to have them. But it's still a valuable feature.

    They both should exist, but covariance should have existed a long time ago.

    Interestingly, one feature that Java originally was designed to have, but now never will, is Design by Contract.
  • 843793
    843793 Member Posts: 41,732 Green Ribbon
    There are no JVM changes required for generics
    Your probably right, I just thought I read somewhere that a JVM change was needed because of reflection?
  • 843793
    843793 Member Posts: 41,732 Green Ribbon
    I'm not aware of any - and I am aware of them going to great lengths to make sure it didn't happen.

    However, it's entirely possible that an updated VM would help to make it efficient?
  • 843793
    843793 Member Posts: 41,732 Green Ribbon
    Which problem do generics attempt to resolve? All the answers answer the �how to?� question but not �what for?� question. I tried to figure out what the problem do generics address and haven�t found anything except this:
    The main benefit of adding generics to the Java programming language lies in the added expressiveness
    and safety that stems from making type parameters explicit and making type casts implicit. This is
    crucial for using libraries such as collections in a
    exible, yet safe way.


    In other words they address ONLY collection problems. But I still can't find enough arguments for genetics. All they (contributors) do is trying to ensure java community that generics will not harm to java.

    2.1 Please describe the proposed Specification:
    A specification for extending the Java programming language with generic types. Ultimately, the Java Language Specification should be revised to integrate the proposed changes. The proposed specification will include language changes. If necessary, it may contain class file format changes needed to implement it. These would require Java Virtual Machine* Specification updates as well.
    � this does not describe the proposal specification; this just states that some changes are needed to satisfy someone�s proposal.
    2.2 What is the target Java platform? (i.e., desktop, server, personal, embedded, card, etc.) All platforms � The fatter JVM (for embedded systems), the worse.
    2.3 What need of the Java community will be addressed by the proposed specification?
    Many programs and libraries written in the Java (tm) programming language are intrinsically generic. However, the Java programming language lacks the ability to specify generic types. As a result, programs are unnecessarily hard to read and maintain, and are more likely to fail with runtime type errors. This feature is one of the most frequently requested language extensions on the JDC (no. 7 on the bug parade - no. 2 among language extensions).
    Templeted code isn't easy to read too. People ask for this feature, because Java doesn�t support co-variants.
    2.4 Why isn't this need met by existing specifications?
    This can only be addressed at the language level, i.e., by the Java Language Specification.
    . Co variants don�t require any changes at all.
    2.5 Please give a short description of the underlying technology or technologies:
    C1) Upward compatibility with existing code. Pre-existing code must work on the new system. This implies not only upward compatibility of the class file format, but also interoperability of old applications with parameterized versions of pre-existing libraries, in particular those used in the platform library and in standard extensions. .
    . Co variants don�t require any changes at all.
    C2) Upward source compatibility. It should be possible to compile essentially all existing
    Java language programs with the new system.
    . Co variants don�t require any changes at all.
    C3) Timeliness. The revised system should be plausibly implementable in a reasonable time frame, without imposing an undue burden on vendors of virtual machines, IDEs and compilers. As the amount of code written in the Java programming language expands, the effort involved in upgrading to the revised language expands as well. Hence it is the interest of the Java community that any extensions should be made available quickly.
    . Co-variants don�t require any changes at all.
    C4) Support for migration of existing APIs. It should be possible to parameterize existing APIs
    without undue pain. In particular, there should be a clean, demonstrable migration path
    for the Collections APIs that were introduced in the Java 2 platform.
    . Co-variants don�t require any changes at all.
    C5) Insofar as possible, the design of generic classes should not introduce non-obvious or far-reaching changes in other parts of the language. I hope.
    C6) Preservation of performance of existing code. The performance of non-generic programs written in the Java programming language should not be materially influenced by the presence of the generic extension. At most, a penalty of 1-2% in space or time might be acceptable. They�re going to slow down existing code, for more interesting concept see below.
    C7) Preservation of the spirit of the Java programming language. The generic language should integrate well with the existing design and philosophy of the Java programming language. Co-variants are the philosophy of java, templates may not preserve it.
    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.
    10% PERFORMANCE PENALTY? Good performance? Aren't they crazy?

    When they talk that changes for users are minimal and more essential changes are required in JWM I think at first to those who support bytecodes running natively embedded devices, on silicon. Java becoming standard to these systems and making Java JVM fatter will abort big segment of marked from java. Co variants can solve the same problem without any neither speed nor memory (chip area) loss.
    In addition to performance fall, generics actually do not solve the problem they are addressed! In the case you transfer collection with ObjectStreams, you can get Runtime fault anyway, or I�m mistaken?

    I have some experience of covariant-style programming; it is the only way to extend collections in Delphi. The only disadvantage is that this approach leads to a bit more lines of code than using templates. From the other side it is simpler to read.
    So, co-variants and generics address different problems? Yes, generics solve subset of problems referred to collections, co-variants solve more general problem, and using co-variants you may make your code more reliable extending existing classes restricting return type to more specific. AND THEY DO WITH MUCH LESS BLOOD! No changes neither in specification nor in JVM required, no compatibility problems, no performance slow down, no JVM weighting, just a need to repair bug in compiler. I think that if java implementers would implement co-variants at first step then nobody proposed for generics afterwards. Which general contract do co-variants break that it is impossible to adopt them without generics?
  • 843793
    843793 Member Posts: 41,732 Green Ribbon
    The current proposal (which is the outcome of the JSR you quote) requires only minor changes in the JVM and imposes negligible performance penalties. So your concerns about performance or fatter JVMs are unwarranted.
    Although for most people collections may be the main or even only beneficiary of generics, their ubiquity means that this is not a minor gain.
  • 843793
    843793 Member Posts: 41,732 Green Ribbon
    valjok, a lot of the areas where you've written "Co variants doesn't require any change at all" this is also true for generics.
    No changes neither in specification nor in JVM required, no compatibility problems, no performance
    slow down, no JVM weighting, just a need to repair bug in compiler.
    Actually, the bug is in the JLS, so it does require a change in the specification.
    I think that if java implementers would implement co-variants at first step then nobody proposed for
    generics afterwards.
    Maybe, maybe not. If you're right, I'm glad covariance wasn't in Java 1.0, because some of the stuff I'm doing ATM requires generics and can't be done solely with covariant return types.
  • 843793
    843793 Member Posts: 41,732 Green Ribbon
    Is it so hard for you to type 2 lines of code and use natural way to extend a collection?
    public class MyCollection extends java.util.ArrayList    {
     public void add(MyObject o) { super.add(o); }      
     public MyObject get(int index) { return (MyObject)super.get(index); }    
    }
    It's simple, it's natural OOP approach and consistent with Java spirit. Templates are hostile. What is the application of generics, where they are so highly required?
  • 843793
    843793 Member Posts: 41,732 Green Ribbon
    YATArchivist, Explain me, please, it it really so hard for you to write 2 lines of code to extend collection?
    It is standard tecnitue you use in languages which don't support templates. Both address the same problem but covariance is more general and cheap solution.
  • 843793
    843793 Member Posts: 41,732 Green Ribbon
    It usually takes many more than just two lines to extend a collection to be fully type specific. Also if you base it on the standard collection classes, you can still add any type of object (and you still need covariance to override get() in the manner you suggest). So you either need to delegate all methods to the standard collection (adding an extra object) or you have to develop a new set of collection classes where most methods are protected and intended to serve as the parent for type safe collections. Unfortunately doing this loses compatibility with existing code.

    Conside just the basic Collection interface.
    add(Object o)
    addAll(Collection c)
    contains(Object c)
    containsAll(Collection c)
    remove(Object o)
    removeAll(Collection c)
    retainAll(Collection c)
    Iterator iterator()

    That is at least 8 methods which ought to be replaced. Ideally the toArray methods should be fixed as well.

    Also unlike the type erasure performed by the current generics proposal, writing your own type safe wrappers will result in additional runtime classes and code bloat.
This discussion has been closed.