Installing Erlang 17 for Elixir 0.13 the easy way (Mac)

As of Elixir 0.13, you’ll need to have Erlang 17 installed.  If you use brew to install erlang then elixir you’ll find this message awaiting you:

ERROR: OTP release R16B03-1 does not match required regex (17).*

The current Erlang brew formula is still at R16B03-1.  BUT! the development version IS 17.  So here you go:

brew install --devel erlang

I’m sure this will change soon, but until then this’ll get you going again.

Elixir needs at least 4 JSON parsers

Elixir has, at the time of this post, 3 JSON parsers hosted on expm.

Some time back I went looking for one and started exploring elixir-json, including the github repo.  I loved how the encoder used protocols to implement the encoding of different types.  It’s beautiful.  Kudos to @carloslage.

Then I looked at the decoder.  It’s full of elixir-isms… tuples, binary pattern matching, etc.  Over the last few nights I decided to implement my own JSON parser learning from Carlos were I ran aground.

I don’t like the use of HashDict for objects, but spaces rule out most options like Keyword lists.  I’m also not a huge fan of the nested case for dealing with the what’s next? of key/value pairs.

def parse_object( acc, << rest :: binary >> ) do
  { key, rest } = parse_content rest
  { value, rest } = lstrip(rest) |> parse_object_value 

  acc = [ { key, value } | acc ] 

  case lstrip(rest) do
    << ?}, rest :: binary >> -> {, rest }
    << ?,, rest :: binary >> -> parse_object acc, lstrip(rest)

Overall it feels very cohesive.  You can see clearly how the pieces compose after being dispatched from the parse_content.

def parse_content( << m, rest :: binary >> ) when m in ?0..?9, do: parse_number << m, rest :: binary >>
def parse_content( << ?", rest :: binary >> ), do: rest |> parse_string
def parse_content( << ?{, rest :: binary >> ), do: lstrip(rest) |> parse_object
def parse_content( << ?[, rest :: binary >> ), do: lstrip(rest) |> parse_array

I also do nothing to support invalid JSON content as with elixir-json.  Oh well, it was a learning tool.

Using HashDict.update for Keyed Reductions (aka group by) in Elixir

I wanted to start playing with Elixir’s Map and Reduce functions to get a better feel for collection transformations in the language.  For this I grabbed some movie data here and planned on grabbing some perspectives.

First problem, we need to turn the data into a list of tuples.  The pseudo-transformation we want to apply:

file -> lines
lines -> parts
parts -> tuples

The results ended up looking like this

[gist id=”6051117″ file=”movies.exs”]

For our data perspectives, lets start small.  The number of movies per year.  This is still a transformation, but it’s not going to be a one-for-one.  We’re instead going to reduce the results after mapping.  Why would we map?  Turns out the only thing you need to know is a full list of the movie years… with dups.  With that we can do an “Add or Update” to a hash for each year.

[gist id=”6051117″ file=”uniqueness.exs”]

What we’re doing is providing an entry point for count_unique which takes a collection.  This creates a new HashDict which seeds our {year, count} and then recursively calls down into a variant of HashDict.update.  This variant will insert a new key if not found with the 3rd parameter being the seed value.  If the key is found HashDict.update will call our anonymous function to increment the value already found.

This pattern seems to work well to get the sum also.  Here we map our collection to pull the year and rating.  I adjusted my original to_movies to use String.to_float so that I have a numeric rating.  From there I use the same HashDict pattern with the rating being our seed and accumulator.

[gist id=”6051117″ file=”sumations.exs”]

Next we’ll look at doing something a little more interesting by calculating an average and distributing the effort across nodes using our previous parallel map.

Triangle Kata in Elixir using Erlang processes for Parallel Maps

Last time I described my setup for learning Elixir, the language built on top of Erlang with a Ruby bent.  Today I wanted to get a hang of processes and mailboxes which are so important to both languages.  To do this I chose the Triangle Kata as my background story.  Take a look:

Update: You might wonder what that slow function is all about. I added that in there to clarify the parallelism. You would expect the slowest classifications to appears at the end of the resultant list.