Suggestions for Java Generics Semantics in Java Version 7.0 (original) (raw)
Jaisimha Narahari jcnarahari at yahoo.com
Wed Jun 10 23:44:41 PDT 2009
- Previous message: Suggestions for Java Generics Semantics in Java Version 7.0.docx
- Next message: Suggestions for Java Generics Semantics in Java Version 7.0 - W/O Attachments
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
I found that my previous post showed up without the attachment I'd sent, so I am posting again w/o the attachment, having transferred its contents directly into this post.
It is a bit of a read, and contains also some explanations that systems guys working on JDK 7 do not really need. Because it comes from an applications developer in Bangalore (I am not a systems guy). I hope you all will patiently read it. Here goes:
I sincerely feel that the OO paradigm has suffered a setback with Backward Compatibility support in Java 5.0, for Raw Types in java.util.Collections of Previous Java Versions.
Especially the sacrifices made w.r.t the semantics of Generics in Java 5.0 to accommodate this interoperability with Legacy Code of previous Java versions.
So I am making suggestions for correcting the situation with Java 7.0.
I have included the arguments in favor of my suggestions.
I definitely hope that these will be looked into, and even implemented, if there is no flaw in my arguments, and if bigger constraints do not forbid them from being incorporated into Java 7.0.
Here's hoping.. :
Suggestions for Java Generics Semantics in Java Version 7.0
It seems to me that in the interest of Backward Compatibility with Raw Types of java.util.Collections in versions previous to Java 5.0, the robustness of Generic Types introduced in Java 5.0 has been sacrificed.
In order to make Generic Types of Java 5.0 inter-operable with Raw Types of java.util.Collections in versions previous to Java 5.0, "Erasure" has been resorted to. Erasure basically refers to the discarding of the type info of Type Parameters of Generic Types at runtime, so that a Generic Type at run time is identified only by its Base Type.
This means, for example, that a variable declared as of type List at compile time is considered merely as a variable of type “List”, in order that it can be assigned/ passed as argument to another variable in Legacy Code which is also of type” List” (A Raw Type).
Raw Types, since they discard all type checking on the type of their contained elements, contribute to total loss of Type Safety in Java, which is the very reason that java.util.Collections classes in Java 5.0 were made Generic.
The issue here is whether interoperability with legacy code is a sufficient enough justification to sacrifice Type Safety, given that this provision has also resulted in the following two contrived rules in the operation of Generic Types in Java 5.0:
(1) For the sake of determining Type Hierarchy of Generic Types, the Type Parameters are not to be considered. That is, code such as the line below is rejected by the compiler:
List lo = new ArrayList;
even as pure OOPS principles allow an Integer to be recognized as an Object.
In Java 5.0 Generics, List and List are treated as
totally unrelated types by the above rule, not only violating the
purity of OOPS but also sacrificing type system robustness.
(2) As a direct consequence of the above rule, any kind of Array Creation
involving Generic Types, such as List [], List [], E[], etc also get forbidden, on account of the fact that Arrays are "Reified" types, implying that they carry over their full type info into the Runtime, and are therefore aware of the type of their contained elements at runtime, in direct contrast to Generic Types, which, because of Erasure, discard the knowledge of the type of their contained elements (i.e., Type Parameters) and are therefore "non-reifiable" types.
[However, the expression E[] can be used, (without “new” used for its creation), to specify an array of ANY REGULAR TYPE, not Generic Type. This syntax therefore is not really one to be associated with Generic Types].
Having introduced Generic Types for the very purpose of Type System Robustness, in the interest of Backward Compatiblity with Raw Types of previous Java versions, Java 5.0 is promptly losing that very advantage provided by Generic Types, for which they were introduced in the first place.
To be fair, Java 5.0 also provides a "patch up" API in the classes provided by java.util.Collections.checkedXXX classes, which try to reverse the effects of Erasure by carrying over the type info of Type Parameters of Generic Types also into the runtime, by separately providing reflection ".class" types of the Type Parameters as part of the checkedXXX classes.
While this provision re-ensures type safety w.r.t. its loss due to erasure, there is no compensation concerning the above two "makeshift" rules that end up greatly restricting Java from having a very robust, elegant Type System, wherein Parameterized Types could enjoy the same status as any other type, without getting quirks and twists in their usage imposed upon them.
The evolution of a programming language should not forever be constrained by the sins of its past versions, which in this case translates to the existence of Raw Types, and consequent necessity to inter-operate with Legacy Code making use of these Raw Types.
Therefore, in the interest of Type System Robustness (which seems to me to be of higher priority in the longer term, in comparison to any immediate need for Backward Compatibility which constricts the language from breaking the "mold" to make true progress), I would like to put forward these suggestions:
From Java Version 7.0, going forward:
(1) "Deprecate" Raw Types
(2) Remove Backward Compatibility provision and therefore convert
"Erasure" to "Reification" for Generic Types, the consequence of which
will render the above two rules for the usage of Generic Types unnecessary, making all types provided by the language behave
uniformly, most especially without violating OOP principles in what is essentially an OOP Language.
Legacy code can still make use of JDK up to Java version 6.0 for inter-operability, with support removed from Java 7.0.
An important point to note in this regard is that Java will continue to violate OO principles (at least according to OO purists) by having a single root super class called "Object" for all of its types, both related types and unrelated types.
This has in fact been responsible for type mismatches in code leading to both compile time and runtime errors such as ClassCastException, ArrayStoreException, etc.
This provision introduced from Java's inception is ARGUABLY a REQUIRED VIOLATION of OO in the interests of pragmatism, and has served its purpose well, just as similar violations of OO Principles in the implementation of "Enums" in Java 5.0 are (maybe) REQUIRED for similar pragmatic reasons.
It will rock the foundations of Java's API to try and have separate class hierarchies for unrelated types, and so the single super class "Object" for all types will have to remain.
Enums and their implementation have only furthered the interests of Type Safety. Violations of OO in the internal implementation of Enums is based upon straitjacket constraints that must be applied to what can be allowed in the developer's domain, with the system enforcing a good portion of the behavior of Enums to make them work. Allowing full OO programming freedom with Enums to developers would have implied unworkable language semantics.
Therefore the nearest thing to "ideal" OO that Java can now achieve in practice, is with the implementation of the above two suggestions in Java 7.0. Java must only then continue to evolve from there.
Thanks for your patience.
- Previous message: Suggestions for Java Generics Semantics in Java Version 7.0.docx
- Next message: Suggestions for Java Generics Semantics in Java Version 7.0 - W/O Attachments
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]