Proposal: Improved Wildcard Syntax for Java
Howard Lovatt
howard.lovatt at iee.org
Tue Mar 17 15:59:03 PDT 2009
2009/3/15 Neal Gafter <neal at gafter.com>:
> My main concern is that this sounds like a significant change to the
> type system, and therefore almost certainly out of scope for project
> Coin.
There is only one change to the type system; which is to allow
covariant assignment, e.g. List<Object> lo = new ArrayList<String>().
This isn't a drastic change, arrays already do this. The other changes
are some new syntax to replace <T extends Type> with <Type T> and the
existing wildcard syntax issues a deprecated warning. This is not a
big change.
> I have no idea how you would specify or implement the proposed
> compile-time diagnostics (such as an error on lo.add(new Object()))
There is no intention to do this, the proposal says exactly the
opposite. Assuming that List<Object> lo = new ArrayList<String>() then
the proposal suggests that lo.add( new Object() ) should be allowed by
the type system.
> or
> runtime type tests (such as the "equivalent of ArrayStoreExceptions").
Nothing to do here. The class either generates an exception upon write
or it doesn't, just like pre-generics. For example if the underlying
store in ArrayList is Object[], as it currently is, then no error on
write. However if the underlying store was from a type factory passed
into the constructor, e.g.:
class List16<E> extends AbstractList<E> {
private Object[] values;
List16(final Class<E> clazz) { values = (Object[])
Array.newInstance(clazz, 16); }
public E get(final int index) { return (E) values[index]; }
public E set(final int index, final E value) {
final E temp = (E) values[index];
values[index] = value;
return temp;
}
public int size() { return values.length; }
}
final List<Object> l16 = new List16<String>(String.class);
l16.set(0, new Object()); // throws ArrayStoreException
Then you will get an ArrayStoreException, because the underlying array
is correctly typed.
> The link with "more details" actually has fewer details than this
> email. I don't see how you plan to make the change backward
> compatible. Without something resembling a specification, it's hard
> to evaluate further.
Nothing is removed, the old syntax still works as before (except you
get a deprecated warning when you use it), hence it is backward
compatible.
Howard.
>
> On Sat, Mar 14, 2009 at 6:41 PM, Howard Lovatt <howard.lovatt at iee.org> wrote:
>> Neal Gafter has proposed replacing the current wildcard syntax with in
>> and out instead of extends and super; an alternative to the current
>> extends/super and Neal's proposal would be to deprecate the current
>> wildcards and to change to the behaviour to that of arrays (covariant
>> only). In particular to change the wildcard syntax to
>> SomeClass<SomeOtherClass> for variables, arguments, or fields, class
>> AClass<AnotherClass T> for classes, and <SomeClass T> for methods
>> where T is compulsory when declaring classes or methods but not used
>> when declaring variables etc. (i.e. exactly like method arguments).
>> This new syntax is similar in behaviour to the current syntax
>> SomeClass<T extends SomeOtherClass> (the difference is that the new
>> does not issue a warning for covariant assignment).
>>
>> This proposal deprecates the concepts of SomeClass<T super
>> SomeOtherClass>, SomeClass<?>, and SomeClass<SomeOtherClass> in the
>> current syntax. Generics are made covariant so that List<Object> lo =
>> new ArrayList<String>() is OK and does not issue a warning (like
>> arrays). If "lo" form the previous example has an object added to it,
>> lo.add( new Object() ), then if this produces an error or not is
>> dependant on the class in question (in the case or ArrayList it
>> wouldn't). See http://www.artima.com/weblogs/viewpost.jsp?thread=222021
>> for more detail.
>>
>> At the same time I propose cleaning up other pain points with
>> generics, in particular:
>>
>> 1. Deprecate raw declarations, new ArrayList() becomes a deprecated
>> warning - you need to say new ArrayList<Object>().
>>
>> 2a. Deprecate self references, you get a deprecated warning for class
>> Type<T extends Type<T>>, you wouldn't use generics in this case.
>>
>> 2b. It follows that <Type<T> T> is an error in the new syntax, see
>> next point for how you would do this.
>>
>> 3. Deprecate the ability to specify multiple bounds, e.g. instead of
>> static <T extends Object & Comparable<? super T>> T max(Collection<?
>> extends T>) you write static <Comparable T> T max(Collection<T>) (note
>> Comparable would not be parameterised with the new syntax since you
>> would almost always want Comparable<Object>).
>>
>> 4. Allow arrays of parameterised types, List<String>[] lsa = new
>> ArrayList<String>[10] is OK (you may get a runtime exception though if
>> you misuse the feature).
>>
>> Examples of use of proposed new syntax are:
>>
>> boolean isAnnotationPresent( Class<Annotation> annotationClass ); //
>> was: boolean isAnnotationPresent( Class<? extends Annotation>
>> annotationClass );
>>
>> static createList( Collection<Number> coll ); // was: static
>> createList( Collection<? extends Number> coll );
>>
>> static <Comparable T> void sort( List<T> list ); // was: static <T
>> extends Comparable<? super T>> void sort( List<T> list );
>>
>> static Enum valueOf( Class<Enum> enum, String name ); // was: static
>> <T extends Enum<T>> T valueOf( Class<Enum> enum, String name );
>>
>> The disadvantage of this proposal is that you can now get the
>> equivalent of ArrayStoreExceptions, the reason that this is acceptable
>> is that ArrayStoreExceptions are rare (I have never had one). For
>> compatibility the existing syntax would still be allowed, but would
>> issue a deprecated warning. The reason that I am proposing deprecating
>> wildcards is that they are not worth the trouble (they have a poor
>> cost/benifit ratio - less is more). I know the language pedants will
>> hate this proposal, but I think the vast majority of Java users would
>> welcome this change.
>>
>> This proposal has some overlap with the proposal to infer generic
>> types in that they both concern generic declarations, but are
>> otherwise orthogonal. The collections library, in particular methods
>> like sort (see above) and interfaces like Comparable, and enum class
>> would need updating to the new syntax and this new library would have
>> to be supplied as a module so that old code could use the old library
>> (nt 100% compatible).
>>
>> So I am proposing eventually removing something from the language
>> (actually replacing) - is removing a feature a first on coin-dev?
>>
>>
>
> ______________________________________________________________________
> This email has been scanned by the MessageLabs Email Security System.
> For more information please visit http://www.messagelabs.com/email
> ______________________________________________________________________
>
More information about the coin-dev
mailing list