Funciones puras e impuras¶
En el desarrollo moderno con Kotlin y Jetpack Compose, las funciones puras son un pilar esencial. Nos permiten escribir código predecible, testable y eficiente, especialmente en arquitecturas declarativas donde la interfaz depende del estado.
¿Qué es una función pura?¶
Una función pura es aquella que:
-
Depende únicamente de los parámetros que recibe.
No utiliza variables externas ni accede a estados globales. -
No produce efectos secundarios.
No modifica datos fuera de sí misma ni interactúa con el entorno (pantalla, ficheros, red, etc.). -
Siempre devuelve el mismo resultado para los mismos valores de entrada.
fun sumar(a: Int, b: Int): Int {
return a + b
}
Características
- Solo depende de sus argumentos.
- No modifica nada fuera.
- Es 100 % predecible → siempre que
a = 3yb = 2, el resultado será5.
Ejemplo de función impura¶
var total = 0
fun sumarImpura(a: Int) {
total += a // modifica una variable global
}
Problemas
- Depende del valor de
total(estado externo). - Cambia el entorno → efecto secundario.
- Llamarla dos veces con el mismo valor da resultados diferentes.
En Jetpack Compose¶
Compose está diseñado alrededor del concepto de funciones puras de interfaz: un composable ideal debería comportarse igual cada vez que recibe los mismos parámetros.
@Composable
fun Saludo(nombre: String) {
Text("Hola, $nombre 👋")
}
// Función pura: lógica de negocio
fun calcularDescuento(precio: Double, porcentaje: Double): Double {
return precio - (precio * (porcentaje / 100))
}
// UI reactiva: Compose muestra el resultado
@Composable
fun CalculadoraDescuento() {
var precio by remember { mutableStateOf("") }
var porcentaje by remember { mutableStateOf("") }
val resultado = if (precio.isNotBlank() && porcentaje.isNotBlank()) {
calcularDescuento(precio.toDouble(), porcentaje.toDouble())
} else null
Column(modifier = Modifier.padding(16.dp)) {
OutlinedTextField(
value = precio,
onValueChange = { precio = it },
label = { Text("Precio original") }
)
OutlinedTextField(
value = porcentaje,
onValueChange = { porcentaje = it },
label = { Text("Descuento (%)") }
)
resultado?.let {
Text("Precio final: %.2f €".format(it), style = MaterialTheme.typography.titleMedium)
}
}
}
Fíjate que...
calcularDescuento()es pura → se puede probar en un test unitario.CalculadoraDescuento()es impura → depende del estado de la UI y del framework Compose.- Separamos responsabilidades: lógica de negocio (pura) y presentación (reactiva).
Ventajas de las funciones puras¶
| Ventaja | Descripción |
|---|---|
| Predecibles | Siempre devuelven el mismo resultado con los mismos datos. |
| Testeables | Se pueden probar sin interfaz ni dependencias. |
| Reutilizables | No dependen del contexto ni del framework. |
| Eficientes | Facilitan recomposición y optimización en Compose. |