Friday, December 28, 2007

Covariant Return and Contravariant Arguments

Covariant Return and Contravariant Arguments

As we know, to a variable of function type may be assigned a closure with compatible return type and compatible argument types. "Compatible return type" means that the type is either the same as in function type or is a subclass of this type (return types are covariant).

  { => Number } p1 = 
    { => Integer.valueOf(19) };  // Integer is a subclass of Number
  { => Number } p2 = 
    { => Double.valueOf(1.25) };  // Double is a subclass of Number
  

"Compatible argument type" means that the argument type is either the same as in function type or is a superclass of this type (argument types are contravariant).

  { String => void } p = 
    // Object is a superclass of String
    { Object o => System.out.println(o); };
  

We can combine covariant return with contravariant arguments:

  { String => Number } p = { Object o => Integer.valueOf(o.hashCode()) };
  System.out.println(p.invoke("haf"));
  

These rules define hierarchy on function types. So a function type might be a subtype or supertype of another function type. For example, { => Integer } is a subtype of { => Number } and { String => void } is a supertype of { Object => void }. As for class types, to a variable of function type may be assigned an object (closure) of its type or any subtype.

What is meant by covariant and contravariant?
Let S and T be two types (classes or function types) such that S is a subtype of T. If method m of T is overridden in S, then the corresponding types from the m's signature can either preserve the relationship between S and T (i.e. the type used in S is a subtype of the corresponding type in T), reverse this relationship (i.e. the type used in S is a supertype of that in T), or neither preserve nor reverse this relationship. If they preserve the relationship of S and T, we say they are covariant, and if they reverse the relationship of S and T, we say they are contravariant.

8 comments:

Hamlet D'Arcy said...

The covariant works fine for me unless I specify an Object as the type.... then my closure starts yielding null all the time.

Is there a forum to discuss this on?

Do you know why the following produces 19, 19, null?

public class Example {

  public static void main(String[] args) {
    { => Integer } one = { => Integer.valueOf(19) };
    System.out.println(one.invoke());

    { => Number } two = { => Integer.valueOf(19) };
    System.out.println(two.invoke());

    { => Object } three = { => Integer.valueOf(19) };
    System.out.println(three.invoke());
  }
}

Zdeněk Troníček said...

It works under the previous version (2007-11-30) so it is probably a bug in the latest version.

Neal Gafter said...

Hamlet: thanks for the bug report. Now fixed.

hbrednek said...

I don't understand this. In particular, the statement is made that argument types must be contravariant. As I understand this then if I specify, for example, that an argument should be of type javax.naming.directory.SearchResult because I expect to invoke its member function getAttributes() in the closure, I can pass an actual instance of javax.naming.NameClassPair which is a supertype of SearchResult. This makes no sense, as NameClassPair has no getAttributes() method to invoke. HELP!

Zdeněk Troníček said...

Hi Mike,

"contravariant arguments" are not used when you call the closure but when you assign a closure to a variable of function type.

For example, the p variable is a reference to a closure that has a single argument of type String:

{ String => void } p;

And we are allowed to assign to p a closure that takes an argument of type Object:

p = { Object o => System.out.println(o); };

Why? Because String is Object. So, when you call a closure with a String argument, this argument can be safely passed to the referenced closure.

Alat Bantu Romantis Warga pria wanita said...

kami penyededia informasi alat bantu sex.
sekaligus jual alat sex wanita.
alat bantu sex pria.
semua alat seks ada pada kami.
sex toys terbaru.

Alat Bantu Romantis Warga pria wanita said...

nie job.

sameer said...



Nice blog. I Love reading all your blog post. it feels so nice and enjoying reading your blogs.

https //www.twitch.tv/activate