Effect.ts: Absence as First-Class

State ManagementLesson 32 of 51

32. Queue - Coordinating Absent Values

Queue stores values that producers create and consumers await

Code Example
const program = Effect.gen(function* () {
  // Create queue - it's empty (values absent)
  const queue = yield* Queue.bounded<string>(10);

  // Consumer: wait for absent values
  const consumer = Effect.gen(function* () {
    while (true) {
      // Suspends when queue is empty!
      const item = yield* Queue.take(queue);
      yield* Console.log(`Got: ${item}`);
    }
  });

  // Producer: make values available
  const producer = Effect.gen(function* () {
    yield* Queue.offer(queue, "Task 1");
    yield* Effect.sleep("100 millis");
    yield* Queue.offer(queue, "Task 2");
  });

  // Run concurrently
  yield* Effect.fork(consumer);
  yield* producer;
});
Interactive Example
const { Queue } = await import('effect');
const program = Effect.gen(function* () {
      const queue = yield* Queue.bounded(10);
      yield* Queue.offer(queue, 'Task 1');
      yield* Queue.offer(queue, 'Task 2');
      yield* Queue.offer(queue, 'Task 3');
      const item1 = yield* Queue.take(queue);
      const item2 = yield* Queue.take(queue);
      return [item1, item2];
});
const [t1, t2] = await Effect.runPromise(program);
return `Queue!

Offered: Task 1, Task 2, Task 3
Took: ${t1}, ${t2}
Remaining: 1 item

Producer/consumer coordination!`;
Explanation

Queue: coordinating temporal absence between fibers.

Traditional approach: shared arrays with locks (messy!). Queue types producer-consumer absence:

  • Queue starts empty (all values absent)
  • take: suspend until value becomes available
  • offer: make value available to waiters
  • No assumptions about producer/consumer speed
  • Values flow from absent → available → absent again

Absence-first coordination: explicitly managing when values exist!


Part 32 of 51 in the Effect.ts Absence Modeling series