Browse Clojure Foundations for Java Developers

Handling Side Effects in Concurrent Programs

Keep I/O out of swap!/dosync and push effects to explicit edges and queues.

The easiest way to break concurrency code is to mix state coordination and side effects in the same place.

Two practical rules keep you safe:

  1. Never do side effects inside swap! functions or STM transactions. They may be retried.
  2. Push effects to the edges: run I/O in a boundary layer, then pass results into pure functions.

For Java engineers, this is the same separation of concerns you already value—just enforced at a smaller granularity: “calculate vs do.”

This section focuses on patterns for containing effects (queues, channels, agents, boundary namespaces) so the rest of your code stays deterministic and testable.

In this section

Revised on Friday, April 24, 2026