Reputation: 8841
What is the difference between a named and anonymous function?
How is hello = &("Hello, #{&1}")
an anonymous function?
Upvotes: 4
Views: 1039
Reputation: 102
The function itself has no name, it is bound to a variable, but you could place it inline anywhere a function is expected like:
Enum.map([1,2,3], &("Hello, #{&1}") )
No name. Anonymous.
Upvotes: 1
Reputation: 2267
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.
Upvotes: 5
Reputation: 206
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.
Upvotes: 3