Covarianza y contravarianza (ciencias de la computación)
# Covarianza y contravarianza (ciencias de la computación)

La covarianza y la contravarianza son propiedades de la relación entre dos tipos compuestos, e indican si se mantiene o se invierte la relación de orden entre los tipos que los componen. Tienen especial relevancia en el diseño de lenguajes tipados, puesto que determinan cuándo es posible sustituir un tipo determinado por un subtipo o un supertipo.

Sea por ejemplo un sistema de tipos en el que int y float identifican a los números enteros y racionales, respectivamente, que además guardan una relación de orden int ≤ float, indicando que int es un subtipo de float. Sea también int⟶ el tipo de una función que acepta un parámetro de tipo int. Si el sistema de tipos permite usar una función float⟶ en cualquier lugar donde se necesita una función int⟶, se dice entonces que las funciones son contravariantes en los argumentos, puesto que float⟶ ≤ int⟶ y en el tipo compuesto se invierte la relación de orden entre los tipos simples int ≤ float. Si en cambio se tiene una función ⟶float que devuelve un racional, y el sistema de tipos permite usar una función ⟶int que devuelve un entero en su lugar, entonces ⟶int ≤ ⟶float, y se dice que las funciones son covariantes en los valores de retorno.

En los lenguajes modernos se suele hablar de varianza, y aplica no sólo a las relaciones de subtipado entre funciones libres, si no también a cómo funciona la especialización de métodos en subclases, o a cómo de restrictivos son los parámetros en los tipos compuestos que contienen genéricos.

## Formalización

Sean $A$ y $B$ dos tipos simples en un sistema de tipos, y sean $I{<}A{>}$ e $I{<}B{>}$ dos tipos construidos sobre $A$ y $B$ respectivamente. Si $\leq$ es una relación de orden que indica subtipado, y además $A{\leq }B$, se dice que:

* $I$ es covariante si $I{<}A{>}\leq I{<}B{>}$
* $I$ es contravariante si $I{<}B{>}\leq I{<}A{>}$
* $I$ es invariante si no es covariante ni contravariante.

e $I$ se denomina en este contexto una frase o constructor de tipos. Nótese que si $I$ se construye con más de un parámetro puede ser covariante o contravariante de forma indistinta en cada uno de ellos.

## Historia

Aunque no con la nomenclatura actual, el concepto ya fue descrito por John C. Reynolds en ALGOL68 y aplicado por Luca Cardelli a su modelo orientado a objetos. Giuseppe Castagna usa ya la nomenclatura moderna en su estudio sobre los fundamentos de la orientación a objetos.

C++ incluyó métodos covariantes en los tipos de retorno en su modelo de herencia en 1998, y Java hizo lo propio en su versión 1.5 liberada en 2004.

