Skip to main content

Declaración de funciones

Las funciones son una herramienta fundamental para construir software reutilizable, legible y organizado. Kotlin facilita su declaración con una sintaxis concisa y expresiva, que incluye características como parámetros con valores por defecto, funciones de una sola expresión e inferencia de tipos.

En esta lección aprenderás a declarar funciones en Kotlin, entender cómo funciona vararg para aceptar múltiples argumentos y cuándo conviene especificar tipos de retorno. También explorarás funciones estándar como map y fold, y conocerás las diferencias entre colecciones como Array y List.

No es necesario dominar todos los detalles de inmediato: a medida que avancemos en el curso, retomaremos y profundizaremos en los elementos más relevantes.

🧩 Funciones en Kotlin

Una función en Kotlin es un bloque de código reutilizable que realiza una tarea específica. La sintaxis básica para declarar una función es la siguiente:

Estructura general
fun functionName(param1: Type1, param2: Type2 = defaultValue, ...): ReturnType {
// Cuerpo de la función
return result
}

Explicación de la sintaxis

  • fun: Palabra clave para declarar una función.
  • functionName: Nombre descriptivo que identifica la función.
  • Parámetros (param1, param2): Lista de argumentos con sus tipos.
    • Una función puede no tener parámetros.
    • Es posible definir valores por defecto, haciendo que el parámetro sea opcional.
  • ReturnType: Tipo del valor que retorna la función.
    • Si la función no devuelve un valor significativo, se usa Unit, que puede omitirse por ser implícito.
  • Cuerpo de la función: Conjunto de instrucciones que se ejecutan al llamarla.

➕ Ejemplo: Sumar dos números

Supongamos que queremos crear una función que sume dos números enteros. La declaración sería:

Versión con cuerpo de bloque (functions/src/main/kotlin/cl/ravenhill/math/add.kt)
fun add(a: Int, b: Int): Int {
return a + b
}

Si la función contiene solo una expresión, puedes escribirla de forma más concisa mediante asignación directa:

Versión con asignación directa y tipo explícito (functions/src/main/kotlin/cl/ravenhill/math/add.kt)
fun add(a: Int, b: Int): Int = a + b

Kotlin incluso permite inferir el tipo de retorno automáticamente:

Versión con inferencia de tipo (functions/src/main/kotlin/cl/ravenhill/math/add.kt)
fun add(a: Int, b: Int) = a + b

Este estilo hace que el código sea más breve, pero úsalo con moderación: puede dificultar la lectura si el tipo de retorno no es evidente y volver el código más frágil frente a cambios accidentales en el tipo devuelto.

Estilo de nombres

En Kotlin, las funciones y variables deben nombrarse usando la convención camelCase. Esto significa:

  • El nombre comienza con minúscula.
  • Cada palabra siguiente se escribe sin espacios, comenzando con mayúscula.

✅ Ejemplos correctos:

  • calculateTotal
  • printMessage
  • main

Usar un estilo de nombres consistente mejora la legibilidad y asegura que tu código se mantenga alineado con las prácticas idiomáticas de Kotlin.

🔢 Funciones variádicas (vararg)

En Kotlin puedes definir funciones que aceptan una cantidad variable de argumentos usando la palabra clave vararg.
Esto permite invocar la función con cero, uno o más valores del mismo tipo, de manera similar a *args en Python o ...args en JavaScript.

Ejemplo: sumar múltiples números (functions/src/main/kotlin/cl/ravenhill/math/sum.kt)
fun sumAll(vararg nums: Int): Int =
nums.sum()
Invocación de la función (functions/src/main/kotlin/cl/ravenhill/math/sum.kt)
sumAll(1, 2, 3, 4)  // devuelve 10
sumAll() // devuelve 0

Si tienes un arreglo existente, puedes desempaquetarlo usando el prefijo *:

Desempaquetando un arreglo (functions/src/main/kotlin/cl/ravenhill/math/sum.kt)
val extras = intArrayOf(5, 6)
sumAll(1, 2, *extras) // devuelve 14

Hack: Uno o más argumentos

Si necesitas que una función reciba al menos un argumento obligatorio, puedes declararlo como un parámetro normal seguido de un vararg.

Una forma útil de entender esto es compararlo con expresiones regulares:

  • * representa “cero o más repeticiones”
  • + representa “una o más repeticiones”

En este contexto:

  • El parámetro obligatorio representa el +
  • El vararg representa el *

Juntos, expresan la idea de “uno o más argumentos”.

Al menos un argumento requerido (functions/src/main/kotlin/cl/ravenhill/math/sum.kt)
fun sumTo(first: Int, vararg rest: Int): Int =
rest.fold(first) { acc, i -> acc + i }
Invocación de la función (functions/src/main/kotlin/cl/ravenhill/math/sum.kt)
sumTo(1)                                        // devuelve 1
sumTo(1, 2, 3, 4) // devuelve 10
sumTo(first = 1, rest = intArrayOf(2, 3, 4)) // devuelve 10

Este patrón también sirve para funciones con dos o más parámetros obligatorios, seguidos por una cantidad variable de argumentos opcionales.

Ejercicio

Ejercicio de cierre: Duplicar niveles de poder

Vamos a practicar la declaración de funciones en Kotlin aplicando una transformación sobre una lista.
Supón que tienes una lista de niveles de poder (Int) y quieres duplicar cada uno de ellos usando map.

Como recordatorio, map aplica una función a cada elemento de una colección y devuelve una nueva colección con los resultados:

fun <T, R> Iterable<T>.map(transform: (T) -> R): List<R>
fun IntArray.map(transform: (Int) -> R): List<R>

Tu tarea es definir una función llamada doublePowers que reciba una lista de enteros (List<Int>) o bien una cantidad variable de argumentos (vararg) y devuelva una nueva lista con cada valor duplicado.

🎯 Conclusiones

En esta lección conocimos la sintaxis básica para declarar funciones en Kotlin, un componente esencial para estructurar código reutilizable, expresivo y mantenible. También exploramos algunas variantes idiomáticas como la inferencia de tipos, las funciones variádicas y la diferencia entre colecciones como Array y List.

🔑 Puntos clave

  • Las funciones se declaran con la palabra clave fun y pueden tener parámetros con valores por defecto.
  • El tipo de retorno puede inferirse automáticamente si la función se reduce a una sola expresión.
  • vararg permite definir funciones que aceptan una cantidad variable de argumentos.
  • Es posible requerir al menos un argumento junto a vararg, combinándolos en la firma.
  • Array<T> y List<T> parecen similares, pero tienen diferencias clave en mutabilidad y uso.
  • Kotlin favorece un estilo conciso, pero también explícito y claro cuando la función es pública o compleja.

🧰 ¿Qué nos llevamos?

Esta lección es una primera aproximación al sistema de funciones de Kotlin.
No necesitas memorizar todos los detalles ahora: puedes volver a este material como referencia rápida.

A lo largo del curso, retomaremos estos conceptos y profundizaremos en los aspectos más relevantes según el contexto de cada unidad.

📖 ¿Con ganas de más?

🔥 Referencias recomendadas

  • 🌐 Funciones | Kotlin en Kotlin docs:
    Esta documentación ofrece una guía exhaustiva sobre la declaración y uso de funciones en Kotlin. Aborda desde conceptos básicos como la sintaxis con fun, el uso de parámetros con tipo explícito y valores por defecto, hasta temas más avanzados como funciones variádicas (vararg), argumentos nombrados, funciones de una sola expresión, inferencia de tipos, funciones infijas (infix), genéricas y recursivas de cola (tailrec). También detalla cómo declarar funciones a nivel superior, funciones locales, de miembro y de extensión, promoviendo un estilo conciso, idiomático y expresivo. Es una fuente esencial para comprender el modelo funcional y flexible de funciones en Kotlin.

Footnotes

  1. El principio get-put establece que un tipo covariante puede ser usado como un tipo de retorno (out) pero no como un tipo de entrada (in). En este caso, out indica que el arreglo solo se usa para obtener valores, no para insertarlos.

  2. Se llama azúcar sintáctica (syntactic sugar) a una forma más conveniente o legible de escribir algo que, en realidad, se traduce a una forma más básica del lenguaje.