Effect.ts: Absence as First-Class

State ManagementLesson 36 of 51

36. Ref + Effect - Concurrent State

Multiple fibers updating the same absent state safely

Code Example
const program = Effect.gen(function* () {
  const counter = yield* Ref.make(0);

  // 10 fibers all incrementing concurrently
  const increment = Ref.update(counter, n => n + 1);

  yield* Effect.all(
    Array(10).fill(increment),
    { concurrency: "unbounded" }
  );

  const final = yield* Ref.get(counter);
  // final = 10 (guaranteed!)

  // No race conditions!
  // Each fiber safely resolves the state absence.
});

// Compare to: let counter = 0; counter++ (UNSAFE!)
Interactive Example
const { Ref } = await import('effect');
const program = Effect.gen(function* () {
      const counter = yield* Ref.make(0);
      const increment = Ref.update(counter, n => n + 1);




      // Create array of 10 increments
      const increments = Array.from({ length: 10 }, () => increment);




      yield* Effect.all(increments, { concurrency: 'unbounded' });
      return yield* Ref.get(counter);
});
const final = await Effect.runPromise(program);
return `Concurrent Ref!

10 fibers incrementing
Final value: ${final}

No race conditions!`;
Explanation

Ref + concurrency: safely resolving shared state absence.

Traditional approach: shared variables, race conditions, chaos. Ref types concurrent state updates as safe absence:

  • State is absent to all fibers
  • Each update describes transformation
  • No assumptions about execution order
  • Atomic operations ensure consistency
  • Ref.update serializes the absence resolution

Absence-first concurrency: state updates are concurrent absence transformations!


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