Covarianza y contravarianza (ciencias de la computación)

De Wikipedia, la enciclopedia libre

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.[1][2]

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

Formalización[editar]

Sean y dos tipos simples en un sistema de tipos, y sean e dos tipos construidos sobre y respectivamente. Si es una relación de orden que indica subtipado, y además , se dice que:[2]

  • es covariante si
  • es contravariante si
  • es invariante si no es covariante ni contravariante.

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

Historia[editar]

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

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

Referencias[editar]

  1. a b c John C. Reynolds (1981). North-Holland, ed. The Essence of Algol. Symposium on Algorithmic Languages. 
  2. a b c Giuseppe, Castagna (1996). Object-Oriented Programming A Unified Foundation. Birkhäuser Boston. p. 154–155. ISBN 9781461241386. OCLC 840279585. 
  3. «Variances | Scala Documentation». docs.scala-lang.org. Consultado el 8 de octubre de 2017. 
  4. a b «Generics: in, out, where - Kotlin Programming Language». Kotlin. Consultado el 8 de octubre de 2017. 
  5. Howard, Mark; Bezault, Eric; Meyer, Bertrand; Colnet, Dominique; Stapf, Emmanuel; Arnout, Karine; Keller, Markus (abril de 2003). «Type-safe covariance: Competent compilers can catch all catcalls». Consultado el 8 de octubre de 2017. 
  6. Luca Cardelli (1984). Springer, ed. A semantics of multiple inheritance. Semantics of Data Types (International Symposium Sophia-Antipolis, France, June 27 – 29, 1984). Lecture Notes in Computer Science 173. doi:10.1007/3-540-13346-1_2.  (Versión ampliada en Information and Computation, 76(2/3): 138-164, febrero 1988)
  7. Allison. «What's New in Standard C++?». Archivado desde el original el 27 de mayo de 2012. Consultado el 8 de octubre de 2017. 
  8. Sanghera, Paul (30 de noviembre de 2006). SCJP Exam for J2SE 5: A Concise and Comprehensive Study Guide for The Sun Certified Java Programmer Exam (en inglés). Apress. p. 140. ISBN 9781430201731. Consultado el 8 de octubre de 2017.