Kotlin

4 octubre 2015

Hace unos meses, en la Droidcon 2015 en Madrid, en varias charlas, y en especial en una de Antonio Leiva, se habló de un lenguaje de programación que me llamó mucho la atención, Kotlin. Ya había oído hablar de él pero no tan en profundidad, así que me puse a investigar y hacer alguna que otra prueba, y tras juguetar un poco con el me ha llamado la atención por su curva de aprendizaje, muy rápida y amena, y su orientación funcional.

Como siempre me gustaría avisar que soy primerizo con Kotlin así que cualquier aclaración será bienvenida, por ahora solo he realizado algunas pruebas basadas en sus koans de introducción que podéis encontrar en el enlace mas abajo, ¡espero que os sea de utilidad!.

Kotlin es creado por Jetbrain, la compañía detrás de IntelliJ, y corre sobre la máquina virtual de Java de lo que luego hablaremos más en profundidad, es un lenguaje orientado a objetos y como he mencionado antes tiene algunas ideas que vienen de la programación funcional.

Por que Kotlin me gusta

Instalación

Es muy sencillo, la gente de Jetbrain lo ha hecho muy bien. Requerimientos:

  1. Intellij 14.1 o Android Studio: IntelliJ IDEA Minimal Survival Guide. Puedes descargarlo desde la página de descargas de Jetbrains
  2. JDK 1.6 o superior: Puedes descargarlo desde la página de Oracle o si estas muy perdido puedes recurrir al tutorial JVM Minimal Survive Guide
  3. Plugin de Kotlin: Se puede descargar desde el propio IDE, abre IntelliJ: File -> Plugins, y busca ==Kotlin==.
  4. listo :).

Compilador

Cuando investigué sobre Kotlin me llamó la atención su compilador y hasta ese entonces no sabía nada de como funcionaban los compilador de los lenguajes que funcionan sobre Java. En el caso de Kotlin, requiere que Kotlin entienda los ficheros fuente de Java y sus binarios, y viciversa, es decir que Java entienda los ficheros fuente de Kotlin y sus binarios. La idea de que el compilador de Kotlin entienda los ficheros fuente de Java es fácil de imaginar, pero hacer que javac, el compilador de Java, entienda los ficheros fuente de Kotlin es claramente imposible.

Actualmente el estado de los compiladores es el siguiente:

Características:

Java compatible

Según la gente de Jetbrain Kotlin fue diseñado con la interoperabilidad en mente, y lo poco que he probado a través de los koans me ha resultado bastante sencillo de entender e implementar, tanto Kotlin puede usar Java como en sentido contrario de un manera bastante cómoda.

Aquí la documentación es muy extensa y hacen de la experiencia algo muy agradable, recomiendo echar un vistazo directamente a la web ya que me sorprendió mucho como interactúan ambos lenguajes.

Más información en la Documentación oficial y en Koan resuelto en Github

Null Safety

Una de mis características favoritas y que soluciona uno de los problemas que más incómodo me parece, las referencias a null. Null es lo que se llama un « first-class citizen » en el sistema de tipos de Kotlin, es decir los tipos son conscientes de que pueden ser null, tanto en el flujo de la aplicación así como en su referencia. Esto es bastante útil ya que en mi opinión la posibilidad de acceder en un nuestro código a referencias que son null (NullPointerException en Java) es una fuente de problemas inmensa que conlleva mucho boilerplate code y programación defensiva.

Kotlin puede hacer distinción entre aquellos tipos que pueden hacer referencia a null y aquellos que no.

var a: String = "abc"
a = null // compilation error"
val l = a.lenght() // esto nunca generará un NullPointerException y el compilador no dará problemas

Pero igualmente nos permite hacer un tipo « nullable »

var b: String? = "abc"
b = null // ok
val l = a.length() // esto puede generar un NullPointerException y el compilador no nos permitirá hacer esta llamada

En los casos en los que null es inevitable, Kotlin nos ofrece maneras bastante útiles de checkear las posibles referencias a null:

Más información en la Documentación oficial y en Koan resuelto en Github

Soporte para funciones de alto nivel y Lambdas

Otra cosa que me encanta. Básicamente un función de alto nivel es una función que acepta otras funciones como parámetros o incluso que devuelve otra función. Pongo un ejemplo:

list.filter {it % 2 == 1}

En este ejemplo se filtra una lista eliminando todos los elementos pares, es un ejercicio muy básico que usa una función predefinida filter al que se le pasa otra función como argumento it % 2 == 1 y que se aplica toda la colección.

Probablemente la mejor manera de entenderlo sea en la Documentación oficial o en el koan resuelto en mi Github

Data Classes

Muy útiles para clases que solo almacenan información (DTO), las Data clases nos generan de manera automática ciertas funcionalidad como la función equals(), hashCode(), toString() o una función copy() que copia los valores en una instancia nueva del objeto permitiéndonos modificar los valores deseados, actualmente tenemos alternativas en Java como la librería AutoValue de Google.

data class Money(val currency: String, val amount: Int)
val money = Money("USD", 100)
val moreMoney = money.copy(amount = 200)

Y nos permite dar valores por defecto a los parámetros de la construcción, así nos podemos olvidar de definir diferentes constructores.

data class Money(val currency: String = "Euro", val amount: Int = 0)

Y otra cosa que me gustó mucho son las Multi-declaraciones, que nos permiten hacer cosas del tipo:

val jane = User("Jane", 35) 
val (name, age) = jane
println("$name, $age years of age") // Imprime "Jane, 35 years of age"

Más información en la Documentación oficial y en Koan resuelto en Github

Traits

Me encantan los Traits no puedo decir más, los Traits se pueden entender como interfaces en las que se pueden implementar funciones. Aquí no tengo ningún ejemplo, los conozco por Scala, pero puedes encontrar mas información sobre ellos en este post.

Extension Fuctions

Kotlin permite ampliar las funcionalidades de la clases (tanto propias de Kotlin como de Java) sin necesidad de heredarlas usando la declaración extension, estos miembros se introducen de manera estática, de esta manera nos podemos olvidar de las clases « Utils » repletas de llamadas a funciones estáticas y obtener un código mucho mas limpio

fun String.last() : Char {
return this[length - 1]
}
val x = "Hey!"
println(x.last()) // Imprime "!".

A partir de mis escarceos con Kotlin descubrí que otros lenguajes también implementa esta funcionalidad como puede ser C#

Mas información en la Documentación oficial y en Koan resuelto en mi Github

Conclusión

Para ser honestos mi aventura con Kotlin ha sido breve por ahora, y apenas he hecho algún desarrollo que vaya mas allá de la resolución de los Koans, pero me esta gustando mucho ya que aporta mucha flexibilidad y aires moernos a Java. Espero que este post os haya sido de utilidad!

Referencias:


Publicado el 4 octubre 2015 por Alfredo Cerezo.
Kotlin