Elixir: Is there any benefit of using & operator to get an anonymous function out of a named function
up vote
1
down vote
favorite
So I was reading this book and at some point it states that :
There’s a second form of the & function capture operator. You can give
it the name and arity (number of parameters) of an existing function,
and it will return an anonymous function that calls it.
But I don't understand why would somebody want to do this. What is the benefit one can get out of it, knowing that you can can bound both named and unnamed function to variables if you want to.
elixir operators anonymous-function
add a comment |
up vote
1
down vote
favorite
So I was reading this book and at some point it states that :
There’s a second form of the & function capture operator. You can give
it the name and arity (number of parameters) of an existing function,
and it will return an anonymous function that calls it.
But I don't understand why would somebody want to do this. What is the benefit one can get out of it, knowing that you can can bound both named and unnamed function to variables if you want to.
elixir operators anonymous-function
add a comment |
up vote
1
down vote
favorite
up vote
1
down vote
favorite
So I was reading this book and at some point it states that :
There’s a second form of the & function capture operator. You can give
it the name and arity (number of parameters) of an existing function,
and it will return an anonymous function that calls it.
But I don't understand why would somebody want to do this. What is the benefit one can get out of it, knowing that you can can bound both named and unnamed function to variables if you want to.
elixir operators anonymous-function
So I was reading this book and at some point it states that :
There’s a second form of the & function capture operator. You can give
it the name and arity (number of parameters) of an existing function,
and it will return an anonymous function that calls it.
But I don't understand why would somebody want to do this. What is the benefit one can get out of it, knowing that you can can bound both named and unnamed function to variables if you want to.
elixir operators anonymous-function
elixir operators anonymous-function
asked Nov 7 at 10:24
asdfsarandom
11710
11710
add a comment |
add a comment |
2 Answers
2
active
oldest
votes
up vote
5
down vote
accepted
It's pretty common to have some simple functions like
Enum.map(list, fn(element) -> element.id end)
Or just
Enum.map(list, &(&1.id))
With some practice, second one is even easier to read than the first
Regarding your question, you can also call a named function in the same way
Enum.map(list, &Integer.to_string/1)
Alternative is to pass a function to the Enum using fn
Enum.map(list, fn(number) -> Integer.to_string(number) end)
Also, captured variant is easier to read.
1
OK I did not see that thanks .
– asdfsarandom
Nov 7 at 10:58
add a comment |
up vote
3
down vote
The book is incorrect. &MyModule.my_function/0
does not return "an anonymous function that calls the given function" - it returns a function object that refers to the named function. To get an anonymous function, you'd use fn -> MyModule.my_function() end
.
This becomes important when you reload modules at runtime: an anonymous function is part of the module it was created in, and since only two versions of a given module are kept in the virtual machine (the "current" and the "old" version), you could end up with a function that can't be called anymore.
Let's start with this module:
defmodule MyModule do
def the_real_function() do
2
end
def anonymous_function() do
fn -> __MODULE__.the_real_function() end
end
def named_function() do
&__MODULE__.the_real_function/0
end
end
It contains the function we're actually interested in, and two functions that return functions that refer to the real function - one with an anonymous function, one with a named function object.
Let's load the module, get two function objects, and check that we can call them:
iex(1)> c "my_module.ex"
[MyModule]
iex(2)> f_anon = MyModule.anonymous_function()
#Function<0.62651516/0 in MyModule.anonymous_function/0>
iex(3)> f_named = MyModule.named_function()
&MyModule.the_real_function/0
iex(4)> f_anon.()
2
iex(5)> f_named.()
2
So far so good. Now, let's say we need to update the module, so that the function returns 3 instead. We edit the module and reload it:
iex(6)> c "my_module.ex"
warning: redefining module MyModule (current version defined in memory)
my_module.ex:1
[MyModule]
iex(7)> f_anon.()
3
iex(8)> f_named.()
3
Our function references still work - good. Say we need to update the module again, to return 4:
iex(9)> c "my_module.ex"
warning: redefining module MyModule (current version defined in memory)
my_module.ex:1
[MyModule]
iex(10)> f_anon.()
** (BadFunctionError) expected a function, got: #Function<0.62651516/0 in MyModule>
iex(10)> f_named.()
4
Now the anonymous function is broken! That's because we got a reference to it two module versions back, and therefore the code for this anonymous function is no longer kept in the VM. The named function reference still works, because it just refers to the function with the given module, name and arity.
add a comment |
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
5
down vote
accepted
It's pretty common to have some simple functions like
Enum.map(list, fn(element) -> element.id end)
Or just
Enum.map(list, &(&1.id))
With some practice, second one is even easier to read than the first
Regarding your question, you can also call a named function in the same way
Enum.map(list, &Integer.to_string/1)
Alternative is to pass a function to the Enum using fn
Enum.map(list, fn(number) -> Integer.to_string(number) end)
Also, captured variant is easier to read.
1
OK I did not see that thanks .
– asdfsarandom
Nov 7 at 10:58
add a comment |
up vote
5
down vote
accepted
It's pretty common to have some simple functions like
Enum.map(list, fn(element) -> element.id end)
Or just
Enum.map(list, &(&1.id))
With some practice, second one is even easier to read than the first
Regarding your question, you can also call a named function in the same way
Enum.map(list, &Integer.to_string/1)
Alternative is to pass a function to the Enum using fn
Enum.map(list, fn(number) -> Integer.to_string(number) end)
Also, captured variant is easier to read.
1
OK I did not see that thanks .
– asdfsarandom
Nov 7 at 10:58
add a comment |
up vote
5
down vote
accepted
up vote
5
down vote
accepted
It's pretty common to have some simple functions like
Enum.map(list, fn(element) -> element.id end)
Or just
Enum.map(list, &(&1.id))
With some practice, second one is even easier to read than the first
Regarding your question, you can also call a named function in the same way
Enum.map(list, &Integer.to_string/1)
Alternative is to pass a function to the Enum using fn
Enum.map(list, fn(number) -> Integer.to_string(number) end)
Also, captured variant is easier to read.
It's pretty common to have some simple functions like
Enum.map(list, fn(element) -> element.id end)
Or just
Enum.map(list, &(&1.id))
With some practice, second one is even easier to read than the first
Regarding your question, you can also call a named function in the same way
Enum.map(list, &Integer.to_string/1)
Alternative is to pass a function to the Enum using fn
Enum.map(list, fn(number) -> Integer.to_string(number) end)
Also, captured variant is easier to read.
edited Nov 7 at 10:42
answered Nov 7 at 10:30
denis.peplin
5,74333144
5,74333144
1
OK I did not see that thanks .
– asdfsarandom
Nov 7 at 10:58
add a comment |
1
OK I did not see that thanks .
– asdfsarandom
Nov 7 at 10:58
1
1
OK I did not see that thanks .
– asdfsarandom
Nov 7 at 10:58
OK I did not see that thanks .
– asdfsarandom
Nov 7 at 10:58
add a comment |
up vote
3
down vote
The book is incorrect. &MyModule.my_function/0
does not return "an anonymous function that calls the given function" - it returns a function object that refers to the named function. To get an anonymous function, you'd use fn -> MyModule.my_function() end
.
This becomes important when you reload modules at runtime: an anonymous function is part of the module it was created in, and since only two versions of a given module are kept in the virtual machine (the "current" and the "old" version), you could end up with a function that can't be called anymore.
Let's start with this module:
defmodule MyModule do
def the_real_function() do
2
end
def anonymous_function() do
fn -> __MODULE__.the_real_function() end
end
def named_function() do
&__MODULE__.the_real_function/0
end
end
It contains the function we're actually interested in, and two functions that return functions that refer to the real function - one with an anonymous function, one with a named function object.
Let's load the module, get two function objects, and check that we can call them:
iex(1)> c "my_module.ex"
[MyModule]
iex(2)> f_anon = MyModule.anonymous_function()
#Function<0.62651516/0 in MyModule.anonymous_function/0>
iex(3)> f_named = MyModule.named_function()
&MyModule.the_real_function/0
iex(4)> f_anon.()
2
iex(5)> f_named.()
2
So far so good. Now, let's say we need to update the module, so that the function returns 3 instead. We edit the module and reload it:
iex(6)> c "my_module.ex"
warning: redefining module MyModule (current version defined in memory)
my_module.ex:1
[MyModule]
iex(7)> f_anon.()
3
iex(8)> f_named.()
3
Our function references still work - good. Say we need to update the module again, to return 4:
iex(9)> c "my_module.ex"
warning: redefining module MyModule (current version defined in memory)
my_module.ex:1
[MyModule]
iex(10)> f_anon.()
** (BadFunctionError) expected a function, got: #Function<0.62651516/0 in MyModule>
iex(10)> f_named.()
4
Now the anonymous function is broken! That's because we got a reference to it two module versions back, and therefore the code for this anonymous function is no longer kept in the VM. The named function reference still works, because it just refers to the function with the given module, name and arity.
add a comment |
up vote
3
down vote
The book is incorrect. &MyModule.my_function/0
does not return "an anonymous function that calls the given function" - it returns a function object that refers to the named function. To get an anonymous function, you'd use fn -> MyModule.my_function() end
.
This becomes important when you reload modules at runtime: an anonymous function is part of the module it was created in, and since only two versions of a given module are kept in the virtual machine (the "current" and the "old" version), you could end up with a function that can't be called anymore.
Let's start with this module:
defmodule MyModule do
def the_real_function() do
2
end
def anonymous_function() do
fn -> __MODULE__.the_real_function() end
end
def named_function() do
&__MODULE__.the_real_function/0
end
end
It contains the function we're actually interested in, and two functions that return functions that refer to the real function - one with an anonymous function, one with a named function object.
Let's load the module, get two function objects, and check that we can call them:
iex(1)> c "my_module.ex"
[MyModule]
iex(2)> f_anon = MyModule.anonymous_function()
#Function<0.62651516/0 in MyModule.anonymous_function/0>
iex(3)> f_named = MyModule.named_function()
&MyModule.the_real_function/0
iex(4)> f_anon.()
2
iex(5)> f_named.()
2
So far so good. Now, let's say we need to update the module, so that the function returns 3 instead. We edit the module and reload it:
iex(6)> c "my_module.ex"
warning: redefining module MyModule (current version defined in memory)
my_module.ex:1
[MyModule]
iex(7)> f_anon.()
3
iex(8)> f_named.()
3
Our function references still work - good. Say we need to update the module again, to return 4:
iex(9)> c "my_module.ex"
warning: redefining module MyModule (current version defined in memory)
my_module.ex:1
[MyModule]
iex(10)> f_anon.()
** (BadFunctionError) expected a function, got: #Function<0.62651516/0 in MyModule>
iex(10)> f_named.()
4
Now the anonymous function is broken! That's because we got a reference to it two module versions back, and therefore the code for this anonymous function is no longer kept in the VM. The named function reference still works, because it just refers to the function with the given module, name and arity.
add a comment |
up vote
3
down vote
up vote
3
down vote
The book is incorrect. &MyModule.my_function/0
does not return "an anonymous function that calls the given function" - it returns a function object that refers to the named function. To get an anonymous function, you'd use fn -> MyModule.my_function() end
.
This becomes important when you reload modules at runtime: an anonymous function is part of the module it was created in, and since only two versions of a given module are kept in the virtual machine (the "current" and the "old" version), you could end up with a function that can't be called anymore.
Let's start with this module:
defmodule MyModule do
def the_real_function() do
2
end
def anonymous_function() do
fn -> __MODULE__.the_real_function() end
end
def named_function() do
&__MODULE__.the_real_function/0
end
end
It contains the function we're actually interested in, and two functions that return functions that refer to the real function - one with an anonymous function, one with a named function object.
Let's load the module, get two function objects, and check that we can call them:
iex(1)> c "my_module.ex"
[MyModule]
iex(2)> f_anon = MyModule.anonymous_function()
#Function<0.62651516/0 in MyModule.anonymous_function/0>
iex(3)> f_named = MyModule.named_function()
&MyModule.the_real_function/0
iex(4)> f_anon.()
2
iex(5)> f_named.()
2
So far so good. Now, let's say we need to update the module, so that the function returns 3 instead. We edit the module and reload it:
iex(6)> c "my_module.ex"
warning: redefining module MyModule (current version defined in memory)
my_module.ex:1
[MyModule]
iex(7)> f_anon.()
3
iex(8)> f_named.()
3
Our function references still work - good. Say we need to update the module again, to return 4:
iex(9)> c "my_module.ex"
warning: redefining module MyModule (current version defined in memory)
my_module.ex:1
[MyModule]
iex(10)> f_anon.()
** (BadFunctionError) expected a function, got: #Function<0.62651516/0 in MyModule>
iex(10)> f_named.()
4
Now the anonymous function is broken! That's because we got a reference to it two module versions back, and therefore the code for this anonymous function is no longer kept in the VM. The named function reference still works, because it just refers to the function with the given module, name and arity.
The book is incorrect. &MyModule.my_function/0
does not return "an anonymous function that calls the given function" - it returns a function object that refers to the named function. To get an anonymous function, you'd use fn -> MyModule.my_function() end
.
This becomes important when you reload modules at runtime: an anonymous function is part of the module it was created in, and since only two versions of a given module are kept in the virtual machine (the "current" and the "old" version), you could end up with a function that can't be called anymore.
Let's start with this module:
defmodule MyModule do
def the_real_function() do
2
end
def anonymous_function() do
fn -> __MODULE__.the_real_function() end
end
def named_function() do
&__MODULE__.the_real_function/0
end
end
It contains the function we're actually interested in, and two functions that return functions that refer to the real function - one with an anonymous function, one with a named function object.
Let's load the module, get two function objects, and check that we can call them:
iex(1)> c "my_module.ex"
[MyModule]
iex(2)> f_anon = MyModule.anonymous_function()
#Function<0.62651516/0 in MyModule.anonymous_function/0>
iex(3)> f_named = MyModule.named_function()
&MyModule.the_real_function/0
iex(4)> f_anon.()
2
iex(5)> f_named.()
2
So far so good. Now, let's say we need to update the module, so that the function returns 3 instead. We edit the module and reload it:
iex(6)> c "my_module.ex"
warning: redefining module MyModule (current version defined in memory)
my_module.ex:1
[MyModule]
iex(7)> f_anon.()
3
iex(8)> f_named.()
3
Our function references still work - good. Say we need to update the module again, to return 4:
iex(9)> c "my_module.ex"
warning: redefining module MyModule (current version defined in memory)
my_module.ex:1
[MyModule]
iex(10)> f_anon.()
** (BadFunctionError) expected a function, got: #Function<0.62651516/0 in MyModule>
iex(10)> f_named.()
4
Now the anonymous function is broken! That's because we got a reference to it two module versions back, and therefore the code for this anonymous function is no longer kept in the VM. The named function reference still works, because it just refers to the function with the given module, name and arity.
answered Nov 7 at 13:23
legoscia
28.2k1178109
28.2k1178109
add a comment |
add a comment |
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53187557%2felixir-is-there-any-benefit-of-using-operator-to-get-an-anonymous-function-ou%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown