Lambda: qué es, sintaxis y uso en Kotlin

Autor: IT Sectr Publicado: 2026-06-23 Tiempo de lectura: 7 min

Lambda es una función anónima representada como una expresión compacta { argumentos -> cuerpo }. En Kotlin, las lambdas son la forma principal de pasar comportamiento a funciones de orden superior, proporcionando una sintaxis concisa sin necesidad de declarar una función separada. Según la documentación de Kotlin (2026), más del 70% de las funciones de orden superior en proyectos típicos se invocan con lambdas. Lambda permite escribir código en estilo funcional con un mínimo ruido sintáctico.

Puntos clave

  • Lambda — una función anónima en sintaxis { args -> body }, sin nombre
  • it implícito reemplaza el único argumento de una lambda, simplificando la escritura
  • Trailing lambda — mover la última lambda fuera de los paréntesis de llamada para legibilidad
  • Clausura (closure) — una lambda puede acceder a variables del ámbito exterior
  • Tipo funcional (T) -> R define la firma de la lambda y es verificado por el compilador

¿Qué es lambda?

Lambda (expresión lambda) es una función anónima definida como una expresión en lugar de una declaración. El término proviene del cálculo lambda de Alonzo Church (1936). En programación, una lambda es un bloque de código que puede pasarse como valor, almacenarse en una variable y ejecutarse más tarde. En Kotlin, una lambda siempre está encerrada entre llaves { }, con los argumentos separados del cuerpo por la flecha ->.

Una lambda se diferencia de una función normal por la ausencia de nombre y de la palabra clave fun. Esto permite declarar el comportamiento directamente en el punto de uso, sin saturar el código con declaraciones adicionales. El compilador de Kotlin infiere los tipos de los argumentos del contexto, por lo que en muchos casos los tipos pueden omitirse. Una lambda es azúcar sintáctico sobre el tipo funcional (T) -> R: cada lambda tiene un tipo funcional correspondiente.

El uso principal de las lambdas en Kotlin es pasarlas a funciones de orden superior. La biblioteca estándar usa lambdas en todas partes: filter { it > 0 }, map { it.uppercase() }, forEach { println(it) }. Las lambdas también se utilizan para listeners de eventos, callbacks y configuradores de objetos mediante apply y run, haciendo el código más declarativo en comparación con las clases anónimas.

Sintaxis de expresiones lambda en Kotlin

La forma completa de una expresión lambda en Kotlin: { argumentos -> cuerpo_lambda }. Los argumentos se enumeran separados por comas, seguidos de una flecha y el cuerpo — una o más expresiones. Si el cuerpo contiene varias líneas, la última expresión se convierte en el valor de retorno. Si una función acepta una lambda como último argumento, puede colocarse fuera de los paréntesis de llamada.

kotlin
val sum: (Int, Int) -> Int = { a, b -> a + b }

// Tipos inferidos del contexto
val sumShort = { a: Int, b: Int -> a + b }

// Llamada lambda
val result = sum(5, 3)  // 8
println(result)

La variable sum se declara con un tipo funcional explícito (Int, Int) -> Int y se inicializa con una lambda { a, b -> a + b }. Para sumShort, los tipos se especifican dentro de la lambda y el tipo de la variable se infiere. Ambas variantes son equivalentes. Llamar a una lambda no es diferente de llamar a una función normal — usando la sintaxis sum(5, 3). Una lambda sin argumentos se escribe como { body }, con un argumento — { it -> it * 2 } o simplemente { it * 2 }.

it implícito y omisión de argumentos

Cuando una lambda acepta exactamente un argumento, Kotlin proporciona el nombre implícito it. Esto elimina la necesidad de declarar el argumento en la parte izquierda. El desarrollador escribe solo el cuerpo de la lambda, usando it para acceder al único parámetro. Esta sintaxis es especialmente conveniente en cadenas de procesamiento de colecciones, donde it se refiere al elemento actual.

kotlin
val numbers = listOf(1, 2, 3, 4, 5)

// Nombre de parámetro explícito
val squaredExplicit = numbers.map { n -> n * n }

// it implícito
val squared = numbers.map { it * it }

// Filtrando con it
val even = numbers.filter { it % 2 == 0 }

println(squared) // [1, 4, 9, 16, 25]

En el ejemplo, map { it * it } usa it en lugar de declarar n ->. Kotlin asigna automáticamente it para un único parámetro de lambda. Si una lambda acepta dos o más argumentos, it no se crea — todos los parámetros deben declararse explícitamente. Para mejorar la legibilidad de lambdas anidadas, conviene dar nombres significativos a los parámetros y usar it solo en predicados cortos de una línea.

Trailing lambda y lambdas multilínea

Trailing lambda es una característica sintáctica de Kotlin que permite mover el último argumento lambda fuera de los paréntesis de llamada de la función. Esto hace que el código se asemeje a construcciones integradas del lenguaje. Si la lambda es el único argumento, los paréntesis pueden omitirse por completo. Este enfoque se utiliza activamente en la biblioteca estándar y los DSL.

kotlin
// Llamada estándar
thread(block = {
    println("Hola desde el hilo")
})

// Versión trailing lambda
thread {
    println("Hola desde el hilo")
}

// repeat con trailing lambda
repeat(3) { index ->
    println("Iteración $index")
}

// run con lambda multilínea
val config = run {
    val host = "localhost"
    val port = 8080
    "$host:$port"
}

La función thread acepta un Runnable como último argumento. Gracias a trailing lambda, la lambda puede pasarse fuera de los paréntesis, asemejándose visualmente a un bloque de código. La función repeat toma un número de iteraciones y una lambda con un índice. run es un ejemplo de función de orden superior donde una lambda multilínea calcula un valor devuelto por la última expresión. Los paréntesis alrededor de run() pueden omitirse si la lambda es el único argumento.

Captura de variables (closure) en lambdas

La captura de variables (closure) es la capacidad de una lambda para acceder a variables declaradas en el ámbito exterior. En Kotlin, una lambda puede leer y modificar variables var, así como leer variables val del contexto circundante. Las variables capturadas se almacenan con la lambda durante todo su ciclo de vida, permitiendo crear funciones con estado.

kotlin
fun makeCounter(): () -> Int {
    var count = 0
    return {
        count++  // capturas count
    }
}

fun main() {
    val counter = makeCounter()
    println(counter()) // 0
    println(counter()) // 1
    println(counter()) // 2
}

La función makeCounter declara una variable local count y devuelve una lambda { count++ }. Aunque makeCounter ha terminado su ejecución, la lambda devuelta conserva una referencia a count mediante la clausura. Cada llamada a counter() incrementa y devuelve el valor actual. El mecanismo de closure subyace a la currificación, las fábricas de funciones y la memoización. Es importante recordar que la captura de variables mutables puede provocar comportamientos inesperados en ejecución concurrente.

Preguntas frecuentes

¿Puede una lambda tener return?

Lambda no soporta return incondicional — un return sin etiqueta devuelve el control a la función exterior. Para salir de una lambda, usa return@label, donde label es el nombre de la función de orden superior a la que se pasó la lambda.

¿Cuál es la diferencia entre una lambda y una función anónima?

Una función anónima se escribe como fun(a: Int): Int { return a * 2 } y soporta return sin etiqueta. Una lambda { a -> a * 2 } es más corta en sintaxis pero requiere return@label para una salida anticipada.

¿Cómo pasar una lambda como argumento sin flecha?

Si una lambda no acepta argumentos, la flecha se omite: { body() }. Si acepta un argumento pero no lo usa, escribe { _ -> body() } con un guion bajo para ignorar el parámetro.

¿Siempre crea una lambda un nuevo objeto?

Sí, cada lambda pasada a una función no inline crea una instancia de una clase anónima. Para funciones inline, la lambda se inserta en el lugar de la llamada sin crear un objeto. Las lambdas que no capturan se almacenan en caché como objetos singleton.

¿Por qué no se puede usar return directamente en una lambda?

Return en Kotlin es un operador de salto que pertenece a la función más cercana declarada con fun. Una lambda no es una función (fun), sino una expresión. Por lo tanto, un return dentro de una lambda sin etiqueta se trata como un retorno de la función externa contenedora.

Resumen

  • Lambda — función anónima en sintaxis { args -> body }, pasada como valor a funciones de orden superior
  • it implícito reemplaza el único argumento, haciendo el código más compacto en predicados cortos
  • Trailing lambda mueve la última lambda fuera de los paréntesis de llamada, leyéndose como un bloque de código
  • Clausura (closure) permite a una lambda acceder a variables del contexto exterior tras completarse la función contenedora
  • Tipo funcional (T) -> R define la firma de la lambda con verificación en tiempo de compilación
  • Funciones inline eliminan la creación de clases anónimas para lambdas, mejorando el rendimiento en bucles
  • Lambdas multilínea devuelven el valor de la última expresión, soportando cómputos complejos sin declarar una función separada

Desarrollaremos una aplicación móvil llave en mano

IT Sectr crea aplicaciones para iOS y Android para startups y empresas desde 2017. Le asesoraremos y le propondremos la mejor solución.

Discutir el proyecto

Lea también