Immutable queue in Clojure
Data Structures & Algorithms practice on Codemia
Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.
Introduction
Clojure, a dialect of the Lisp programming language, is renowned for its emphasis on immutability and functional programming principles. One of its powerful data structures is the immutable queue. In this article, we'll explore the concept of an immutable queue, its implementation in Clojure, and how it contrasts with mutable queues found in other programming languages. Through technical explanations and examples, you'll get a hands-on understanding of how immutable queues operate and how they can be beneficial in a functional programming paradigm.
Understanding Immutable Queues
The concept of immutability in Clojure means that once a data structure is created, it cannot be changed. Instead of mutating the structure, operations on it produce a new structure, preserving the original. This is a core principle of functional programming, offering benefits such as easier reasoning about code, enhanced concurrency, and avoidance of unforeseen side-effects.
How Immutable Queues Work
An immutable queue in Clojure is realized as a sequence of elements that follows the first-in-first-out (FIFO) order. When you enqueue (add) or dequeue (remove) elements, a new queue representation is returned with the desired changes.
Implementation in Clojure
Clojure provides the `clojure.lang.PersistentQueue` for immutable queue operations, which can be interfaced using the standard Clojure sequence functions.
Here's an example of creating and using an immutable queue in Clojure:
- Creating a Queue: We start by defining a queue using `PersistentQueue/EMPTY` and use `conj` to add elements.
- Enqueuing: To enqueue, you use `conj`, which adds an element to the queue, returning a new queue.
- Dequeuing: You use `peek` to retrieve the first element and `pop` to remove it, both returning new structures.
- Integration with Core.async: Immutable queues can be used with channels in core.async for managing states and communication in concurrent programming.
- Data Transformation: They can be combined with other Clojure functions like `map`, `filter`, and `reduce` for transforming queued data.
Related reading
- ImmutableSortedDictionary range enumeration by key
- Implement a queue in which push_rear, pop_front and get_min are all constant time operations
- implement Broadcast Tree on OMNET++
- Implement Stack using Two Queues
- Implementation of a hits in last second/minute/hour data structure
- Implementation of delayed queue for PHP AMQP
- Implementation of distributed greedy algorithm for finding maximum independent set
- Implementations of image matching using Scalable Recognition with a Vocabulary Tree

DSA Fundamentals
Master algorithmic patterns and data structures through hands-on LeetCode-style problems - from arrays and hashing to dynamic programming and advanced graphs.
View the courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
Data Structures & Algorithms practice on Codemia
Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.