Six months with Elixir
September 11, 2016
Back in January I sat down and had a play with Elixir. By the end of February I'd decided this could be the one. I've waxed and waned on that, as one does with a new language, but it's just a little longer than six months now and here I am, all in. This is why.
Functional programming, and for me that means separating out the data (AKA the state) and the functions that work on that state, functional programming is… and it pains me to say this more than I can say… as it turns out it… feels right to me. I am eating humble pie on this one. I have fought against it for so long, often for very good reasons: functional programmers sometimes can't help themselves make programming as obscure as possible, and while coding isn't for everyone it shouldn't ever be for the chosen few. That aside, here they have a point. On this they were right; I was wrong.
The functional part of Elixir allows testing with certainty, the same set of inputs are always going to give you the same set of outputs, and it allows parallel code without a bunch of locks and checks and guesswork.
Other modern languages – Go, Rust, pretty much all of them except for Swift – make it more or less easy to spin up parallel processes, but only Elixir (and the Erlang OTP framework it uses to do this) can spin those processes up, and if something goes wrong with one of them, the others are going to chug along untouched. That cannot be emphasized enough.
You can spin up a million and one shopping carts on your site, and if one of them dies for some reason the other million carts won't even blink. No other languages can do that.
Elixir can do it because it's built on top of Erlang, and the thing everyone always notices/says is that Elixir adds Ruby-style syntax to Erlang. It's deeper than that though, some other things Elixir gets from Ruby, apart from a bunch of its programmers, is a respect for testing & for elegant code.
Beauty's in the eye of the beholder, but code that's easier to read (and to write) is easier to maintain. And any way, pattern matching in Elixir is drop dead gorgeous.
Once describes were added to group tests in ExUnit in Elixir 1.3, and once I finally grocked module attributes as a replacement for a mocking library, I think it may have everything I want in a testing framework. The Elixir community's nowhere near as big and the tool-belt's nowhere near as large, yet, but both are growing steadily and both make up for a lack of quantity with their quality. In terms of tooling: Credo for example is a very good opinionated linter & exCoveralls produces some very pretty coverage output. Both recent finds for me, and both best of breed.
I'd been burnt by monkey patching in Ruby, so was worried early on that Elixir macros might work the same way. But they don't. Macros are opt-in in a module and they're expanded at compile time, so you don't get any nasty surprises because somebody upstream thought it'd be a great idea to change how integers work.
There have been some pain points. Part of the pain's been self inflicted. Elixir wants to stay running, it wants to be a bullet-proof long running thing. So naturally I started building command line tools with it… yeah, the fit's ok, but there are things like date/time libraries not working in binaries (escripts)… that I can forgive, it's on the very edge of the project. Sometimes the pain's caused by a distinct lack of online examples. The docs are very good, but sometimes you need to work things out rather than Googling them - which is fun too, right. (You do like programming, right? Ha.)
That works for big things & small - last night I was trying to test a function call in a genserver, I was starting it up, and missing the error completely because it was getting messaged off to the calling process… when I suddenly hit on the much simpler solution of just calling the function. A genserver's just a module, a function's just a function. That kind of thing seems obvious in retrospect (and probably is obvious to everyone else), but it can take a bit of confidence, and that takes time.
I had an epiphany watching a presentation online last night too, I was coming up with better answers to questions than the presenter was. That was a pleasing lightbulb moment - hey, I can do this stuff now. I know this stuff now.