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.










share|improve this question


























    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.










    share|improve this question
























      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.










      share|improve this question













      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






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked Nov 7 at 10:24









      asdfsarandom

      11710




      11710
























          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.






          share|improve this answer



















          • 1




            OK I did not see that thanks .
            – asdfsarandom
            Nov 7 at 10:58


















          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.






          share|improve this answer





















            Your Answer






            StackExchange.ifUsing("editor", function () {
            StackExchange.using("externalEditor", function () {
            StackExchange.using("snippets", function () {
            StackExchange.snippets.init();
            });
            });
            }, "code-snippets");

            StackExchange.ready(function() {
            var channelOptions = {
            tags: "".split(" "),
            id: "1"
            };
            initTagRenderer("".split(" "), "".split(" "), channelOptions);

            StackExchange.using("externalEditor", function() {
            // Have to fire editor after snippets, if snippets enabled
            if (StackExchange.settings.snippets.snippetsEnabled) {
            StackExchange.using("snippets", function() {
            createEditor();
            });
            }
            else {
            createEditor();
            }
            });

            function createEditor() {
            StackExchange.prepareEditor({
            heartbeatType: 'answer',
            convertImagesToLinks: true,
            noModals: true,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: 10,
            bindNavPrevention: true,
            postfix: "",
            imageUploader: {
            brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
            contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
            allowUrls: true
            },
            onDemand: true,
            discardSelector: ".discard-answer"
            ,immediatelyShowMarkdownHelp:true
            });


            }
            });














             

            draft saved


            draft discarded


















            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

























            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.






            share|improve this answer



















            • 1




              OK I did not see that thanks .
              – asdfsarandom
              Nov 7 at 10:58















            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.






            share|improve this answer



















            • 1




              OK I did not see that thanks .
              – asdfsarandom
              Nov 7 at 10:58













            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.






            share|improve this answer














            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.







            share|improve this answer














            share|improve this answer



            share|improve this answer








            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














            • 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












            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.






            share|improve this answer

























              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.






              share|improve this answer























                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.






                share|improve this answer












                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.







                share|improve this answer












                share|improve this answer



                share|improve this answer










                answered Nov 7 at 13:23









                legoscia

                28.2k1178109




                28.2k1178109






























                     

                    draft saved


                    draft discarded



















































                     


                    draft saved


                    draft discarded














                    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





















































                    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







                    這個網誌中的熱門文章

                    Xamarin.form Move up view when keyboard appear

                    Post-Redirect-Get with Spring WebFlux and Thymeleaf

                    Anylogic : not able to use stopDelay()