generics scala ceylon kotlin

generics - Genéricos reificados en Scala 2.10



ceylon kotlin (3)

Kotlin ha modificado los genéricos para los parámetros de tipo de función en línea, como se documenta aquí: https://kotlinlang.org/docs/reference/inline-functions.html#reified-type-parameters . Esto ha existido en Kotlin desde hace algún tiempo, ya que son utilizadas por muchas bibliotecas dentro del ecosistema de Kotlin. Otras respuestas aquí están desactualizadas al referirse al Kotlin. Kotlin ha sido lanzado como 1.0 desde febrero de 2016.

Ejemplos de genéricos reificados en Kotlin, el famoso TypeReference en Jackson, cuando se usan en el módulo de Jackson Kotlin usan este código:

public inline fun <reified T: Any> ObjectMapper.readValue(jp: JsonParser): T = readValue(jp, object: TypeReference<T>() {})

Y lo mismo de la biblioteca Injekt basada en Kotlin:

public inline fun <reified T: Any> fullType(): FullTypeReference<T> = object:FullTypeReference<T>(){} public inline fun <reified T : Any> injectLazy(): Lazy<T> { return lazy { Injekt.get(fullType<T>()) } }

La falta de genéricos reificados en Scala es lo que más me molesta del lenguaje, ya que las cosas simples no se pueden implementar sin usar construcciones complicadas.

Tanto Kotlin como Ceylon son compatibles con los genéricos reificados, por lo que es definitivamente posible hacerlo en la parte superior de la JVM. En el past se dijo que Scala no podía apoyarlos sin un cambio en la JVM, pero ahora se rumored que Scala 2.10 tiene un soporte limitado para la reificación. Así que mi pregunta es:

  • ¿Qué podemos esperar para la reificación en Scala 2.10? ¿Podré, por ejemplo, implementar un rasgo genérico varias veces ? ¿Qué tan limitado es?
  • Si la reificación de Scala 2.10 resulta ser más limitada que Kotlin y Ceylon . Porqué es eso ?

Según lo que dice Andrey Breslav en Kotlin página, Kotlin no tiene tipos reificados:

"Sí, los parámetros de tipo no están disponibles en los objetos de clase"


Su argumento es defectuoso. Kotlin no se ha lanzado todavía *, y Ceylon acaba de lanzar su primera versión, y citaré una de las cosas que falta en su anuncio :

  • genéricos reificados

Entonces, discúlpeme, pero ¿qué implementación prueba que es posible? De hecho, no he mirado mucho lo que Kotlin promete, pero lo que promete Ceilán es lo que ya proporcionan los manifiestos, pero de una manera transparente.

Pero consideremos el problema que describiste en tu pregunta:

trait Handles[E <: Event] { def handle(event: E) }

Entonces, en primer lugar, JVM no proporciona ninguna manera de identificar parámetros de tipo en interfaces o clases, por lo que JVM no puede verificar E Sin embargo, puede almacenar información sobre lo que E representa en cada objeto que implementa Handles , tal como podría escribir esto en Scala:

abstract class Handles[E <: Event : Manifest] { def handle(event: E) }

A continuación, veamos el handle método. Una vez más, JVM no proporciona ninguna forma de usar parámetros de tipo en una definición de método. La única forma de implementarlo es que el handle acepte el Object como parámetro: es decir, escriba borrar.

Y aquí está el trato: para hacer manejable desde Java, debe ser borrado. Y, si es un tipo borrado, está sujeto a la limitación descrita en su pregunta. La única forma de evitar eso es eliminar la compatibilidad con Java (que, por cierto, tampoco está disponible en la primera versión de Ceylon).

Sí, Scala tendrá reificación (de algún tipo) en 2.10, según Martin Odersky. Pero independientemente de lo que proporcione (y estoy apostando a un uso más transparente de los manifiestos para afirmar la igualdad de tipos), esta limitación particular es intrínseca a JVM y no se puede superar sin abandonar la integración de Java.

(*) Kotlin tiene una demostración ahora, y su reificación, hasta ahora, es solo un azúcar sintáctico para agrupar manifiestos y pruebas de instancia. Todavía está sujeto a todas las mismas limitaciones que Scala.