Introduce Covariance/Contravariance at declaration site for Java 9 ?

Andrey Breslav andrey.breslav at jetbrains.com
Sat Oct 27 09:35:16 PDT 2012


Looks like a decent practical solution. An IDE would make it a breeze to put all those wildcards in.

On Oct 27, 2012, at 20:22 , Brian Goetz wrote:

> This is definitely worthy of exploration.  And, the good news is, it can be entirely implemented using a JSR-308 checker -- so (at least initially) no javac changes are required to develop and validate the concept.  This fits nicely into the use of annotations as a means of capturing design intent, and enabling tools to verify design intent.
> 
> (Its bad enough we make these mistakes; its worse that some of these then cannot be corrected because of compatibility concerns.)
> 
> On 10/27/2012 6:19 AM, Remi Forax wrote:
>> I've maybe found a solution :)
>> 
>> First, it's not possible to let the compiler do the transformation
>> automagically because
>> in that case adding a default method to a function interface may break a
>> lot of user code.
>> A function interface that is inherently co/contravariant should be
>> declared as such in its declaration.
>> 
>> Removing the burden for the user to write wildcard is a nice goal, but
>> it means that
>> the Java type system will be inherently more complex and it may not
>> worth to add such
>> complexity for little benefit.
>> 
>> The issue is that users that creates API forget to add wildcards, so the
>> practical solution is to
>> add a lint option to javac that warn user when they use a
>> co/contravariant function interfaces
>> without specifying wildcards.
>> This solution doesn't change the type system so it can be implemented
>> without pain and fear of corner cases.
>> 
>> Here is the proposal:
>> - adds two new type annotations (as defined by JSR308) in
>> java.lang.annotation, Covariant and Contravariant,
>> that applies on type variables. These annotations are not inherited.
>> - add a new lint pass to javac that checks parameters of methods (not
>> returns type, you should not use wildcards
>> on return type). If a type of a parameter is a parametrized type with
>> type variables annotated with Covariant
>> (resp. contravariant), emit a warning is the parametrized type is not a
>> ? extends X (resp. ? super X).
>> 
>> so by example, the function interface Mapper will be declared:
>>   interface Mapper<@Covariant U, @Contravariant T> {
>>     public U map(T element);
>>   }
>> and Iterator and Iterable can be retrofitted like this:
>>   interface Iterator<@Covariant T> { ... }
>>   interface Iterable<@Covariant T> { ... }
>> but ListIterator, that inherits from Iterator can not have it's
>> parameter T declared as covariant
>> because ListIterator defined methods add and set that takes a T as
>> parameter
>> (that's why annotations @Covariant/@Contravariant should be declared are
>> not inheritable).
>> 
>> now if in a class there is a method declared like this:
>>   static <T, U> Iterator<U> mapIterator(Iterator<T> iterator, Mapper<U,
>> T> mapper) { ... }
>> the compiler will emit two warnings because the parameter iterator
>> should be an Iterator<? extends T>
>> and mapper should be a Mapper<? extends U, ? super T>.
>> 
>> The only open question is does lint should accept to tag a type
>> parameter with @Covariant/@Contravariant
>> even if the type parameter appear in method of the interface at position
>> it should not. C# does that.
>> 
>> cheers,
>> Rémi
>> 
>> On 10/18/2012 09:25 PM, Kevin Bourrillion wrote:
>>> FTR, I agree fairly strongly with everything Dan says here.
>>> 
>>> 
>>> On Thu, Oct 18, 2012 at 12:20 PM, Dan Smith <daniel.smith at oracle.com
>>> <mailto:daniel.smith at oracle.com>> wrote:
>>> 
>>>    I think it's a good idea, at least worth serious consideration.
>>> 
>>>    There would be no _requirement_ to design libraries in
>>>    declaration-site-friendly ways, but the fact is we already have
>>>    _lots_ of types that are inherently co-/contra- variant, and the
>>>    "right" way to use those types is to always use a wildcard.  It
>>>    turns into a mechanical transformation that obscures the code
>>>    behind layers of wildcards and pointlessly punishes users if they
>>>    mess up; it would sure be nice to remove that burden from clients
>>>    of variant types.
>>> 
>>>    Anyway, I can say it's on the radar.  But maybe we will conclude
>>>    it's a horrible idea; or maybe other things will take priority.
>>> 
>>>    —Dan
>>> 
>>>    On Oct 15, 2012, at 6:24 PM, Joshua Bloch <josh at bloch.us
>>>    <mailto:josh at bloch.us>> wrote:
>>> 
>>>    > I believe that declaration site variance annotations are every
>>>    bit as bad as use-site annotations.  They're bad in a different
>>>    way--they force you to write idiosyncratic types because natural
>>>    types don't lend themselves to fixed variance restrictions--but
>>>    they're still bad. Providing both use and declaration site
>>>    variance in one language is the worst of both worlds (unless
>>>    you're trying to kill the language).
>>>    >
>>>    >     Josh
>>>    >
>>>    > On Mon, Oct 15, 2012 at 3:09 PM, Remi Forax <forax at univ-mlv.fr
>>>    <mailto:forax at univ-mlv.fr>> wrote:
>>>    > I've just read the presentation of Stuart Marks at JavaOne [1],
>>>    > all examples after slide 32, the first one that use lambdas are
>>>    not written correctly
>>>    > because all method signatures do not use wildcards.
>>>    >
>>>    > Brian, I know that we will not be able to introduce
>>>    covariance/contravariance
>>>    > at declaration site for Java 8, so the solution we will deliver
>>>    will be far from perfect
>>>    > because nobody understand wildcards.
>>>    > Is there a way to free Dan and Maurizio  enough time to
>>>    investigate if
>>>    > covariance/contravariance can be added to Java 9.
>>>    >
>>>    > Rémi
>>>    > [1]
>>> 
>>> https://stuartmarks.wordpress.com/2012/10/07/javaone-2012-jump-starting-lambda-programming/
>>> 
>>>    >
>>>    >
>>> 
>>> 
>>> 
>>> 
>>> --
>>> Kevin Bourrillion | Java Librarian | Google, Inc. |kevinb at google.com
>>> <mailto:kevinb at google.com>
>>> 
>> 

--
Andrey Breslav
http://jetbrains.com
Develop with pleasure!




More information about the lambda-libs-spec-experts mailing list