Introducing the Struct

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


  1. Larry Rix on October 28, 2022 at 6:39 am

    For me—this really warrants a larger discussion (but not here). While the error message makes an emphatic imperative declaration about the syntax and grammar of the “defstruct” construct, such choices ought never be seen as though they are the only ones available—that is—Elixir could have been designed differently. Some immediate questions are: First, why not more than one struct per module? Second, why not use Defstruct instead of Defmodule? Third, why not use the “do … end” construct with “defstruct”?

    In the end—all language design choices have consequences—some good and some bad. Those choices can either help productivity or hurt it. One way to hurt programmer productivity is to create language constructs, syntaxes and grammars that hide bugs and help the programmer produce them. This leads to downstream issues with readability, maintainability, and overall software quality for the entire lifecycle of the software system.

    As a new Elixir/Phoenix programmer, such questions are fresh in my mind and seeing this error causes me to ask a lot of “why?” questions. 🙂

    iex(11)> recompile
    Compiling 1 file (.ex)

    == Compilation error in file lib/junk.ex ==
    ** (ArgumentError) defstruct has already been called for Junk, defstruct can only be called once per module

  2. Larry Rix on October 28, 2022 at 7:28 am

    Little things that are bothersome:

    1 def player_stuff do
    2 frank = %Junk{username: “Frank”, email: “”}
    3 Map.get(frank, :username, “no-name”)
    4 end

    The user of “username:” in line 2 and then the same reference in line 3 as “:username”.

    From a language design point of view, there is no reason that the parser/compiler cannot use “:username” as an atom. I know, I know, I know—you just have to “get used to thinking that way” in Elixir. But—the truth is this—the choices of the language designer are what force the programmer to “get used to it”.

    Am I being critical (perhaps unduly so)? Yes—I am. Does that mean I do not “like” Elixir? Not at all. It is a tool and a powerful one at that. Pattern matching is an outstanding invention and I wish many languages had it inherently in the syntax and grammar of its constructs.

    All in all—I am VERY thankful for this course material. It is outstandingly helpful!

    • Mark Ericksen on October 31, 2022 at 8:04 am

      You do have the option of writing it this way if you find it helpful:

      def player_stuff do
        frank = %Junk{username: “Frank”, email: “”}
        frank.username || “no-name”

      However, if the map doesn’t contain an atom key named :username then it will result in a runtime error. But when working with a struct that defines the field, it will always be present.

Leave a Comment

You must be logged in to post a comment.