惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

大猫的无限游戏
大猫的无限游戏
Webroot Blog
Webroot Blog
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
T
Threat Research - Cisco Blogs
V2EX - 技术
V2EX - 技术
L
LINUX DO - 热门话题
Google DeepMind News
Google DeepMind News
Recorded Future
Recorded Future
S
Schneier on Security
I
InfoQ
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
The GitHub Blog
The GitHub Blog
S
Security @ Cisco Blogs
O
OpenAI News
W
WeLiveSecurity
Vercel News
Vercel News
阮一峰的网络日志
阮一峰的网络日志
Simon Willison's Weblog
Simon Willison's Weblog
人人都是产品经理
人人都是产品经理
Cloudbric
Cloudbric
The Last Watchdog
The Last Watchdog
The Hacker News
The Hacker News
Google Online Security Blog
Google Online Security Blog
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
GbyAI
GbyAI
NISL@THU
NISL@THU
T
Tailwind CSS Blog
V
Visual Studio Blog
PCI Perspectives
PCI Perspectives
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
Jina AI
Jina AI
D
DataBreaches.Net
B
Blog RSS Feed
N
News and Events Feed by Topic
N
News and Events Feed by Topic
H
Heimdal Security Blog
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
腾讯CDC
Latest news
Latest news
V
Vulnerabilities – Threatpost
Hacker News: Ask HN
Hacker News: Ask HN
WordPress大学
WordPress大学
V
V2EX
aimingoo的专栏
aimingoo的专栏
博客园 - 司徒正美
Apple Machine Learning Research
Apple Machine Learning Research
D
Darknet – Hacking Tools, Hacker News & Cyber Security
The Register - Security
The Register - Security
Help Net Security
Help Net Security

jola.dev

Elixir Cluster 101 | jola.dev How to stop Claude from saying load-bearing | jola.dev Let libraries be libraries | jola.dev CI workflows on Tangled for Elixir | jola.dev Automatically syncing your blog to atproto and standard.site | jola.dev Appreciation for the small web | jola.dev Treating LLMs as programming books Publishing your blog to standard.site in Elixir Generating OG images in Elixir The social contract of writing Highest Random Weight in Elixir bunnyx: a bunny.net Elixir client library Building for the joy of building Running local models on an M4 with 24GB memory How to hit your Claude weekly limit so you can go outside and touch grass Dropping Cloudflare for bunny.net Building a blog with Elixir and Phoenix Stay in the Loop: How I Actually Use Claude Code Ruthless Prioritization: The Path to Delivery Estimates Are More Valuable Than You Think When Software Engineers Think They Need More Focus Time If the Goal is Resiliency, Defensive Programming is Your Enemy The Magic of Daily Pull Requests: Why Smaller is Better Building a Distributed Rate Limiter in Elixir with HashRing Announcing Hex Diff Building Hex Diff Push-based GenStage Patterns for managing ETS tables Health checks for Plug and Phoenix The new `Registry.select/2` and what match specs are Elixir String Processing Optimization
The Erlang :queue module in Elixir
Johanna Larsson · 2019-10-18 · via jola.dev

Elixir doesn’t provide its own data structures, instead, it uses the ones provided by Erlang. Many of them are wrapped by Elixir modules and have shorthand syntax, to make them easier to work with. You’ve seen [], {}, and %{}, and the modules List, Tuple, and Map. Elixir also exposes “structs”, which are maps with special behaviors associated with them. Some structs are treated as opaque, like MapSet, with its own set of functions to interact with it. But Erlang has a few more data types that, because they’re not wrapped in Elixir, you might not have been introduced to yet. This article is about the one I’ve had the most use of, :queue.

Erlang queues are similar to lists but double-ended, meaning you can efficiently insert items to both the front and the rear of it. It is also known as a “first in first out”, or FIFO, data structure. The Erlang documentation describes it:

Queues are double-ended. The mental picture of a queue is a line of people (items) waiting for their turn. The queue front is the end with the item that has waited the longest. The queue rear is the end an item enters when it starts to wait. If instead using the mental picture of a list, the front is called head and the rear is called tail.

A common use case is where you want to temporarily store items and eventually take them back out in the order that you put them in. I use this pattern as the buffer in Push-based GenStage.

Using them can feel a bit awkward, partly because Erlang orders arguments differently than Elixir, and partly because the internal representation of queues is exposed. Note that the docs clearly state that you should treat it as an opaque type.

Here’s some examples of how to use it

iex(38)> q = :queue.new()

{[], []}

iex(33)> q = :queue.in("a", q)

{["a"], []}

iex(34)> q = :queue.in("b", q)

{["b"], ["a"]}

iex(35)> q = :queue.in("c", q)

{["c", "b"], ["a"]}

When getting items back out you need to keep track of both the item and the queue.

iex(36)> {{:value, value3}, q} = :queue.out(q)

{{:value, "a"}, {["c"], ["b"]}}

iex(37)> {{:value, value2}, q} = :queue.out(q)

{{:value, "b"}, {[], ["c"]}}

iex(37)> {{:value, value3}, q} = :queue.out(q)

{{:value, "c"}, {[], []}}

If the queue is empty you get the :empty atom instead.

iex(39)> :queue.out(q)

{:empty, {[], []}}

One thing to note about queues is that they don’t keep track of their length themselves, so :queue.len/1 has to traverse the entirety of the queue. If you’re working with very large queues and frequently need to check the size, consider keeping track of it separately, or creating your own wrapped queue module.

Check out the documentation for more information and functions.

Written by Johanna Larsson. Thoughts on this post? Find me on Bluesky at @jola.dev or why not give it a vote on Bubbles.