Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What Is The Difference Between A Named And An Anonymous Function In Elixir?

What is the difference between a named and anonymous function?

How is hello = &("Hello, #{&1}") an anonymous function?

like image 500
user1354934 Avatar asked Jan 06 '23 01:01

user1354934


2 Answers

The main difference is one of scope. What do you have access to in the function body.

Named functions in Elixir are grouped into modules, and their scope is limited to the arguments given to them.

An anonymous function can be defined anywhere, and have access to whatever is visible in their immediate surrounding. The jargon is that they are "closures", that they "close over" surrounding scope.

Let's look at an example:

c = 10

anon = fn(a, b) -> a + b + c end
anon.(1, 2) # => 13, because c is available in the anonymous function

# The module below will fail to compile, because c isn't available
defmodule MyModule do
  def named(a, b), do: a + b + c
end

You can create an anonymous functions from a named function with the & capture operator, and it will have access to your current scope. This is common, as many functions expect other functions as arguments. Browse through the docs for Enum, and you'll see plenty of examples.

You'll notice I called the anonymous anon function like this: anon.(1, 2), instead of anon(1, 2). It makes the difference between the two kinds of functions more explicit in your code.

José gave a good answer to a related question.

like image 56
Martin Svalin Avatar answered Jan 14 '23 13:01

Martin Svalin


A named function needs to be defined inside a module. An anonymous function doesn't have that restriction.

On your example, &("Hello, #{&1}") is the anonymous function part. It is using the capture operator &, so this function is just a shorter way of writing fn (x) -> "Hello, #{x}" end. The &1 is a placeholder for the function parameter. You can assign that anonymous function to a variable (hello in this case). To access the function via the variable you use hello.("Derek"). Don't forget the dot!

Remember that Function is also a type in Elixir and functions are first-class citizen, that's why you can assign it to a variable and make functions return other functions.

like image 33
Ricardo Marinovic Avatar answered Jan 14 '23 14:01

Ricardo Marinovic