Covariance And Contravariance - A Simple Guide
Written by Mike James   
Friday, 20 November 2020
Article Index
Covariance And Contravariance - A Simple Guide
Object Hierarchies
Why Bother?

What's the point?

Now you understand the idea of covariance and contravariance you might be wondering what the point is?

The answer is that it is all a matter of when a language, or a language implementation, should, or could, allow automatic type conversion.

As array construction is covariant, if T(B) constructs an array of type B, it is fairly safe to treat an array of B as being an array of A without needing an explicit type conversion.

In many languages you can indeed write:

string[] x=new string[];
object[] y=a;

without the need for a cast and this is because object>string implies object[]>string[]. 

For a more involved example consider the C# delegate.

A delegate is a type that can wrap a function with a specific signature. A delegate accepts a function as input parameter and returns a delegate type that wraps it.

Consider a delegate

delegate Mydelegate(functionB);

and two functions which only differ in the type of their input parameter then A>B implies by contravariance:

functionA(A param)<functionB(B param);

Hence functionA can be used anywhere functionB can and so it should be safe to use Mydelegate to wrap an instance of a function that has parameters that are less derived than it.

By a similar argument a delegate:

delegate Mydelegate(A function);

which wraps a function which returns an A should be quite safe wrapping a function that returns a B as A>B implies by covariance that A function>B function and so you can use a B function anywhere you can use an A function. Thus delegates are covariance in the return parameter of the function they wrap and so can safely wrap a function that returns a more derived result.

Is it worth it?

Is it worth introducing what appear to be complex ideas like covariance and contravariance?

In practical work probably not as the whole thing is usually simple enough to work out from first principles.

For example, can an array of strings be used in place of an array of objects?

Well yes obviously as a string is just an object with additional properties and methods so it can always be treated as an object.

So if you want to just think about type conversion and substitution rules from first principles that's fine. If you want to dress the idea up in the terms covariance and contravariance that's fine too.

However, the academic terms do have the disadvantage that it's easy to miss practical concerns.

Languages have to be pragmatic and this means they don't always obey the substitution principle.

For example a double can always be used where an integer can be used - e.g. write 1.0  in place of 1 but in practice it it rare for a language to define a double as a derived type of int.

For another example, consider the array of string types. If this is cast to an array of object types then this works for all read access but write access often fails. For example, try

string[] mystring=new string[10];
object[] myobject=mystring;
object[5]=123;

in most languages this will fail because the underlying type of the object element is string and not object but by the substitution principle it should work. In this case it is a result of inheritance not being implemented fully, i.e. an array of strings isn't really an array of objects with some additional properties.

In practice programming is more complicated and messy that pure theory allows.

Look out for a follow-on article that explains covariance and contravariance in C# in more detail.

arrowscontraandco

Related Articles

Strong typing

Casting – the escape from strong typing

Introduction to Delegates

Barbara Liskov Admitted to National Inventors Hall of Fame       

   

To be informed about new articles on I Programmer, sign up for our weekly newsletter, subscribe to the RSS feed and follow us on Twitter, Facebook or Linkedin.

 

Banner


Open Platform For Enterprise AI Launched
18/04/2024

A new platform aimed at building and supporting an open artificial intelligence (AI) and data community has been launched.  The Open Platform for Enterprise AI (OPEA) was announced by The Linux F [ ... ]



Interact With Virtual Historic Computers
14/04/2024

Alan Turing's ACE computer is a legendary computer that is particularly special for I Programmer - our account of it was the first ever history article on the site when it launched in 2009. Now this i [ ... ]


More News

raspberry pi books

 

Comments




or email your comment to: comments@i-programmer.info

 

<ASIN:1871962439>

<ASIN:1871962587>

 



Last Updated ( Friday, 20 November 2020 )