++ Operator Performance Gotcha

While going through the [Programming Elixir][1] book by Dave Thomas, one of the exercises was to implement Enum.split ([see the docs here][2]):

Enum.split(list, count) => { count_elems_from_front, remaining_elems }

My first attempt looked like this:

def split([], _), do: {[], []}
def split(list, 0), do: { [], list }
def split([head | tail], count) do
  _split(tail, count - 1, [head])
end

defp _split([], _, front) do
  { front, [] }
end
defp _split(back, 0, front) do
  { front, back }
end
defp _split([head | ...

Dates, date formatting, and parsing

There is no direct Elixir support for dates, though there is the Erlang calendar module. Dates, Times, and Date Times are represented as tuples

  • {2014, 2,10} - 10 Feb 2014
  • {16,45,15} - 16:45:15
  • {{2014,2,10}, {16,45,15}} - 10 Feb 2014, at 16:45:15

There are a number of in-progress date parsing and formatting libraries, eg:

Env-specific deps

I found myself in the situation where I wanted to have a dependency only compiled in my dev env. You can do this as follows: -

  def project do
    [ app: :my_proj,
      version: "0.0.1",
      elixir: "~> 0.12.3",
      env: [
        dev:  [deps: dev_deps],
        test: [deps: deps],
        prod: [deps: deps]
      ]
    ]
  end

  defp deps do
    []
  end

  defp dev_deps do
    [
      { :ex_doc, github: "elixir-lang/ex_doc" }
    ] ++ deps
  end

If anyone knows of a cleaner way to share common deps, please to share. :)

Heroku compile issue (Elixir Buildpaack) ** (Mix) Expected :version to be a SemVer version

I was having issues with getting a dynamo project compiling on Heroku using the Elixir buildpack and marcelog/jsonex:

could not compile dependency jsonex, mix compile failed. You can recompile this dependency with `mix deps.c>
** (Mix) Expected :version to be a SemVer version

The issue was in the Jsonex mix.exs: the project version was "2.0". Forking and [changing the version to "2.0.0"
](https://github.com/paulanthony...

Dependencies for the test environment

When I updated to Elixir 0.12.3, I found the dependency behaviour changed for the test environment. Running

mix deps.get

Gets dependencies for production(?), so I'm able to compile with

mix

However

mix test

Fails with Unchecked dependencies for environment test:.

Get test dependencies with

MIX_ENV=test mix deps.get

UndefinedFunctionError using EEx with an escript

Although EEx is bundled with the Elixir distribution it is not part of the Elixir core.

$ ls -1 /usr/local/Cellar/elixir/0.12.2/lib/
eex
elixir       # <- Elixir core stuff is here
ex_unit
iex
mix

When you run mix escriptize it bundles your project beam files, plus any project dependencies and the Elixir core beam files (from under lib/elixir), but none of the other libraries bundled in the Elixir distribution. So if your project uses EEx the resulting escript will fail reporting an undefined function for anything from EE...

Examining Escriptized Binaries

The escript binaries output by mix escriptize are actually made up of 3 lines of ascii text (the escript shell script bit) followed by a big blob of zip data that contains your project’s beam files.
If you want to see what beam files have been bundled into your escript do the following:

Generate your escript:

$ mix escriptise
# Creates my_escript

Exact the zip data:

$ tail -n +4 my_escript > my_escript.zip

Now list the contents of the zip to see the included beam files:

$ unzip -l my_escript.zip
Arch...