Matching Heads and Tails



Here's the raw POST request we pasted in the video:

request = """
POST /bears HTTP/1.1
User-Agent: ExampleBrowser/1.0
Accept: */*
Content-Type: application/x-www-form-urlencoded
Content-Length: 21


response = Servy.Handler.handle(request)

IO.puts response

And here's the starting point we used for the matching route function:

def route(%Conv{method: "POST", path: "/bears"} = conv) do
  %{ conv | status: 201, resp_body: "Create a bear!" }

Linking Heads and Tails

The familiar way to make a list is by separating each element by a comma:

iex> nums = [1, 2, 3]
[1, 2, 3]

But now you know that a list is either empty or it consists of a head and a tail which is itself a list. It follows then that you can create the same list using the [head | tail] expression:

iex> nums = [1 | [2, 3]]
[1, 2, 3]

In the same way, you can add elements to the head of a list (prepend) using the [head | tail] expression:

iex> [0 | nums]
[0, 1, 2, 3]

And if you wanted to take the long way around the barn, you could create the list of numbers 0-3 as a series of heads and tails like so:

iex> [0 | [1 | [2 | [3 | []]]]]
[0, 1, 2, 3]

Doesn't that make you appreciate the comma-separated syntax all the more? The point is that a list in Elixir is implemented as a series of linked lists. The head is always the first element of the list. The tail "points" or "links" to the list that consists of the head and tail of the remaining elements. So lists are by definition recursive data structures!

Accessing Head and Tail with Functions

The head and tail of a list can also be accessed with the functions hd and tl:

iex> nums = [1, 2, 3]

iex> hd(nums)

iex> tl(nums)
[2, 3]

The hd and tl functions are defined in the Kernel module which is automatically imported into every module so you don't have to prefix the function with the module name.

Code So Far

The code for this video is in the post-requests directory found within the video-code directory of the code bundle.