Prev Next

Modeling with Structs in Elixir

Notes

Tasty Sugar

So, in terms of collections, we have lists, maps, tuples, and now keyword lists? Well, kinda. Keyword lists are actually just a tiny dose of syntactic sugar.

For example, here’s the keyword list we passed to the defstruct macro:

[ method: "", path: "", resp_body: "", status: nil ]

Internally, keyword lists are represented as a list of tuples containing two values: an atom (the key) and the associated value. Here’s what that looks like for the keyword list above:

[ {:method, ""}, {:path, ""}, {:resp_body, ""}, {:status, nil} ]

So keyword lists aren’t yet another collection, but rather a tasty mashup of lists and tuples.

Keyword lists are most commonly used as a simple list of options. In contrast, maps are the go-to data structure for storing key/value pairs.

Updating Structs

In the video, we changed the pattern in the route function heads to verify that the argument is a Conv struct. For example:

def route(%Conv{ method: "GET", path: "/wildthings" } = conv) do
  %{ conv | status: 200, resp_body: "Bears, Lions, Tigers" }
end

We didn’t need to change the expression in the function body because the syntax for updating a struct is just like updating a map.

However, we could have changed the update syntax to stipulate a Conv struct, like so:

%Conv{ conv | status: 200, resp_body: "Bears, Lions, Tigers" }

The difference is this verifies that the value being updated (conv) is indeed a struct of the type Conv, not a generic map. In this particular case, the extra check doesn’t gain us anything since the pattern in the function head requires the argument to be a Conv type. But sometimes it’s worth adding that extra type safety check.

To see what happens if we try to update a plain map, try this in an iex session:

iex> map = %{method: "GET", path: "/wildthings"}
 
%Servy.Conv{ map | status: 200, resp_body: "Bears, Lions, Tigers" }
** (BadStructError) expected a struct named Servy.Conv, got: %{method: "GET", path: "/wildthings"}

This is yet another compile-time check that comes with using a struct as compared to a map.

Code So Far

The code for this section is in the structs directory found within the video-code directory of the code bundle

Prev Next