Elixir - Funciones

Una función es un conjunto de declaraciones organizadas juntas para realizar una tarea específica. Las funciones en programación funcionan principalmente como funciones en matemáticas. Le das a las funciones algo de entrada, generan resultados basados ​​en la entrada proporcionada.

Hay 2 tipos de funciones en Elixir:

Función anónima

Funciones definidas mediante el fn..end constructson funciones anónimas. Estas funciones a veces también se denominan lambdas. Se utilizan asignándolos a nombres de variables.

Función nombrada

Funciones definidas mediante el def keywordson funciones nombradas. Estas son funciones nativas proporcionadas en Elixir.

Funciones anónimas

Tal como su nombre lo indica, una función anónima no tiene nombre. Estos se pasan con frecuencia a otras funciones. Para definir una función anónima en Elixir, necesitamos elfn y endpalabras clave. Dentro de estos, podemos definir cualquier número de parámetros y cuerpos de función separados por->. Por ejemplo,

sum = fn (a, b) -> a + b end
IO.puts(sum.(1, 5))

Cuando se ejecuta el programa anterior, se ejecuta, genera el siguiente resultado:

6

Tenga en cuenta que estas funciones no se llaman como las funciones nombradas. Tenemos una '.'entre el nombre de la función y sus argumentos.

Uso del operador de captura

También podemos definir estas funciones usando el operador de captura. Este es un método más sencillo para crear funciones. Ahora definiremos la función de suma anterior usando el operador de captura,

sum = &(&1 + &2) 
IO.puts(sum.(1, 2))

Cuando se ejecuta el programa anterior, genera el siguiente resultado:

3

En la versión abreviada, nuestros parámetros no tienen nombre, pero están disponibles para nosotros como & 1, & 2, & 3, y así sucesivamente.

Funciones de coincidencia de patrones

La coincidencia de patrones no se limita solo a variables y estructuras de datos. Podemos usar la coincidencia de patrones para hacer que nuestras funciones sean polimórficas. Por ejemplo, declararemos una función que puede tomar 1 o 2 entradas (dentro de una tupla) e imprimirlas en la consola,

handle_result = fn
   {var1} -> IO.puts("#{var1} found in a tuple!")
   {var_2, var_3} -> IO.puts("#{var_2} and #{var_3} found!")
end
handle_result.({"Hey people"})
handle_result.({"Hello", "World"})

Cuando se ejecuta el programa anterior, produce el siguiente resultado:

Hey people found in a tuple!
Hello and World found!

Funciones nombradas

Podemos definir funciones con nombres para poder referirnos a ellas fácilmente más adelante. Las funciones nombradas se definen dentro de un módulo usando la palabra clave def. Las funciones nombradas siempre se definen en un módulo. Para llamar a funciones nombradas, necesitamos hacer referencia a ellas usando su nombre de módulo.

La siguiente es la sintaxis para funciones con nombre:

def function_name(argument_1, argument_2) do
   #code to be executed when function is called
end

Definamos ahora nuestra función denominada suma dentro del módulo Matemáticas.

defmodule Math do
   def sum(a, b) do
      a + b
   end
end

IO.puts(Math.sum(5, 6))

Cuando se ejecuta el programa anterior, produce el siguiente resultado:

11

Para las funciones de una línea, hay una notación abreviada para definir estas funciones, usando do:. Por ejemplo

defmodule Math do
   def sum(a, b), do: a + b
end
IO.puts(Math.sum(5, 6))

Cuando se ejecuta el programa anterior, produce el siguiente resultado:

11

Funciones privadas

Elixir nos brinda la posibilidad de definir funciones privadas a las que se puede acceder desde dentro del módulo en el que están definidas. Para definir una función privada, usedefp en vez de def. Por ejemplo,

defmodule Greeter do
   def hello(name), do: phrase <> name
   defp phrase, do: "Hello "
end

Greeter.hello("world")

Cuando se ejecuta el programa anterior, produce el siguiente resultado:

Hello world

Pero si solo intentamos llamar explícitamente a la función de frase, usando el Greeter.phrase() función, generará un error.

Argumentos predeterminados

Si queremos un valor predeterminado para un argumento, usamos el argument \\ value sintaxis -

defmodule Greeter do
   def hello(name, country \\ "en") do
      phrase(country) <> name
   end

   defp phrase("en"), do: "Hello, "
   defp phrase("es"), do: "Hola, "
end

Greeter.hello("Ayush", "en")
Greeter.hello("Ayush")
Greeter.hello("Ayush", "es")

Cuando se ejecuta el programa anterior, produce el siguiente resultado:

Hello, Ayush
Hello, Ayush
Hola, Ayush