Continually experimenting with new ideas and techniques — Reconstructing, Developing, Modernising.
“The sound of surprise” was a used by Whitney Balliet, a jazz reviewer, to describe the magical nature of improvisation. I expect that’s where the title of a Bill Bruford’s Earthworks album came from, but before I discovered that the phrase had been used by a jazz reviewer my internal explanation of it as an album title was in reference to laughter — that moment when the switch in framing in a joke or a situation surprises you and makes you laugh. My initial “non-trivial” foray into Elixir was full of pleasant surprises, times when I had my eyes opened a bit. The high points for me were:
I wanted to try a couple of bits of tooling out while I developed this small program to get a sense of how the tools worked in practice. The tools were credo (a static source analysis tool, think rubocop for Elixir), and dialyxir (allows the Dialyzer static analysis tool to be run on the BEAM byte code generated by Elixir). I wanted to use these because I find rubocop has helped me improve my ruby coding style, and as applications become bigger I think some kind of typing becomes more useful. Both of these should help me be a better Elixir programmer.
The first thing I did to refresh my Elixir knowledge was to set up my editor with the latest vim-elixir package and run through some Elixir koans. I was pretty happy with how I was doing when suddenly my ruby-ish assumptions were surprisingly thrown into relief:
Assertion failed in lib/koans/04_lists.ex:49
List.insert_at([1, 2, 3], 10, 4) == [1, 2, 3, nil, nil, nil, nil, nil, nil, nil, 10]
Coming from perl-land via ruby-land I expected the intermediate list elements to be magically generated. In Elixir that’s not the way it happens! Whenever I stumbled I was pleasantly surprised how easy to navigate and understand Elixir’s on-line documentation is.
The story’s best told by looking at the Github repository which charts my progress from getting a simple escript to say “Hello World” and my explorations as I dug around looking for other people’s bits of code to duplicate the Perl 6 builtins so I could concentrate on writing the puzzle brute-force solver.
My naïve style means that the Elixir code probably isn’t as concise as it could be, however it seems pretty readable to me.
mix does a great job of starting and building the project. Admittedly this is a small project, but mix compiles only the modules whose source has changed, and the compilation time of a small module is small. My change/test/react cycle seemed as fast as when developing ruby.
I discovered that I could put |> IO.inspect anywhere in the pipeline to check that the data resembled my expectations. It returns its argument, so it doesn’t materially affect the processing.
I like having tools like credo and dialyxir to help guide me. I find it much easier to keep things clean as I go along rather than fix things up later. I’ll confess that I still have a lot to learn about success typing, but mix dialyzer did help me a couple of times even on a project as small as this.
I was surprised that making the Square module for the square seemed to slow things down as much as it did (wall clock time went from about 0.9 seconds to about 1.6 seconds).
I found the doctests in conjunction with more traditional tests were helpful to me because I could write examples of the code I was about to write, and that guided some thoughts on the interface. It also encouraged writing the “happy path” tests where Elixir’s documentation tools could pick them up too.
I liked mix escript which generated a script which I should be able to copy onto any machine with Erlang installed and be able to run it.
I was amazed by the speed. When I ran the perl 6 program using rakudo-star from homebrew it took a little over 3 minutes of wall clock time to run on my Mac, the escript took about 1.6 seconds of wall clock time. I wasn’t expecting that large a difference.
$ perl6 -v
This is Rakudo version 2016.04 built on MoarVM version 2016.04
implementing Perl 6.c.
$ elixir -v
Erlang/OTP 18 [erts-7.3] [source] [64-bit] [smp:8:8] [async-threads:10] [hipe] [kernel-poll:false] [dtrace]
I have a lot to learn, I find Elixir to be engaging and intriguing. A surprisingly pragmatic functional language.