Introducción al pattern matching

El pattern matching es uno de los elementos esenciales de Elixir. Con el pattern matching se pueden escribir expresiones con algunas incógnitas (en forma de variable) y dejar que sea el propio lenguaje quien trate de buscar las soluciones. Por el camino, nos dice qué valor tendrán esas incógnitas.

El pattern matching en Elixir es una de las características más potentes y distintivas del lenguaje, y entenderlo bien nos abre la puerta a escribir código más claro y expresivo. Aunque a primera vista pueda parecer complicado, en realidad es un concepto muy natural si lo pensamos como una forma de despejar incógnitas para que dos expresiones encajen.

Cuando usamos el operador igual en Elixir, no estamos haciendo una asignación tradicional como en otros lenguajes. En realidad, estamos usando un operador especial que intenta hacer que la expresión de la izquierda y la de la derecha coincidan. Por ejemplo, si escribimos x = 5, lo que Elixir hace es preguntarse: ¿qué valor debe tener x para que esta igualdad sea cierta? La respuesta es que x debe valer 5, y por eso el valor se asigna. Pero no es una asignación en el sentido clásico, sino un encaje de patrones.

Este mecanismo funciona como resolver una ecuación matemática. Si tenemos x = 4 + 6, Elixir calcula que x debe valer 10 para que la igualdad sea verdadera. Sin embargo, no podemos poner dos incógnitas sin más, como x + y = 4 + 6, porque no hay una única solución para eso. El pattern matching requiere que haya una única forma de que las expresiones coincidan.

Cuando empezamos a trabajar con tuplas, el pattern matching se vuelve aún más interesante. Por ejemplo, si hacemos x = {:hello, :goodbye}, Elixir entiende que para que x sea igual a esa tupla, x debe ser exactamente esa tupla. Pero podemos ir más allá y usar variables dentro de la tupla para descomponerla. Si escribimos {a, b} = {:hello, :goodbye}, Elixir buscará qué valores deben tener a y b para que la igualdad sea cierta. En este caso, a será :hello y b será :goodbye. Así, el pattern matching nos permite extraer valores de estructuras complejas de forma sencilla.

Sin embargo, el pattern matching no siempre funciona. Por ejemplo, si intentamos hacer {a, b, c} = {:ok}, no hay forma de que una tupla de tres elementos sea igual a una tupla de uno solo. Esto genera un error de coincidencia (match error), porque no existe una solución que haga que ambas expresiones encajen. Otro caso donde falla es cuando intentamos hacer coincidir dos tuplas con valores constantes que no son iguales, como {:true, texto} = {:false, "hola mundo"}. Aquí, aunque texto pueda tomar cualquier valor, el primer elemento no coincide, por lo que el pattern matching no puede completarse.

También podemos hacer pattern matching con valores constantes y variables mezclados. Por ejemplo, si tenemos {1, a, 3} = {1, 2, 3}, Elixir buscará qué valor debe tener a para que la igualdad sea cierta, y en este caso a será 2. Esto nos permite hacer coincidir parcialmente estructuras y extraer solo las partes que nos interesan.

Es importante tener en cuenta que el pattern matching puede fallar por varias razones: porque las estructuras tienen diferente tamaño, porque los valores constantes no coinciden o porque no existe una única solución para las variables involucradas. Cuando esto sucede, Elixir nos lanza un error de coincidencia que nos indica que no ha sido posible hacer que las expresiones encajen.

Este mecanismo de encaje de patrones es fundamental en Elixir y lo vamos a usar mucho, no solo para asignar valores, sino también en funciones, condicionales y muchas otras situaciones donde necesitamos extraer información o validar estructuras de datos de forma clara y concisa. Entender bien cómo funciona el pattern matching nos permitirá aprovechar todo el potencial del lenguaje y escribir código más elegante y robusto.

Para ilustrar algunos ejemplos básicos de pattern matching con tuplas y variables, podemos ver el siguiente código:

# Asignación simple con pattern matching
x = 5
# x ahora vale 5

# Pattern matching con tuplas
x = {:hello, :goodbye}
# x es la tupla {:hello, :goodbye}

# Descomposición de tuplas con variables
{a, b} = {:hello, :goodbye}
# a es :hello
# b es :goodbye

# Pattern matching parcial con valores constantes y variables
{1, a, 3} = {1, 2, 3}
# a es 2

# Ejemplo que falla y genera un match error
{a, b, c} = {:ok}
# Error porque no coinciden los tamaños de las tuplas

Así, el pattern matching nos permite trabajar con estructuras de datos de forma muy natural y expresiva, haciendo que nuestro código sea más legible y fácil de mantener.

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