Atoms manage independent, synchronous state changes. If you’re coming from Java, an atom is closest to an AtomicReference<T> with a functional update operation.
Use an atom when:
- the state is owned by one “thing” (a cache, stats counter, in-memory registry)
- updates don’t need to coordinate with other pieces of state
- you want atomicity without locks
Create and Read
1(def counter (atom 0))
2
3@counter ; deref => 0
4(deref counter) ; same as @
Update: reset! and swap!
1(reset! counter 100) ; set a new value
2(swap! counter inc) ; apply a function to the current value
3(swap! counter + 5) ; functions can take extra args
Important: swap! Functions Should Be Pure
Under contention, swap! may retry the update function. If you do side effects inside it (logging, DB calls, HTTP), you can accidentally repeat them.
Compare-and-Set
1(compare-and-set! counter 105 0) ; => true/false
Knowledge Check: Atoms
### Why should the function passed to `swap!` avoid side effects?
- [x] Because it may be retried under contention, which could repeat the side effect.
- [ ] Because atoms only work at compile time.
- [ ] Because `swap!` runs actions on a separate thread.
- [ ] Because atoms can’t hold maps or vectors.
> **Explanation:** `swap!` uses CAS semantics. Under contention, the update function may be invoked multiple times before one update wins.
### What does `@counter` do?
- [x] Dereferences the atom to obtain its current value.
- [ ] Resets the atom to `nil`.
- [ ] Increments the atom.
- [ ] Creates a new atom.
> **Explanation:** `@x` is shorthand for `(deref x)`. It works for atoms, refs, agents, futures, delays, and promises.
### What’s the difference between `reset!` and `swap!`?
- [x] `reset!` sets an explicit value; `swap!` computes a new value from the old via a function.
- [ ] `swap!` is read-only, but `reset!` mutates.
- [ ] `reset!` is asynchronous, but `swap!` is synchronous.
- [ ] They are synonyms.
> **Explanation:** `swap!` is the common “update based on current value” operation. `reset!` replaces the value directly.