Effect.ts: Absence as First-Class
State Management • Lesson 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