Overview

2 Immutable stacks and queues

This chapter introduces immutable data structures as a practical alternative to mutable ones, arguing that immutability improves correctness, makes past states easy to preserve, reduces security risks such as TOCTOU bugs, and simplifies multithreaded code. It also explains that immutable structures can still be efficient because they are persistent, meaning new versions can share most of their internal structure instead of copying everything. Along the way, the chapter emphasizes a functional-programming mindset while showing that these ideas can be very useful in object-oriented languages too.

The chapter then builds an immutable stack from a linked-list-like design, starting from an abstract data type rather than from the implementation. The stack uses a singleton empty object and a nonempty node type, with operations such as push, peek, pop, and emptiness checks implemented so that no mutation occurs. This design avoids null references, supports covariance by moving push into an extension method, and demonstrates how the stack’s persistent structure lets multiple variables share nodes safely while keeping operations like push, pop, peek, and enumeration efficient.

From there, the chapter develops an immutable queue using two stacks, one for enqueues and one for dequeues, and analyzes both worst-case and amortized performance. It also shows how immutable data structures make undo-redo logic much simpler by wrapping them in a mutable interface that stores previous versions, then extends the idea to the Hughes list, a function-based list representation that makes push, append, and concatenation cheap by deferring work into closures. The Hughes list reveals that the “data” is hidden in captured state inside delegates, and the chapter closes by noting its strengths for building lists incrementally, its expensive access operations, and the tradeoff between delayed work and immediate efficiency.

Each variable in the example code references a particular immutable stack. Stacks with the same tail can refer to the same immutable object.
The example includes six immutable queues and six immutable stacks. Because the data structures are persistent and immutable, objects can be reused across different queues.
 A Hughes list is secretly a binary graph. Delegates created from lambda bodies have automatically created closure classes with fields hl1 and hl2 that refer to the left and right lists being concatenated.

Summary

  • Immutable data structures are easier to reason about and often safer than the equivalent mutable data structure.
  • Persistence makes immutable data structures efficient in space.
  • Immutable data structures can be made time-efficient as well, though there are pitfalls to be wary of when some operations are expensive.
  • Undo-redo operations are straightforward when program state is immutable.
  • The Hughes list shifts the performance costs of seemingly expensive operations by performing them in the optimal order later, but it makes some normally cheap operations, such as Pop, expensive. There’s no free lunch, but costs can be pushed into the future.

FAQ

Why do immutable data structures help correctness?Because facts you deduce about an immutable object stay true forever. Since the object cannot change after you’ve checked it, you avoid bugs caused by stale assumptions becoming invalid later.
How do immutable data structures improve security?They reduce time-of-check/time-of-use problems. If low-trust code cannot mutate an object after validation, it becomes much harder to exploit the gap between checking a value and using it.
Why are immutable objects safer for multithreaded code?Because multiple threads can share the same immutable object without locks. Since no thread can modify it, all threads always see the same contents.
What is persistence in an immutable data structure?Persistence means new versions of a data structure can reuse internal state from old versions. This saves memory because unchanged parts are shared instead of copied.
What operations does the immutable stack interface provide?The immutable stack supports Push, Peek, Pop, and IsEmpty. Push and Pop return new stacks instead of mutating the existing one.
Why is an empty stack implemented as a singleton object?An empty stack is a valid value, so it should be represented by an object rather than null. Making it a singleton also avoids creating multiple equivalent empty stack objects.
How does the immutable queue work using two stacks?It uses one stack for enqueues and one for dequeues. New items are pushed onto the enqueue stack, and when the dequeue stack runs out, the enqueue stack is reversed and used as the new dequeue stack.
What is the amortized cost of dequeue in the immutable queue?Although some dequeues are worst-case O(n) when a reversal is needed, the amortized cost is O(1). Each item is only moved a constant number of times overall.
Why use a mutable wrapper around an immutable data structure?A mutable wrapper gives you a convenient mutable interface while preserving the benefits of immutability internally. It also makes features like undo and redo much simpler to implement.
What is a Hughes list and why is it useful?A Hughes list is a stack-like structure implemented as a delegate that represents list concatenation. It makes Push, Append, and Concatenate cheap, which is useful when building lists from many parts before reading them.

pro $24.99 per month

  • access to all Manning books, MEAPs, liveVideos, liveProjects, and audiobooks!
  • choose one free eBook per month to keep
  • exclusive 50% discount on all purchases
  • renews monthly, pause or cancel renewal anytime

lite $19.99 per month

  • access to all Manning books, including MEAPs!

team

5, 10 or 20 seats+ for your team - learn more


choose your plan

team

monthly
annual
$49.99
$499.99
only $41.67 per month
  • five seats for your team
  • access to all Manning books, MEAPs, liveVideos, liveProjects, and audiobooks!
  • choose another free product every time you renew
  • choose twelve free products per year
  • exclusive 50% discount on all purchases
  • renews monthly, pause or cancel renewal anytime
  • renews annually, pause or cancel renewal anytime
  • Fabulous Adventures in Data Structures and Algorithms ebook for free
choose your plan

team

monthly
annual
$49.99
$499.99
only $41.67 per month
  • five seats for your team
  • access to all Manning books, MEAPs, liveVideos, liveProjects, and audiobooks!
  • choose another free product every time you renew
  • choose twelve free products per year
  • exclusive 50% discount on all purchases
  • renews monthly, pause or cancel renewal anytime
  • renews annually, pause or cancel renewal anytime
  • Fabulous Adventures in Data Structures and Algorithms ebook for free
choose your plan

team

monthly
annual
$49.99
$499.99
only $41.67 per month
  • five seats for your team
  • access to all Manning books, MEAPs, liveVideos, liveProjects, and audiobooks!
  • choose another free product every time you renew
  • choose twelve free products per year
  • exclusive 50% discount on all purchases
  • renews monthly, pause or cancel renewal anytime
  • renews annually, pause or cancel renewal anytime
  • Fabulous Adventures in Data Structures and Algorithms ebook for free