Raybench - Elixir (PLC pt.10)

As it's wikipedia entry states, Elixir is a functional, concurrent and general purpose programming language that runs on top of the Erlang virtual machine.

Appearing around 4 years ago, it has gained popularity very quickly and has amassed recognition as a very capable alternative to the traditional Erlang language; some people even calling it one of the most productive programming languages.

Erlang syntax is similar to other ML based languages, and embraces the functional paradigm very well.

The code used here was based mainly on the OCaml implementation.

Results

Elixir version 1.2.4 was used for running the tests.

Parse and loading time

How fast does the interpreter loads and parses the code.

$ time elixir elixirrb.exs
elixirrb.exs:13: warning: function vdiv/2 is unused

real    0m1.504s  
user    0m1.372s  
sys    0m0.096s  

Loading and parsing time is slow compared to other compilers and interpreters, nonetheless the slowdown is not very noticeable; although it might be on larger codebases.

Running Time

$ time elixir elixirrb.exs
elixirrb.exs:13: warning: function vdiv/2 is unused

real    123m59.025s  
user    118m2.504s  
sys     4m16.504s  

Running time is an order of magnitude slower compared to mono and python (running over pypy). Definitely not good.

Code Metrics

Line count: 123 code, 16 blank, 138 total.
File size: 5332 bytes.

The implementation spans 123 lines of code and 5332 bytes total, placing it around 500 bytes above the OCaml implementation size.

General Thoughts

I have mixed feelings about this language, and to try being a little bit more concise, I'll post some thoughts in two parts.

The Good

  • The language enforces the definition of modules to structure your program, this gives you a better sense of clarity.

  • Encapsulation can be achieved using private functions inside modules.

  • Structs, when instantiated, are automatically initialized with default values.

  • Alerts you of unused functions/objects when compiling/executing. Which no other language so far has done, although some warn on unused variables. See warnings on the output of the parse/running times.

  • Gives you warnings on possible ambiguity.

  • Tips you on best practices.

The Bad

  • Anonymous functions can't be recursive. You have to resort to passing around a pointer to itself or make it a fully fledged function.

  • Calling normal functions and anonymous functions has different syntax.

While the good parts seem to offset the bad ones, working with the language gave me a felling of dealing with a half finished product. Having different syntax to calling regular and anonymous functions is confusing, at least for beginners; and also not being able to recurse on anonymous functions is quite a let down.

For anonymous functions I refer to this:

samples = fn (x,y) ->  
  Enum.map(1..@samples, ...

As opposed to this:

defp writeppm(data) do  
  {:ok, ppm} = ...

Al around the language seems promising, it's syntax is expressive but the runtime needs more work.

On a later article I'll talk about how easy/difficult it was to get this program to run concurrently on multiple cores.

Follow

You can follow the development of this project on GitHub: https://github.com/niofis/raybench