Introducing Modules and Functions

You cannot view this unit as you're not logged in yet. Go to Account to login.

6 Comments

  1. Rodrigo Lessa on November 15, 2020 at 7:23 am

    Hey at the end you say you don’t recommend naming modules like this. What would be your recommended way for setting up that module structure?

    • Mark Ericksen on November 15, 2020 at 7:44 am

      Good question! While using an “alias” with :as works, I think it’s simpler and clearer if the module is just named in a way that doesn’t need an :as. Imagine code in different modules using a different alias as and you have to go to the extra effort of looking it up to see if it’s the same one.

      In this example, I think it’s better to just name the module:

      alias MyApp.Customers.Orders.OrderProcessor

  2. Chad Henson on February 19, 2021 at 9:41 am

    It seems like the “alias” feature might be ripe for a decent naming strategy. I could imagine where the namespace represents a functional area of concern and not necessarily just a safeguard against two “same-named” (and arity) functions that do different things. So your function could be called OrderProcessor or you like you mentioned maybe you have a namespace called `MyApp.Orders.Purchasing` and one called `MyApp.Orders.Sales`. One namespace would encompass order processing from the perspective of sales orders and the other would encompass order processing from the perspective of purchase orders. So orders placed to you…versus placed by you. That seems like a reasonable use of aliasing code modules as a means to organize code across functional domains.

  3. Larry Rix on October 27, 2022 at 11:33 am

    It turns out that literally everything in Elixir is a function—that includes modules. You can prove this to yourself by writing:

    defmodule (MyFoo) do

    def (foo) do
    “Hello!”
    end

    end

    Whatever is being used to parse the code is searching for function patterns. One clue is the “do … end” construct, where that is generally preceded by a function name (e.g. “defmodule” or “def” or “defp”) plus a list of argument(s). That there is but a single argument is beside the primary point. In the case above both “MyFoo” and “foo” are arguments being sent in to the defmodule and def functions.

    Note that I added the parenthesis for clarity. Such code does actually compile. For me—know this fact of “everything is a function” has made conditional inclusion of parenthesis make sense (otherwise, I was struggling to understand when and when not to include them).

  4. Larry Rix on October 27, 2022 at 11:48 am

    There is a Principle in Computer Science called Single-entry/Single-exit (SESE) and another school of thought (SEME) Single-entry/Multiple-exit.

    The idea is that exit conditions ought never to break the flow to the end of the function routine, but ought to literally point the way to the end of the routine. Adding to this notion that every Elixir function returns something (even if just nil) is a related matter that has consequences based on either SESE or SEME.

    Over the years, I have grown to enforce SESE even when the language does not enforce it. It helps me to reason about the routine in an expected way. It is another reason to write terse function code rather than verbose. Terse, short functions with a single exit and a forced return or result data item means that you can more easily reason about what the function is doing and why.

    Couple this with functions passing over data rather than data being thrown at functions (as a paradigm) is powerful.

    • Mark Ericksen on October 28, 2022 at 3:46 pm

      I agree! A single exit point is much preferred when reading code. I’ve read large functions in Ruby written by others with many early exists spread throughout the function body. It makes it much harder to reason about.

Leave a Comment

You must be logged in to post a comment.