Capturar funciones

Al capturar funciones podemos obtener referencias a funciones que sí esten declaradas en módulos, para poderlas emplear en casos como pasarlas como parámetro a otras funciones, parecido a las funciones anónimas.

Cuando trabajamos con funciones en Elixir, a menudo nos encontramos con la necesidad de pasar funciones existentes como parámetros a otras funciones. Aunque las funciones anónimas son muy útiles para esto, muchas veces la función que queremos utilizar ya está definida en alguna librería, y no queremos ni necesitamos reescribirla. Por ejemplo, imaginemos que queremos usar la función rem, que nos devuelve el resto de una división.

El problema es que no podemos simplemente pasar rem como si fuera una variable, porque en Elixir las funciones no son variables en sí mismas. rem es un identificador de función dentro del módulo Kernel, y no está disponible como un valor que podamos manipular directamente. Entonces, ¿cómo podemos pasar esa función para usarla como parámetro?

La solución está en capturar la función. Capturar una función no significa secuestrarla ni nada por el estilo, sino convertir esa función que ya existe en un módulo en una expresión que podamos tratar como una variable. Esto nos permite pasarla, almacenarla o reutilizarla fácilmente.

Para capturar una función en Elixir, usamos el operador ampersand &. Este operador nos permite referenciar una función existente junto con su aridad, que es el número de argumentos que recibe. Por ejemplo, para capturar la función rem que recibe dos argumentos, escribimos &rem/2. Esto crea una función anónima que podemos asignar a una variable o pasar como parámetro.

Al hacer esto, puede que veamos que la función capturada aparece como perteneciente a Erlang, por ejemplo, :erlang.rem. Esto ocurre porque muchas funciones nativas de Elixir son simplemente atajos a funciones de la librería estándar de Erlang. Erlang utiliza átomos para nombrar sus módulos, y Elixir aprovecha estas funciones sin necesidad de reinventarlas.

Si queremos capturar otra función que forma parte de un módulo, como String.trim, simplemente escribimos &String.trim/1. Así, podemos asignar esta función a una variable, por ejemplo:

recortar = &String.trim/1

A partir de aquí, recortar es una variable que contiene una función, y podemos aplicarla usando la sintaxis de llamada a función anónima:

recortar.("  hola  ")
# Resultado: "hola"

Volviendo al ejemplo de rem, si queremos usarla en una función que espera recibir una función como parámetro, primero la capturamos:

rem2 = &rem/2

Y luego podemos pasar rem2 donde necesitemos, trabajando con ella como una función anónima.

Es importante recordar que para capturar una función debemos usar el ampersand y especificar la aridad correcta. Olvidar cualquiera de estos detalles es un error común, especialmente al principio, pero con la práctica se vuelve natural.

En definitiva, capturar funciones en Elixir con el operador & nos permite transformar funciones existentes en valores que podemos manipular, facilitando la reutilización y el paso de funciones como parámetros en nuestros programas.

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