A few weeks ago Spredfast held its once or twice yearly hackweek. The whole engineering department drops everything, self-organizes into small teams, and works on something cool they want to work on. Ideally something company related and NOT on the current roadmap. They cater most of your meals for the week and have extra fun snacks and stuff in the afternoons. Developers from other parts of the country flew to Austin, and we cleared all the conference rooms so folks who weren’t able to travel for a week could video-conference with teammates in Austin any time they wanted.
This time around, I paired up with Otto, one of my teammates on the Visibility project I’ve been working on since last May. We’d been talking about Elixir for a while and we decided to try to re-implement one of our microservices using Elixir and Phoenix. We didn’t talk about it beforehand, but we ended up pairing 100% for the first 3 days.
To sum it up:
- Known problem domain (we’d already solved it with ruby and rails)
- New programming language (elixir)
- New programming paradigm (functional)
- New framework (phoenix)
- New development style (pairing)
It was an awesome experience.
We’d both done a little reading ahead of time, working our way through Programming Elixir on nights and weekends. Neither of us had made it all the way through the book. I’d spent a few hours on a couple weekends using elixir to solve my favorite toy programming problem; Counting word frequency in all the books in my Calibre library. Processing 700+ novels is enough to start showing up the problems with overly naive implementations, and I’d had fun parallelizing the work in different ways.
We weren’t coming into this completely blind, but we weren’t fluent in the language, and aside from a few hours on Sunday afternoon reading Programming Phoenix, neither of us had touched Phoenix at all. The first two days we spent huge amounts of time figuring out how to do very simple things. We might lose an hour on something as simple as converting an Erlang timestamp to a UNIX timestamp.
Worse than learning the language constructs and libraries was shifting from an object oriented mindset to a functional one. I swear I could feel my neurons reconfiguring themselves.
Luckily, by the time the third day (Wednesday) came around, we had learned our way around the libraries we were using enough to be focused more on the actual programming task than on figuring out how to query the database. By the end of the day we’d pretty much re-implemented the core data output process from our microservice. It could read the same database as the ruby version and we could compare query results, which involved transforming irregularly sampled data into neat hourly timeseries. Thursday was spent verifying data and trying to get it to run as fast as the highly optimized ruby version.
Friday was reserved for everyone to show off what they’d done, vote on who’s was the most awesome, and the after party.
Pairing with Otto was both awesome and extremely exhausting. We quickly found a good rhythm of one of us working on something while the other acted as copilot, then trading off when we got to a bit of a stopping point.
He constantly pushed to go faster, and it became obvious that we have very different approaches to things. I like to figure things out, then write code. I think Otto prefers to jump right in and figure things out with hands on keyboard. He kept me from dithering too long, and maybe I helped him some too?
He was also much more into the “go go go” spirit of hackweek than I was. I’d get to work around 8:30, work by myself until he got there around 10:00, and then we’d be hard at it until 5:00 when I’d call it a day. Otto would then shift to working on other projects all evening. I would go home completely exhausted and make non-verbal sounds at my family.
By Wednesday afternoon I was really at the limits of my introversion and was quite grouchy. I think that’s why, by unspoken agreement, we didn’t pair on Thursday. We worked together closely, making coordinated efforts to get things done, but didn’t pair program.
I suspect that if I was to pair regularly long term I’d build up much better endurance.
One side effect of the “drop everything and work on something new” feature of hackweek is that I was able to basically do nothing but program in Elixir for 4–5 days (starting on the weekend before). I didn’t have to switch gears and work on ruby at all until near the end when I needed to run some queries for comparison purposes.
I think this was a big contributor to how quickly I could shift my mindset over to the new language. It’s probably a similar effect to an immersive approach to learning natural languages. I didn’t allow myself to give up and reach for the familiar ruby tools, so if I wanted sample data I was going to have to figure out how to generate it with elixir.
By the end of the week it was feeling really natural, and while I still have a long way to go learning the libraries and the dos and don’t of erlang-style parallelism I think I’ve got a pretty good start on Elixir fluency.
The Language Itself
I love elixir. It has some of the same aesthetic as ruby, with a syntax that seems intentionally designed to be pleasant to look at. It wants you to be more explicit about things than ruby, and phoenix in particular tries to avoid the rails magic. Even with all that explicitness and clarity we still wrote considerably less code than the heavily optimized ruby version. We also managed to get it to run slightly faster.
We didn’t do a lot with phoenix - we never got to implementing web API endpoints, so mainly we were using ecto to read and write to the database. Ecto queries DO start to feel a little like rails magic, though they’re still much more explicit than what Im’ used to in rails.
Eventually we sort of settled on a heuristic that we should always use pattern matching and that any sort of conditional inside a function was bad. This lead to lots and lots of tiny little functions that were easy to test-drive. Ordering of pattern matched versions turned out to be an especially painful source of bugs, especially in cases where there were more than 2–3 options. I’m really curious to see what this means for longer term maintainability.
It was a fun week. I learned one hell of a lot. I’ll be looking for opportunities to replicate the language immersion experience in the future, even if only for 2–3 days. I’ll also be looking for chances to do more with elixir and phoenix.
Hack weeks are usually pretty fun - you shift gears and ramp up the intensity in a way that you can’t most of the time. By the end of the week you’re exhausted and you go back to your normal work with a new perspective. Sometimes the projects turn into big new products and the people who built them get to keep working on them.
Incidentally, Spredfast is hiring if this sounds like a place you’d like to work.