Nice to see the data confirm the general consensus (by my measure, at least) regarding the Clojure STM options.

Like others, I've been telling Clojure newbies something like: When you need Clojure STM, default to using an atom unless you really know you need to use something else.

Ok, newbie here!

In Haskell I can add a handful of lines to parallelize an "embarrassingly parallel" computation. For example, there are 66,960,965,307 atomic lattices on 6 atoms. A 20 core Mac Studio can figure this out by reverse search in just over four minutes; divvy the work up into piles, and have everyone count the work in their pile. For the problems I care about, everyone's looking for needles in a haystack; they can report what they found with no concern for what anyone else is doing.

So what's the dumbest "try this first" approach in Clojure?

Within the standard library, `clojure.core/pmap` is good for simple problems[0], whereas the various functions in the clojure.core.reducers[1] namespace are a bit more sophisticated and would probably solve the sort of problem you're describing pretty well. There are also a number of good clojure parallelism libraries floating around if you don't mind incurring dependencies: I've used claypoole[2] and tesser[3] in the past and been pretty happy with them.

All of these options are, IME, relatively easy to drop in to some extant data processing pipeline to parallelize it, and probably require a similar level of finagling to what you're used to in Haskell.

[0] (->> some-lazy-seq (pmap ...) (reduce ...)) goes pretty far, but nesting/composing pmaps or doing i/o doesn't always work particularly well since the JVM [currently] uses OS threads rather than something like the lightweight threads GHC provides.

[1] https://clojure.org/reference/reducers

[2] https://github.com/clj-commons/claypoole

[3] https://github.com/aphyr/tesser