Guardas

Una guarda es una anotación condicional que se pone en una función y que hace que esa función sólo pueda ser utilizada si la precondición que hemos indicado se cumple de antemano con los parámetros. Lo podemos usar para controlar los tipos o los valores que se están intentando proporcionar a la función.

Vamos a ampliar nuestra calculadora en Elixir para manejar operaciones básicas como suma, resta, multiplicación y división. Al implementar la división, nos encontramos con un problema clásico: la división por cero. Si intentamos dividir un número entre cero, Elixir nos lanza un error aritmético, lo que nos obliga a buscar una forma de manejar esta situación sin que el programa falle.

Una solución sencilla sería usar un condicional dentro de la función para detectar si el divisor es cero y devolver un valor especial, como un átomo :infinito. Por ejemplo, podríamos escribir algo así:

def dividir(a, b) do
  if b == 0 do
    :infinito
  else
    a / b
  end
end

Esto funciona, pero Elixir nos ofrece una forma más elegante y potente para manejar casos como este: las guardas. Las guardas nos permiten definir múltiples funciones con el mismo nombre y aridad, pero con condiciones que determinan cuál se ejecuta según los argumentos que reciba.

Podemos definir dos funciones dividir/2: una que se active cuando el divisor sea cero y otra para el resto de casos. La clave está en usar la palabra clave when para establecer la condición de la guarda. Por ejemplo:

def dividir(a, 0) do
  :infinito
end

def dividir(a, b) when b != 0 do
  a / b
end

Aquí, la primera función se ejecuta solo cuando el segundo argumento es cero, devolviendo el átomo :infinito. La segunda función se activa cuando el divisor no es cero y realiza la división normalmente.

Es importante entender que Elixir evalúa las funciones de arriba hacia abajo, buscando la primera definición que coincida con el nombre, la aridad y cuya guarda se cumpla. Si la guarda no se cumple, Elixir pasa a la siguiente definición. Por eso, el orden en que declaramos estas funciones es crucial. Si colocamos primero la función sin guarda, esta se ejecutará siempre y la función con guarda nunca se usará.

Además, las guardas nos permiten mantener nuestro código modular y claro, evitando funciones largas con múltiples condicionales internas. Podemos crear pequeñas funciones especializadas y usar guardas para controlar cuándo se deben ejecutar.

En resumen, las guardas son condiciones booleanas que se colocan fuera de la definición de la función, justo después de la firma, usando when. Permiten que Elixir seleccione la función adecuada según los argumentos, facilitando el manejo de casos especiales como la división por cero en nuestra calculadora.

A medida que avancemos, veremos más tipos de guardas y cómo aprovecharlas para escribir código más limpio y expresivo en Elixir. Por ahora, este enfoque nos ayuda a evitar errores comunes y a mantener nuestras funciones compactas y fáciles de entender.

Lista de reproducción
  1. 1
    ¿Qué es Elixir?
    10 minutos
  2. 2
    Instalación de Elixir
    9 minutos
  3. 3
    ¿Qué es la programación funcional? (Como la de Elixir)
    20 minutos
  4. 4
    ¿Cómo funciona la REPL de Elixir?
    7 minutos
  5. 5
    ¿Cómo hacer asignaciones en Elixir?
    7 minutos
  6. 6
    Operadores aritméticos básicos
    6 minutos
  7. 7
    ¿Qué son los tipos de datos de Elixir?
    5 minutos
  8. 8
    Átomos en Elixir
    4 minutos
  9. 9
    Las palabras clave nil, true y false
    6 minutos
  10. 10
    Operadores lógicos de comparación
    8 minutos
  11. 11
    Comparación estricta con ===
    3 minutos
  12. 12
    Operadores lógicos y proposicionales
    8 minutos
  13. 13
    Invocación de funciones
    10 minutos
  14. 14
    Fundamentos de funciones
    9 minutos
  15. 15
    Cadenas de caracteres
    8 minutos
  16. 16
    Entrada y salida estandar de la mano de gets y puts
    9 minutos
  17. 17
    Concatenar e interpolar strings
    9 minutos
  18. 18
    Código fuente en archivos
    9 minutos
  19. 19
    Condicional IF y bloques DO-END
    11 minutos
  20. 20
    IFs anidados, UNLESS y COND
    12 minutos
  21. 21
    Definición de funciones
    11 minutos
  22. 22
    Fundamentos de compilación de módulos
    6 minutos
  23. 23
    Guardas
    8 minutos
  24. 24
    Funciones anónimas
    7 minutos
  25. 25
    Capturar funciones
    4 minutos
  26. 26
    Invocación de funciones dentro del mismo módulo
    7 minutos
  27. 27
    Tuplas
    8 minutos
  28. 28
    Introducción al pattern matching
    8 minutos
  29. 29
    Pattern matching en funciones
    11 minutos
  30. 30
    Las tuplas :ok, :error
    7 minutos
  31. 31
    case
    10 minutos
  32. 32
    Operador pin
    7 minutos
  33. 33
    Pattern matchings y recursividad
    5 minutos
  34. 34
    Listas
    9 minutos
  35. 35
    Operadores y funciones de lista
    10 minutos
  36. 36
    Keyword lists: listas de palabras clave
    8 minutos
  37. 37
    Mapas
    7 minutos
  38. 38
    Pattern matching de mapas y keyword lists
    6 minutos
  39. 39
    Operadores y funciones para mapas y keyword lists
    5 minutos
  40. 40
    Estructuras con defstruct
    11 minutos
  41. 41
    Bitstrings
    11 minutos
  42. 42
    Charlists
    10 minutos
  43. 43
    Funciones de alto orden en Elixir
    5 minutos
  44. 44
    Uso de la función filter
    10 minutos
  45. 45
    Uso de la función map
    7 minutos
  46. 46
    Uso de la función reduce
    9 minutos
  47. 47
    Pipelines
    11 minutos
  48. 48
    Rangos y Streams
    11 minutos
  49. 49
    Funciones recursivas con listas
    14 minutos