Kotlin como lenguaje: nulabilidad en el sistema de tipos, sealed y exhaustividad, genéricos y varianza, DSLs, corrutinas y Flow por dentro, el compilador K2 y los cuatro backends.
Cada nivel construye sobre el anterior. Sin saltos, sin huecos.
La visión aérea del lenguaje: el sistema de tipos y la nulabilidad, las corrutinas, el compilador K2, los cuatro backends y el ecosistema multiplataforma.
De dónde viene Kotlin, qué problema de Java resolvía, la reescritura del compilador con K2, y los objetivos de compilación que hoy soporta.
La base: `val` frente a `var`, inferencia de tipos, `if` y `when` como expresiones, rangos, y por qué apenas hay sentencias en Kotlin.
Parámetros por defecto y nombrados, funciones de una expresión, funciones locales, `infix`, `vararg` y funciones de nivel superior.
La nulabilidad en el tipo: `T` frente a `T?`, `?.`, `?:`, `!!`, smart casts, y los platform types que llegan desde Java.
Constructor primario y secundarios, bloques `init`, propiedades con getter y setter, visibilidad, y por qué en Kotlin no se escriben campos.
Qué genera una data class, `equals`/`hashCode`/`toString`/`copy`, el desestructurado posicional y el desestructurado por nombre de 2.3.20.
La palabra clave `object`: singletons, expresiones de objeto, `companion object`, factorías, y su representación real en el bytecode.
Jerarquías cerradas: `sealed class` y `sealed interface`, `when` exhaustivo, y modelar estados imposibles fuera del sistema de tipos.
Interfaces con implementación por defecto, resolución de conflictos, y la delegación de implementación con `by` como alternativa a la herencia.
`lazy`, `observable`, delegación a un mapa, escribir tu propio delegado, `lateinit`, y los explicit backing fields estables en 2.4.
Funciones y propiedades de extensión: resolución estática, el receptor, el ámbito de importación, y por qué no son inyección de métodos.
Sintaxis de lambda, `it`, el último parámetro fuera de los paréntesis, referencias a función, y los tipos función por dentro.
Las cinco funciones que todo el mundo confunde: qué recibe cada una, qué devuelve, y un criterio claro para elegir sin dudar.
Por qué existe `inline`: eliminar la asignación de la lambda; `noinline`, `crossinline`, retornos no locales, y los genéricos `reified`.
Parámetros de tipo, restricciones, varianza en el sitio de declaración (`in`/`out`) y en el de uso, proyecciones estrella, y el borrado de tipos.
La jerarquía de solo lectura frente a mutable, los operadores de la stdlib, y cuándo una `Sequence` gana de verdad frente a una lista.
La sobrecarga de operadores por convención de nombres: `plus`, `get`, `invoke`, `componentN`, `compareTo`, iteradores y rangos propios.
El mecanismo detrás de Gradle KTS y Compose: lambdas con receptor, builders con seguridad de tipos, `@DslMarker` y diseñar un DSL usable.
Cómo funciona el análisis de flujo que permite el smart cast, por qué falla con propiedades mutables, y los `contracts` de la stdlib.
Estables en 2.4: qué problema resuelven, en qué se diferencian de los context receivers que sustituyen, y cómo no abusar de ellos.
La decisión de eliminar las checked exceptions, `try` como expresión, `Result`, modelar el fallo con sealed classes, y el diseño en las fronteras.
El corazón del asunto: `suspend` como transformación del compilador, la `Continuation`, el estilo CPS, y por qué una corrutina no es un hilo.
`CoroutineScope`, `Job` y la jerarquía padre-hijo; `launch` frente a `async`, la cancelación cooperativa y la propagación de errores.
El `CoroutineContext` como mapa de elementos, los dispatchers y su pool, `withContext`, y el error de creer que el problema es el hilo.
Comunicación entre corrutinas: `Channel` y sus tipos de buffer, productores y consumidores, `select`, y el modelo CSP en Kotlin.
`Flow` como stream frío: builders, operadores intermedios y terminales, la contrapresión que sale gratis, y el contrato de contexto.
`StateFlow` y `SharedFlow`: conflación, réplica, `shareIn` y `stateIn`, y la diferencia real entre un flujo frío y uno caliente.
Cómo compila Kotlin hoy: el frontend K2 y su árbol, la representación intermedia común, y por qué la reescritura desbloqueó el resto del ecosistema.
Cómo se ve tu Kotlin desde Java: nombres, `@JvmStatic`, `@JvmName`, `@JvmOverloads`, nulabilidad en la frontera y las clases sintéticas.
Las clases de valor y el inline en el runtime: cuándo se elimina el envoltorio y cuándo hay boxing, y su uso para tipos de dominio.
Definir anotaciones y sus targets, la reflexión de Kotlin frente a la de Java, la reflexión ligera, y el coste real de usarla.
El procesamiento de símbolos con KSP frente al viejo kapt, escribir un procesador, y los plugins de compilador que ya usas sin saberlo.
El modelo de KMP: source sets y su jerarquía, `expect`/`actual`, qué se comparte de verdad, y el ciclo de compilación multiplataforma.
La compilación nativa: el recolector 2.0 que enterró los objetos congelados, la interoperabilidad con C y Objective-C, y el export a Swift.
Kotlin/Wasm con su propio modelo de memoria y compilación incremental, Kotlin/JS y su interoperabilidad, y qué esperar de cada uno.
Tests multiplataforma con `kotlin.test`, testear código suspendido con `runTest` y dispatchers de prueba, y el tiempo virtual.
Escribir una biblioteca: `explicit API mode`, qué rompe la compatibilidad binaria y no la de fuente, `@Deprecated` y las opt-in APIs.
El coste oculto: lambdas que asignan, boxing de primitivos y nullables, el escape analysis de la JVM, y cómo medir antes de optimizar.
El modelo mental completo del lenguaje, cómo se decide una nueva característica en el proceso KEEP, leer la fuente del compilador y hacia dónde va.
Empieza por los fundamentos y sube nivel a nivel hasta el dominio total.
Comenzar el camino →