3 minutes
On Yaq
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 inQueue
, 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.