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:
- ¿Por qué el comstackdor de Scala me da un error al pasar una class sellada de Kotlin a un constructor?
- Kotlin VS Scala: Implementar methods con parameters constructor primarios
- Companion se beneficia de la posibilidad de implementar interfaces
- ¿Cómo funcionan las funciones de extensión de Kotlin?
- @uncheckedVariance en Kotlin?
- ¿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 ?
- ¿Cómo hacer que los constructores seguros de Kotlin trabajen en Scala?
- Sistema local de administración de packages Java en Python PIP style?
- Forma equivalente de Scala de Rango a class personalizada
- ¿Por qué Kotlin comstack más rápido que Scala?
- ¿Es posible mezclar Scala y Kotlin en el mismo module maven?
- Progtwigción funcional: cómo continuar el context para una cadena de reglas de validation
- Kotlin: llaves de varias expresiones (o declaraciones)
- Comstackción manual de JAR para Scala & Kotlin
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"
- Kotlin en Android: no se puede encontrar el manifiesto principal fusionado. Que esta causando este error?
- ¿Cómo verificar si una variable "tardía" se ha inicializado?