A couple months ago, I started a new R&D project at work. The best part? I get to use Elixir for something that might go to production!

One of my favorite things about the language is ability to directly call Erlang/OTP modules (which makes sense; Elixir code compiles to Erlang code). There are lots of really useful modules, written by people way smarter than I over the past few decades. Sometimes, however, they don’t always fit the bill.

Case in point: I needed a FIFO queue for my project, so my first instinct was to grab the Erlang Queue module. It’s simple and works well, but it had a couple of shortcomings that made it a challenge for me:

  • It didn’t integrate into Elixir libraries very well. A common idiom in Elixir is to compose functions as a pipeline transformation. The language even has a pipe operator |> to encourage this pattern. Most Erlang modules don’t follow this pattern, so there are a lot of extra assignments and lines of code that are often written to join the two

  • A couple of functions I used a lot were too slow, especially the size operator. Erlang’s Queue doesn’t track the size of the queue as a deliberate design decision, so it needs to iterate the list in order to get the size, and this operation becomes expensive when the size of the list becomes large, as I have in my project.

So instead, I wrote Yaq. Yaq (Yet Another Queue) uses two linked-lists to implement a double-ended queue. It’s not a complicated problem; in fact, I use it as a quick screening question when I interview potential candidates (FizzBuzz is a bit played out). What I added to the problem helps me in a big way, though:

  • It implements the Enumerable and Collectible protocols in Elixir, so it naturally works with a lot of other Elixir libraries.

  • It is written with the pipe operator in mind, so it fits in well with the many Elixir programming idioms.

  • It tracks references internally, so getting the number of elements is a constant-time operation. Very important when using Enumerable. This is a linear-time operation in Queue, so I think this is an improvement, especially when working with potentially hundreds of thousands of records.

In reality, a big part of my motivation was to get the actual experience of publishing an open-source library. I’ve been writing code in some fashion for over 30 years, but I’ve never been a “social” coder, so putting something out into the world for open critique was an untried experience. There was positive response generally from the community, so I feel like I did do something right.

If no one ever uses the library in their code, I’m not going to lose any sleep. I wrote Yaq to help me, and I thought it might help others, too.