oop programming-languages scala haskell functional-programming

oop - Genéricos y polimorfismo restringido versus subtipo



programming-languages scala (4)

¿Cómo los genéricos y el polimorfismo restringido hacen que el subtipo no sea necesario?

No se sabe que lo hacen. Si pone la diapositiva en contexto, creo que el argumento que el orador estaba tratando de hacer es algo como esto:

  • En los viejos tiempos, los subtipos proporcionaban un importante tipo de polimorfismo.

  • También en los viejos tiempos, en otro país, la abstracción de tipo y los parámetros de tipo proporcionaban un tipo importante de polimorfismo. Este tipo es conocido en su tierra natal como polimorfismo paramétrico , pero en tierras extranjeras se le llama genéricos .

  • Los genéricos modernos admiten restricciones, a veces llamadas "polimorfismo acotado", que pueden lograr muchas de las mismas cosas que el polimorfismo de subtipo.

  • Subtimar conlleva una cantidad considerable de equipaje; en particular, debe preocuparse por la covarianza y la contravarianza. Los idiomas terminan con restricciones incómodas, notaciones de peso pesado y, a veces, violaciones de seguridad directas (por ejemplo, Eiffel).

La pregunta abierta: tal vez el polimorfismo paramétrico restringido resuelve suficientes de los mismos problemas que en el futuro feliz, podemos eliminar por completo el polimorfismo de subtipo, y con ello la pregunta desagradable de cuándo el subtipo es covariante, contravariante e invariante.

En esta presentación en PDF sobre Clases de tipos de Haskell, la diapositiva # 54 tiene esta pregunta:

Pregunta abierta :

En un lenguaje con genéricos y polimorfismo restringido, ¿también necesita subtipos?

Mis preguntas son:

  1. ¿Cómo los genéricos y el polimorfismo restringido hacen que el subtipo no sea necesario?

  2. Si los genéricos y el polimorfismo restringido hacen innecesarios los subtipos, ¿por qué Scala tiene subtipos?


2 es fácil: porque lo tiene Java (y código de bytes JVM). Si queremos llamar a Scala desde Java de manera útil, tenemos que permitirnos extender las interfaces y clases de Java; y si las clases de Scala se traducen a clases JVM (y rasgos a interfaces), también podemos extenderlas.

La misma razón por la que Scala tiene null :)

En cuanto a 1, también necesita tener tipos existenciales para codificar el

Num bar(Bool x)

caso:

bar :: Bool -> exists a. Num a


Bueno, si esa es realmente una pregunta abierta, entonces, por definición, no sabemos la respuesta al # 1. Los espacios de diseño son bastante diferentes, y no es obvio para mí cómo podría codificar directamente el subtipo en polimorfismo restringido. La codificación es directa cuando los argumentos son polimórficos. Por ejemplo, una función Haskell con tipo

foo :: (Num a) => a -> Bool

es equivalente a, digamos:

Bool foo(Num x)

en un lenguaje OO. Sin embargo, no está claro cómo codificar:

// I will return some Num, but I''m not going to tell you what kind exactly Num bar(Bool x)

en el polimorfismo restringido, ni está claro cómo codificar:

-- I can return any kind of Num, *you* tell *me* what kind bar :: (Num a) => Bool -> a

en subtipos.

Mi mejor conjetura para el # 2 es que Scala tiene que hablar con Java, y Java habla sobre subtipos. Y porque Scala tiene todas las características del sistema de tipos conocidas por el hombre porque piensa que tiene que ser así para ser cool. :-PAG


El "Sistema de objetos pasados ​​por alto de Haskell" de Oleg Kiselyov y Ralf Lämmel propone una biblioteca para Haskell que implementa un sistema de objetos utilizando las características existentes de Haskell, incluidas las clases de tipos.

Un extracto de la sección de "introducción" del documento (énfasis mío):

El interés en este tema no se limita en absoluto a los investigadores y profesionales de Haskell, ya que hay una pregunta fundamental e inestable, una pregunta que se aborda en el presente documento:

¿Cuál es la relación entre el polimorfismo de subtipo y delimitado por clase de clase?

En este contexto de investigación, nos restringimos específicamente (y enfáticamente) al lenguaje de Haskell existente (Haskell 98 y extensiones comunes cuando sea necesario), es decir, no se deben proponer nuevas extensiones de Haskell. Como demostraremos, esta restricción es adecuada, ya que nos permite ofrecer una respuesta significativa y trascendental a la pregunta antes mencionada.