Modeling With Structs


Tasty Sugar

OK, so in terms of collections we have lists, maps, tuples, and now keyword lists? Well, kinda. Keywords 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" }          

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 video is in the structs directory found within the video-code directory of the code bundle.