Elixir - Functions



A function is a set of statements organized together to perform a specific task. Functions in programming work mostly like function in Math. You give functions some input, they generate output based on the input provided.

There are 2 types of functions in Elixir −

Anonymous function

Functions defined using the fn..end construct are anonymous functions. These functions are sometimes also called as lambdas. They are used by assigning them to variable names.

Named function

Functions defined using the def keyword are named functions. These are native functions provided in Elixir.

Anonymous Functions

Just as the name implies, an anonymous function has no name. These are frequently passed to other functions. To define an anonymous function in Elixir, we need the fn and end keywords. Within these, we can define any number of parameters and function bodies separated by ->. For example,

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

When running above program, is run, it generates the following result −

6

Note that these functions are not called like the named functions. We have a '.' between the function name and its arguments.

Using the Capture Operator

We can also define these functions using the capture operator. This is an easier method to create functions. We will now define the above sum function using the capture operator,

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

When the above program is run, it generates the following result −

3

In the shorthand version, our parameters are not named but are available to us as &1, &2, &3, and so on.

Pattern Matching Functions

Pattern matching is not only limited to variables and data structures. We can use pattern matching to make our functions polymorphic. For example, we will declare a function that can either take 1 or 2 inputs (within a tuple) and print them to the console,

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"})

When the above program is run, it produces the following result −

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

Named Functions

We can define functions with names so we can easily refer to them later. Named functions are defined within a module using the def keyword. Named functions are always defined in a module. To call named functions, we need to reference them using their module name.

The following is the syntax for named functions −

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

Let us now define our named function sum within the Math module.

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

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

When running above program, it produces following result −

11

For 1-liner functions, there is a shorthand notation to define these functions, using do:. For example −

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

When running above program, it produces following result −

11

Private Functions

Elixir provides us the ability to define private functions that can be accessed from within the module in which they are defined. To define a private function, use defp instead of def. For example,

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

Greeter.hello("world")

When the above program is run, it produces the following result −

Hello world

But if we just try to explicitly call phrase function, using the Greeter.phrase() function, it will raise an error.

Default arguments

If we want a default value for an argument, we use the argument \\ value syntax −

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")

When the above program is run, it produces the following result −

Hello, Ayush
Hello, Ayush
Hola, Ayush
Advertisements