Genéricos reificados en Scala 2.10

La falta de generics reificados en Scala es lo que más me molesta sobre el lenguaje, ya que las cosas simples no se pueden implementar sin utilizar constructos complicados.

Tanto Kotlin como Ceylon admiten generics reificados, por lo que es definitivamente posible hacerlo en la parte superior de la JVM. En el pasado se decía que Scala no podía darles soporte sin un cambio en la JVM, pero ahora se rumorea que Scala 2.10 tiene un soporte limitado para la reificación. Entonces mi pregunta es:

  • ¿Qué podemos esperar para la reificación en Scala 2.10, por ejemplo, podré 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 ?

Tu argumento es defectuoso Kotlin aún no ha sido lanzado *, y Ceylon acaba de publicar su primera versión, y citaré una de las cosas que falta en su anuncio :

  • generics reificados

Entonces, discúlpeme, pero ¿qué implementación lo demuestra es posible? De hecho, no he mirado mucho en lo que Kotlin está prometiendo, pero lo que Ceylon está prometiendo es solo lo que los manifiestos proporcionan, pero de manera transparente.

Pero consideremos el problema que describió en su pregunta:

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

Entonces, antes que nada, JVM no proporciona ninguna forma de identificar los parameters de tipo en las interfaces o classs, por lo que E no puede ser revisado por JVM. Sin embargo, puede almacenar información sobre lo que E representa en cada object 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. Nuevamente, JVM no proporciona ninguna forma de usar parameters de tipo en una definición de método. La única forma de implementar eso es tener handle accept Object como parámetro: es decir, escribir borrado.

Y este es el trato: para hacer que el handle invocable desde Java, debe ser un tipo borrado. Y, si se borra el tipo, está sujeto a la limitación descrita en su pregunta. La única forma de evitar esto es eliminar la compatibilidad con Java (que, dicho sea de paso, 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 sea lo que sea que ofrezca (y estoy apostando por un uso más transparente de manifiestos para afirmar la igualdad de tipo), esta limitación particular es intrínseca a JVM y no se puede superar sin abandonar la integración de Java.

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

Kotlin ha reificado los generics para los parameters del tipo de function 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 un time, son utilizados por muchas bibliotecas que ya están 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 generics reificados en Kotlin, el famoso TypeReference en Jackson, cuando se usa en el module Jackson Kotlin usa 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 de 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>()) } } 

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

"Sí, los parameters de tipo no están disponibles en los objects de la class"

  • Tipo de function con receptor en Scala
  • Kotlin zipToda alternativa
  • Herencia genérica de Kotlin
  • Biblioteca Headless de una fuente para JVM y JavaScript
  • Usar varios lenguajes JVM en el mismo proyecto
  • ¿Existe un análogo Future.sequence en kotlin?
  • Clase de Json a Kotlin Data
  • ¿Se puede usar Flink con Kotlin?
  • Convierta la function de Scala a la function de Kotlin
  • Hay alguna biblioteca para trabajar con mónadas en kotlin?
  • Scala require () equivalente en Kotlin