← Lessons

quiz vs the machine

Silver1100

Concurrency

Lazy Evaluation and Concurrency

Compute only when forced, and force it at most once.

4 min read · intro · beat Silver to climb

Deferring work

Lazy evaluation delays a computation until its result is actually needed. A value starts as an unevaluated thunk and turns into a concrete result only when something forces it.

Where concurrency meets laziness

If two threads force the same thunk at the same time, you have a hidden shared mutable cell. Two risks appear:

  • Duplicate work if both threads evaluate the thunk independently.
  • A torn update if one thread reads the cell while another is writing it.

A safe lazy value uses a small atomic transition: the first thread that forces it computes the result, and the rest block briefly and then read the cached answer.

Streams from thunks

Laziness lets you build infinite structures, like a stream of natural numbers, because only the parts you touch are ever computed. Combined with immutability, a lazy stream is safe to share across consumers.

The danger

Pure laziness is safe, but a thunk that performs a side effect when forced makes timing observable, which breaks the illusion that order does not matter.

Key idea

Lazy values defer work until forced; under concurrency they must force exactly once and cache the result.

Check yourself

Answer to earn rating on the learn ladder.

1. What is the risk when two threads force the same thunk?

2. Why does laziness allow infinite structures?