Kotlin: Un lenguaje pragmático y moderno

Encuentra el código de la lección:
El gato se llama Kotlin

Abstract

Kotlin es un lenguaje moderno, pragmático y claro, con foco en la seguridad. Combina de forma eficaz la programación orientada a objetos y la programación funcional en una sintaxis concisa y expresiva.

En este curso usaremos Kotlin para el diseño e implementación de bibliotecas reutilizables. Su interoperabilidad con Java, el modelo seguro frente a nulos, las funciones de extensión, las corrutinas y otras características modernas lo hacen ideal para construir componentes modulares y mantenibles, también en contextos multiplataforma.

Esta primera lección introduce el lenguaje y su filosofía: cómo se escribe en Kotlin, en qué se diferencia de otros lenguajes y qué ventajas aporta para escribir código expresivo y seguro desde el inicio.

A través de ejemplos simples y comparaciones prácticas, sentaremos las bases que guiarán el resto del curso.

¿Qué aprenderás en este módulo?

En este módulo introductorio conocerás los fundamentos esenciales de Kotlin y cómo aplicarlos para crear software reutilizable y expresivo. A lo largo de estas lecciones:

Este módulo sentará las bases conceptuales y prácticas para lo que sigue: técnicas para diseñar bibliotecas reutilizables, seguras y fáciles de mantener.

Objetivos de aprendizaje

Al finalizar este módulo, serás capaz de:

Estos objetivos te darán una base sólida para avanzar hacia temas más complejos como tipos algebraicos, control de flujo funcional y diseño orientado a la composición.

¿Qué es Kotlin?

Kotlin es un lenguaje de programación moderno y multiplataforma desarrollado por JetBrains. Combina paradigmas de programación orientada a objetos y programación funcional, y destaca por su sintaxis concisa y expresiva, su enfoque en la seguridad y su capacidad de compilar a múltiples plataformas:

En este curso nos enfocaremos en Kotlin sobre la JVM, la plataforma más madura del ecosistema. Sin embargo, los conceptos que aprenderás son altamente transferibles a las demás plataformas y aplicables en muchos otros lenguajes modernos.

A Taste of Kotlin

Como en Kotlin in Action (Dmitry Jemerov & Svetlana Isakova, 2017), este apartado ofrece un primer ejemplo realista para mostrar la concisión y expresividad de Kotlin. Aquí usamos personajes de Disco Elysium para hacerlo más memorable.

Primer programa: filtrar y mostrar datos
data class Person(
    val name: String,
    val age: Int? = null
)

fun main() {
    val persons = listOf(
        Person("Harrier Du Bois"),
        Person("Kim Kitsuragi", age = 43)
    )
    val youngest = persons.minByOrNull { it.age ?: Int.MAX_VALUE }
    println("The youngest is: $youngest")
}
// Output: The youngest is: Person(name=Kim Kitsuragi, age=43)

¿Qué acabamos de hacer?

  • Se define una data class llamada Person con dos propiedades: name de tipo String y age de tipo Int? (puede ser nulo).
  • La propiedad age tiene un valor por defecto ( null ), lo que permite omitirla al crear una instancia.
  • Se crea una lista inmutable con listOf , que contiene dos objetos Person .
  • En la segunda instancia se utiliza una asignación nombrada ( age = 43 ) para mayor claridad y legibilidad.
  • Se emplea minByOrNull junto con el operador Elvis ( ?: ) para ignorar los valores nulos y encontrar la persona más joven.
  • Si todas las edades fueran nulas, se usa Int.MAX_VALUE como valor de reemplazo para evitar errores.
  • Finalmente, se imprime el resultado usando interpolación de cadenas.

Filosofía de Kotlin

Kotlin busca simplificar la programación moderna combinando lo mejor de distintos lenguajes, sin reinventar la rueda. Su diseño pragmático evita la complejidad innecesaria y ofrece soluciones directas a problemas comunes como la nulidad o la verbosidad excesiva.

Entre sus principios fundamentales se encuentran:

  • Pragmatismo: resuelve problemas reales de forma efectiva, priorizando lo práctico por sobre lo experimental o lo excesivamente teórico.
  • Concisión expresiva: reduce la verbosidad sin perder claridad ni intención.
  • Seguridad: previene errores comunes en tiempo de compilación —como las referencias nulas— y fomenta un código más robusto.
  • Claridad intencional: promueve un estilo en el que la intención del código es explícita y fácil de comprender para otras personas.

Estos principios guían todo el diseño del lenguaje y se reflejan en los ejemplos que iremos explorando a lo largo del curso.

Beneficios y limitaciones de Kotlin en el desarrollo de bibliotecas de software

Beneficios
  • Interoperabilidad con Java: se integra sin fricciones con el ecosistema Java, permitiendo reutilizar bibliotecas existentes y adoptar Kotlin de forma gradual, incluso en bases de código heredadas.
  • Sintaxis concisa y expresiva: reduce repetición de código, mejora la legibilidad y facilita el mantenimiento. Favorece el diseño de APIs limpias y DSLs orientadas a usabilidad.
  • Seguridad frente a nulls: su sistema de tipos previene errores comunes como NullPointerException , reforzando la robustez de las APIs y facilitando contratos más confiables.
  • Funciones de extensión: permiten ampliar funcionalidades sin modificar clases originales, fomentando una arquitectura modular y extensible — ideal para bibliotecas reutilizables.
  • Compatibilidad multiplataforma: posibilita crear bibliotecas que funcionan en JVM, JS y Native, promoviendo la reutilización de código. Requiere seguir ciertas restricciones de API común y, en el caso de Kotlin/Native, aceptar que el tooling aún está menos maduro que en JVM.
  • Corrutinas integradas: facilitan la programación asíncrona con una sintaxis clara y eficiente, permitiendo exponer APIs no bloqueantes en bibliotecas como clientes HTTP o SDKs.
  • Facilidad para crear DSLs: permite construir APIs idiomáticas, expresivas y personalizables, ideales para bibliotecas de configuración, testing o transformación de datos.
Limitaciones
  • Limitaciones en abstracciones avanzadas: Kotlin aún no soporta conceptos como Higher-Kinded Types (HKT) o los implicits de Scala. Esta decisión es intencional, priorizando claridad y practicidad. Sin embargo, ya se exploran propuestas como context parameters, que podrían habilitar nuevos patrones funcionales sin comprometer la legibilidad.
  • Pattern matching limitado: Kotlin no cuenta con un sistema tan expresivo como Scala, Rust o Haskell. Aunque when y las jerarquías selladas permiten cierto control, no existe una sintaxis declarativa para hacer match de estructuras anidadas ni extraer múltiples valores simultáneamente. El compilador K2 abre la puerta a posibles mejoras en este terreno a futuro.

Kotlin es una excelente opción para diseñar bibliotecas modernas, seguras y expresivas. Su enfoque pragmático lo convierte en una herramienta poderosa para la reutilización de código. Sin embargo, la ausencia de ciertas abstracciones avanzadas puede limitar algunos estilos de diseño altamente genéricos o funcionales.

A lo largo del curso aprenderás a sacar el máximo provecho de Kotlin en el diseño de bibliotecas, aprovechando sus fortalezas y encontrando soluciones pragmáticas cuando el lenguaje no provee una abstracción directamente.

¿Qué distingue una expresión de una declaración?

En Kotlin, es importante distinguir entre expresiones y declaraciones, ya que cumplen funciones diferentes dentro de un programa. Esta distinción —también presente en lenguajes como Rust— favorece un estilo de programación más seguro y predecible.

Expresión

Una expresión produce un valor y puede combinarse con otras. En Kotlin, esto incluye desde constantes hasta funciones anónimas. También lo son operaciones aritméticas, operadores lógicos y llamadas a funciones.

Declaración

Las declaraciones son instrucciones que realizan una acción. En general, no se usan por su valor, y no pueden combinarse con otras expresiones. Ejemplos comunes son la definición de variables, bucles o funciones.

Una diferencia clave con lenguajes como Java, C o JavaScript es que en esos lenguajes las asignaciones son expresiones, lo que puede llevar a errores como if (x = 5) cuando en realidad se quería comparar ( if (x == 5) ). En Kotlin, las asignaciones son declaraciones, lo que impide este tipo de ambigüedades y permite que el compilador detecte errores más fácilmente.

A continuación, una tabla con ejemplos representativos:

Ejemplos de expresiones y declaraciones en Kotlin
Ejemplo ¿Expresión o declaración? ¿Devuelve valor?
val x = 5 Declaración No
5 Expresión Sí, el valor 5
if (a > b) a else b Expresión Sí, el valor de a o b
fun greet() { println() } Declaración No

En resumen

  • Las expresiones devuelven un valor y pueden ser combinadas con otras expresiones.
  • Las declaraciones ejecutan acciones y no devuelven un valor, por lo que no pueden ser combinadas con otras expresiones.

Esta diferencia promueve una programación más expresiva, segura y menos propensa a errores sutiles.

Interpolación de cadenas

La interpolación de cadenas —también conocida como string templates— es una característica de Kotlin que permite insertar valores o expresiones directamente dentro de un String usando el símbolo $ .

Para insertar una variable, basta con escribir $variable . En el caso de expresiones, se deben usar llaves: ${expresión} .

Ejemplo

En el siguiente ejemplo, mostramos el estado de un personaje según sus puntos de vida ( hp ):

Interpolación de cadenas en acción
val name = "Leif"
val hp = 24

println("Unit: $name | Status: ${if (hp <= 0) "defeated" else "active"}")

Esto imprimirá:

Salida en consola
Unit: Leif | Status: active

Gracias a la interpolación de cadenas, podemos construir mensajes dinámicos de forma más clara, concisa y expresiva, evitando la concatenación manual con operadores como + .

Además, las expresiones interpoladas se evalúan en el momento en que se construye la cadena, lo que aporta claridad y eficiencia sin sobrecostos innecesarios.

Sin prefijos especiales

A diferencia de otros lenguajes, como Scala ( s"Hola, $nombre" ) o Python ( f"Hola, {nombre}" ), Kotlin no requiere prefijos como s o f para habilitar la interpolación.

En Kotlin, todas las cadenas admiten interpolación de forma nativa, lo que las hace más simples, legibles y menos propensas a errores.

¿Qué es un StringBuilder ?

Cuando interpolamos cadenas en Kotlin, el compilador genera código que usa internamente un StringBuilder , una clase optimizada para construir texto de forma eficiente sin crear múltiples objetos intermedios.

Esto es relevante porque en Kotlin (y en Java), las cadenas ( String ) son inmutables: cada vez que concatenas con + , se crea una nueva instancia, lo cual puede degradar el rendimiento en operaciones repetidas o dentro de bucles.

Un StringBuilder , en cambio, permite modificar la cadena en memoria, agregando, insertando o eliminando texto sin copiar constantemente.

Por ejemplo, esta interpolación:

Interpolación de cadenas
val name = "Leif"
val status = "active"
val message = "Unit: $name | Status: $status"

Se traduce internamente a algo similar a esto:

Traducción interna usando StringBuilder
val name = "Leif"
val status = "active"
val sb = StringBuilder()
sb.append("Unit: ")
sb.append(name)
sb.append(" | Status: ")
sb.append(status)
val message = sb.toString()

Gracias a esta conversión, la interpolación en Kotlin es más legible que la concatenación manual y más eficiente que usar + repetidamente.

Crear tu primer proyecto Kotlin con Gradle

Antes de comenzar a escribir código Kotlin, necesitamos configurar un entorno de desarrollo funcional. En esta sección aprenderás cómo crear un proyecto Kotlin básico desde la terminal utilizando Gradle, el sistema de construcción que usaremos durante el curso.

Gradle es una herramienta de automatización de construcción flexible y ampliamente utilizada en el ecosistema Kotlin y Java. Nos permitirá compilar, probar y empaquetar nuestras aplicaciones y bibliotecas de forma reproducible.

Te proporcionamos instrucciones específicas para Windows, Linux y macOS:

Por ahora, crearemos una aplicación de consola para probar nuestro código. Más adelante aprenderemos a utilizar Gradle para construir bibliotecas de software reutilizables.

Una vez creado el proyecto, puedes abrirlo con IntelliJ IDEA, Fleet u otro editor. Aún no necesitas comprender a fondo la estructura del proyecto, pero es útil tener en cuenta sus directorios principales:

  • El código fuente está en app/src/main/kotlin .
  • Las pruebas se ubican en app/src/test/kotlin .

Si estás usando IntelliJ IDEA y tienes disponible la herramienta idea en tu terminal, puedes abrir el proyecto con el siguiente comando:

Abrir proyecto en IntelliJ IDEA
idea intro-kt

¿Qué acabamos de hacer?

Este comando abre el proyecto actual en IntelliJ IDEA, siempre que tengas habilitado el Command Line Launcher ( idea ). Puedes activarlo desde el menú Tools > Create Command-line Launcher .

Ejercicio: Un “Hello, World” con sentido

Ya creaste tu primer proyecto en Kotlin. Ahora es momento de darle voz propia.

Tu tarea es explorar la estructura del proyecto, encontrar el punto de entrada del programa y modificarlo para que imprima un mensaje auténtico y significativo para ti.

No se trata de un simple "Hello, World" , sino de una frase que te represente. Algunas ideas:

  • Una línea de tu videojuego favorito
  • Una cita que te inspira
  • Un meme que te haga reír
  • Una frase que hayas escrito tú mismx
Ejecutar el programa
./gradlew :app:run

Si todo está bien configurado, tu mensaje aparecerá en la consola ✨

Recuerda

No necesitas crear clases nuevas ni preocuparte por la estructura ideal. Simplemente disfruta de escribir tu primer programa en Kotlin.

Solución

package org.example

class App {
    val greeting: String
        get() = "Ladies and Gentlemen, I give you Rose Red's killer..."
}

fun main() {
    println(App().greeting)
}

Conclusiones

En esta lección asentaste una base práctica de Kotlin: lo conociste como lenguaje pragmático, exploraste su sintaxis clara, la diferencia entre expresiones y declaraciones, y viste cómo la interpolación de cadenas mejora la legibilidad. Además, dejaste listo un proyecto con Gradle para ejecutar y evolucionar tus ejercicios.

Con esto ya puedes leer y escribir pequeños programas idiomáticos y tienes el entorno de trabajo funcionando para continuar con temas más profundos.

Puntos clave

  • Kotlin prioriza claridad y seguridad sin sacrificar productividad.
  • Expresiones producen valor; declaraciones ejecutan acciones.
  • La interpolación ( $ / ${...} ) evita concatenaciones verbosas y se traduce eficientemente.
  • Con Gradle puedes crear y ejecutar un proyecto base reproducible.

¿Qué nos llevamos?

La “caja de herramientas” inicial para seguir construyendo: un entorno que compila, un primer contacto con la filosofía del lenguaje y hábitos que nos acompañarán todo el curso: preferir la intencionalidad sobre la astucia, elegir construcciones expresivas y cuidar la legibilidad de las APIs.

¿Con ganas de más?