Order loaded modules by amount of functions

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty margin-bottom:0;







up vote
3
down vote

favorite












I am trying to solve some exercises from the "Programming Erlang" book.



One of them is "Write a function to determine which module exports the most functions"



This is my solution:



-module(module_info).
-export([modules_ordered_by_amount_of_functions/0]).

modules_ordered_by_amount_of_functions() ->
Modules = loaded_modules_with_functions(),
SortedModules = lists:sort(fun compare_functions_length/2, Modules),
lists:map(fun extract_amount_of_functions/1, SortedModules).

loaded_modules_with_functions() ->
LoadedModules = code:all_loaded(),
LoadedModuleNames = lists:map(fun extract_module_name/1, LoadedModules),
lists:map(fun extract_functions_from_module/1, LoadedModuleNames).

extract_module_name(ModuleName, _) -> ModuleName.

extract_functions_from_module(ModuleName) ->
[_, exports, Functions | _] = ModuleName:module_info(),
ModuleName, Functions.

compare_functions_length (_, FunctionsA, _, FunctionsB) ->
length(FunctionsA) >= length(FunctionsB).

extract_amount_of_functions (ModuleName, Functions) ->
ModuleName, length(Functions).


It doesn't really feel elegant to me.







share|improve this question



























    up vote
    3
    down vote

    favorite












    I am trying to solve some exercises from the "Programming Erlang" book.



    One of them is "Write a function to determine which module exports the most functions"



    This is my solution:



    -module(module_info).
    -export([modules_ordered_by_amount_of_functions/0]).

    modules_ordered_by_amount_of_functions() ->
    Modules = loaded_modules_with_functions(),
    SortedModules = lists:sort(fun compare_functions_length/2, Modules),
    lists:map(fun extract_amount_of_functions/1, SortedModules).

    loaded_modules_with_functions() ->
    LoadedModules = code:all_loaded(),
    LoadedModuleNames = lists:map(fun extract_module_name/1, LoadedModules),
    lists:map(fun extract_functions_from_module/1, LoadedModuleNames).

    extract_module_name(ModuleName, _) -> ModuleName.

    extract_functions_from_module(ModuleName) ->
    [_, exports, Functions | _] = ModuleName:module_info(),
    ModuleName, Functions.

    compare_functions_length (_, FunctionsA, _, FunctionsB) ->
    length(FunctionsA) >= length(FunctionsB).

    extract_amount_of_functions (ModuleName, Functions) ->
    ModuleName, length(Functions).


    It doesn't really feel elegant to me.







    share|improve this question























      up vote
      3
      down vote

      favorite









      up vote
      3
      down vote

      favorite











      I am trying to solve some exercises from the "Programming Erlang" book.



      One of them is "Write a function to determine which module exports the most functions"



      This is my solution:



      -module(module_info).
      -export([modules_ordered_by_amount_of_functions/0]).

      modules_ordered_by_amount_of_functions() ->
      Modules = loaded_modules_with_functions(),
      SortedModules = lists:sort(fun compare_functions_length/2, Modules),
      lists:map(fun extract_amount_of_functions/1, SortedModules).

      loaded_modules_with_functions() ->
      LoadedModules = code:all_loaded(),
      LoadedModuleNames = lists:map(fun extract_module_name/1, LoadedModules),
      lists:map(fun extract_functions_from_module/1, LoadedModuleNames).

      extract_module_name(ModuleName, _) -> ModuleName.

      extract_functions_from_module(ModuleName) ->
      [_, exports, Functions | _] = ModuleName:module_info(),
      ModuleName, Functions.

      compare_functions_length (_, FunctionsA, _, FunctionsB) ->
      length(FunctionsA) >= length(FunctionsB).

      extract_amount_of_functions (ModuleName, Functions) ->
      ModuleName, length(Functions).


      It doesn't really feel elegant to me.







      share|improve this question













      I am trying to solve some exercises from the "Programming Erlang" book.



      One of them is "Write a function to determine which module exports the most functions"



      This is my solution:



      -module(module_info).
      -export([modules_ordered_by_amount_of_functions/0]).

      modules_ordered_by_amount_of_functions() ->
      Modules = loaded_modules_with_functions(),
      SortedModules = lists:sort(fun compare_functions_length/2, Modules),
      lists:map(fun extract_amount_of_functions/1, SortedModules).

      loaded_modules_with_functions() ->
      LoadedModules = code:all_loaded(),
      LoadedModuleNames = lists:map(fun extract_module_name/1, LoadedModules),
      lists:map(fun extract_functions_from_module/1, LoadedModuleNames).

      extract_module_name(ModuleName, _) -> ModuleName.

      extract_functions_from_module(ModuleName) ->
      [_, exports, Functions | _] = ModuleName:module_info(),
      ModuleName, Functions.

      compare_functions_length (_, FunctionsA, _, FunctionsB) ->
      length(FunctionsA) >= length(FunctionsB).

      extract_amount_of_functions (ModuleName, Functions) ->
      ModuleName, length(Functions).


      It doesn't really feel elegant to me.









      share|improve this question












      share|improve this question




      share|improve this question








      edited Jun 11 at 19:29









      200_success

      123k14143399




      123k14143399









      asked Jun 4 at 20:01









      Altoyr

      1163




      1163




















          1 Answer
          1






          active

          oldest

          votes

















          up vote
          2
          down vote













          Breaking the problem into tiny, useful functions is a very good way to write Erlang code. So your code is easy to read and gives us a great start in understanding and analyzing it.



          The one thing I notice is that, in loaded_modules_with_functions, you map a function over a list and then map a function on the resulting list. This creates an intermediate list which will just be thrown away (GCed.) I'd combine the two operations so there's only one pass through the list. Since the result of this function is the resulting list, I'd use a list comprehension:



          loaded_modules_with_functions() ->
          [ extract_functions_from_module(ModName) || ModName, _ <- code:all_loaded() ].


          In extract_functions_from_module, you're making an assumption that the export list is always the second element. Maybe this is the case. Or maybe in your OTP release this is always the case. The next release, however, may break your code if module_info adds more information. You can use the proplists module (in the standard library) to generalize the look-up:



          extract_functions_from_module(ModuleName) ->
          ModuleName, proplists:get_value(exports, ModuleName:module_info(), ).


          Finally, I'd put a list comprehension at the end of modules_ordered_by_amount_of_functions and inline extract_amount_of_functions.






          share|improve this answer





















            Your Answer




            StackExchange.ifUsing("editor", function ()
            return StackExchange.using("mathjaxEditing", function ()
            StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix)
            StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
            );
            );
            , "mathjax-editing");

            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: "196"
            ;
            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: false,
            noModals: false,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: null,
            bindNavPrevention: true,
            postfix: "",
            onDemand: true,
            discardSelector: ".discard-answer"
            ,immediatelyShowMarkdownHelp:true
            );



            );








             

            draft saved


            draft discarded


















            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f195839%2forder-loaded-modules-by-amount-of-functions%23new-answer', 'question_page');

            );

            Post as a guest






























            1 Answer
            1






            active

            oldest

            votes








            1 Answer
            1






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes








            up vote
            2
            down vote













            Breaking the problem into tiny, useful functions is a very good way to write Erlang code. So your code is easy to read and gives us a great start in understanding and analyzing it.



            The one thing I notice is that, in loaded_modules_with_functions, you map a function over a list and then map a function on the resulting list. This creates an intermediate list which will just be thrown away (GCed.) I'd combine the two operations so there's only one pass through the list. Since the result of this function is the resulting list, I'd use a list comprehension:



            loaded_modules_with_functions() ->
            [ extract_functions_from_module(ModName) || ModName, _ <- code:all_loaded() ].


            In extract_functions_from_module, you're making an assumption that the export list is always the second element. Maybe this is the case. Or maybe in your OTP release this is always the case. The next release, however, may break your code if module_info adds more information. You can use the proplists module (in the standard library) to generalize the look-up:



            extract_functions_from_module(ModuleName) ->
            ModuleName, proplists:get_value(exports, ModuleName:module_info(), ).


            Finally, I'd put a list comprehension at the end of modules_ordered_by_amount_of_functions and inline extract_amount_of_functions.






            share|improve this answer

























              up vote
              2
              down vote













              Breaking the problem into tiny, useful functions is a very good way to write Erlang code. So your code is easy to read and gives us a great start in understanding and analyzing it.



              The one thing I notice is that, in loaded_modules_with_functions, you map a function over a list and then map a function on the resulting list. This creates an intermediate list which will just be thrown away (GCed.) I'd combine the two operations so there's only one pass through the list. Since the result of this function is the resulting list, I'd use a list comprehension:



              loaded_modules_with_functions() ->
              [ extract_functions_from_module(ModName) || ModName, _ <- code:all_loaded() ].


              In extract_functions_from_module, you're making an assumption that the export list is always the second element. Maybe this is the case. Or maybe in your OTP release this is always the case. The next release, however, may break your code if module_info adds more information. You can use the proplists module (in the standard library) to generalize the look-up:



              extract_functions_from_module(ModuleName) ->
              ModuleName, proplists:get_value(exports, ModuleName:module_info(), ).


              Finally, I'd put a list comprehension at the end of modules_ordered_by_amount_of_functions and inline extract_amount_of_functions.






              share|improve this answer























                up vote
                2
                down vote










                up vote
                2
                down vote









                Breaking the problem into tiny, useful functions is a very good way to write Erlang code. So your code is easy to read and gives us a great start in understanding and analyzing it.



                The one thing I notice is that, in loaded_modules_with_functions, you map a function over a list and then map a function on the resulting list. This creates an intermediate list which will just be thrown away (GCed.) I'd combine the two operations so there's only one pass through the list. Since the result of this function is the resulting list, I'd use a list comprehension:



                loaded_modules_with_functions() ->
                [ extract_functions_from_module(ModName) || ModName, _ <- code:all_loaded() ].


                In extract_functions_from_module, you're making an assumption that the export list is always the second element. Maybe this is the case. Or maybe in your OTP release this is always the case. The next release, however, may break your code if module_info adds more information. You can use the proplists module (in the standard library) to generalize the look-up:



                extract_functions_from_module(ModuleName) ->
                ModuleName, proplists:get_value(exports, ModuleName:module_info(), ).


                Finally, I'd put a list comprehension at the end of modules_ordered_by_amount_of_functions and inline extract_amount_of_functions.






                share|improve this answer













                Breaking the problem into tiny, useful functions is a very good way to write Erlang code. So your code is easy to read and gives us a great start in understanding and analyzing it.



                The one thing I notice is that, in loaded_modules_with_functions, you map a function over a list and then map a function on the resulting list. This creates an intermediate list which will just be thrown away (GCed.) I'd combine the two operations so there's only one pass through the list. Since the result of this function is the resulting list, I'd use a list comprehension:



                loaded_modules_with_functions() ->
                [ extract_functions_from_module(ModName) || ModName, _ <- code:all_loaded() ].


                In extract_functions_from_module, you're making an assumption that the export list is always the second element. Maybe this is the case. Or maybe in your OTP release this is always the case. The next release, however, may break your code if module_info adds more information. You can use the proplists module (in the standard library) to generalize the look-up:



                extract_functions_from_module(ModuleName) ->
                ModuleName, proplists:get_value(exports, ModuleName:module_info(), ).


                Finally, I'd put a list comprehension at the end of modules_ordered_by_amount_of_functions and inline extract_amount_of_functions.







                share|improve this answer













                share|improve this answer



                share|improve this answer











                answered Jun 11 at 17:07









                RichN

                38819




                38819






















                     

                    draft saved


                    draft discarded


























                     


                    draft saved


                    draft discarded














                    StackExchange.ready(
                    function ()
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f195839%2forder-loaded-modules-by-amount-of-functions%23new-answer', 'question_page');

                    );

                    Post as a guest













































































                    Popular posts from this blog

                    Greedy Best First Search implementation in Rust

                    Function to Return a JSON Like Objects Using VBA Collections and Arrays

                    C++11 CLH Lock Implementation