liveBook · Manning

Reduced?

As explained in Clojure: The Essential Reference

reduced? is a Clojure predicate that tests whether a value is a Reduced object.

`reduced?` tests whether its argument is a `clojure.lang.Reduced` marker object. It returns `true` for a wrapped value and `false` for a plain value. The marker signals that a reduction should stop early; testing for it does not itself stop the reduction. section 7.3

Test a wrapped value

(def r (reduced "string")) (reduced? r) ; true (reduced? "string") ; false @r ; "string" The wrapped value supports dereferencing, so `@r` retrieves the string rather than the marker. section 7.3

`reduce` and `reduce-kv` understand the early-stop signal. A custom reduction implementation must check a reducing function's result with `reduced?`, return the unwrapped result when it is reduced, and otherwise continue. Without that check, it may keep processing or pass a marker where an ordinary accumulator is expected. section 7.3 section 11.3.4

(extend-protocol clojure.core.protocols/IKVReduce
  java.util.Map
  (kv-reduce [m f init]
    (let [iter (.. m entrySet iterator)]
      (loop [ret init]
        (if (.hasNext iter)
          (let [^java.util.Map$Entry kv (.next iter)
                ret (f ret (.getKey kv) (.getValue kv))]
            (if (reduced? ret) ; #1
              @ret
              (recur ret)))
          ret)))))

(reduce-kv
  (fn [m k v]
    (if (= k :abort)
      (reduced m)
      (assoc m k v)))
  {}
  (LinkedHashMap. {:a 1 :abort true :c 3}))

;; {:a 1} ; #2

The Java-map `reduce-kv` extension checks `(reduced? ret)` after each step, returns `@ret` on an early stop, and recurs only for an ordinary accumulator. section 11.3.4

Use `reduced` to create a marker, `reduced?` to recognize one, `ensure-reduced` to avoid wrapping an existing marker again, and `unreduced` to obtain its value when wrapped. section 7.3

How Clojure: The Essential Reference covers it

How deep it goes
Defines the Boolean contract and demonstrates checking, dereferencing, and handling a marked result in a reduction loop.
Examples
Shows a wrapped string, a moving-average reduction, and a Java-map `reduce-kv` extension that checks before recurring.
What it assumes
Assumes familiarity with Clojure reduction and dereferencing while defining what a Reduced marker means.
What you can do after
Apply it via Clojure's `reduce-kv` extension protocol to recognize an early-stop result and return its unwrapped value.
How it connects
Connects `reduced`, `ensure-reduced`, `unreduced`, `reduce`, `reduce-kv`, reducers, and transducers through the early-stop convention.

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Clojure: The Essential Reference. The section links point to the parts of the book it draws on.