En Elixir, las funciones son piezas fundamentales que nos permiten transformar entradas en salidas siguiendo reglas definidas por expresiones con incógnitas. Podemos pensar en ellas como cajas negras: les damos ciertos valores de entrada y ellas nos devuelven un resultado, sin necesidad de saber cómo se realiza el cálculo interno. Esta idea es similar a cómo funcionan los operadores matemáticos que ya conocemos, como la suma o la multiplicación, que reciben operandos y devuelven un resultado.
Una función en Elixir recibe una o varias entradas y produce una salida, pero lo interesante es que internamente está definida por una expresión que contiene incógnitas o huecos. Estos huecos son los parámetros que debemos proporcionar para que la función pueda evaluarse y devolver un resultado. A diferencia de una variable que almacena un valor ya evaluado, una función guarda la expresión con esos huecos sin resolver, y solo cuando le damos los valores necesarios se evalúa completamente.
Por ejemplo, cuando escribimos en IEX 3 + 4, el intérprete evalúa inmediatamente la expresión y nos devuelve 7. Si hacemos una asignación como x = 3 + 4, la variable x almacenará el valor 7, no la expresión 3 + 4. Esto se debe a que IEX evalúa primero la expresión y luego guarda el resultado, optimizando así el uso de memoria y procesamiento. Sin embargo, con las funciones no ocurre lo mismo: ellas almacenan la expresión con sus incógnitas para evaluarlas cuando se les proporcionen los parámetros.
Elixir cuenta con una amplia librería estándar que incluye muchas funciones ya definidas para realizar operaciones comunes. Por ejemplo, aunque no existe un operador específico para calcular el resto de una división (el módulo) como en otros lenguajes, sí tenemos la función rem que cumple esa función. Esta función recibe dos parámetros: el dividendo y el divisor, y devuelve el resto de la división entera.
Para invocar una función en Elixir, escribimos su nombre seguido de los parámetros entre paréntesis, separados por comas. Por ejemplo, para calcular el resto de dividir 5 entre 2, escribimos:
rem(5, 2)
El resultado de esta expresión será 1, que es el resto de la división.
Otra función útil que trae Elixir es round, que redondea un número decimal al entero más cercano. Si el decimal es 0.5 o mayor, redondea hacia arriba; si es menor, redondea hacia abajo. Por ejemplo:
round(3.75) # Devuelve 4
round(3.25) # Devuelve 3
Al invocar funciones, los parámetros que pasamos pueden ser constantes, variables o incluso otras expresiones. Por ejemplo, si tenemos una variable x con valor 7, podemos combinar funciones así:
x = 7
rem(x, round(3.25)) # Evalúa rem(7, 3), que devuelve 1
Esto muestra cómo las expresiones en Elixir pueden ser primitivas o compuestas, y cómo las funciones se integran en esta estructura expresiva del lenguaje. En definitiva, las funciones nos permiten encapsular transformaciones de datos de forma clara y reutilizable, y su invocación sigue una sintaxis sencilla y consistente que facilita su uso en todo tipo de cálculos y operaciones.