In an attempt to learn more about Clojure's parallel computation functions, I devised the following task: calculate a factorial in parallel using
The idea is to split the factorial sequence into sub-computations, reducing the final output of each.
Here is the obvious non-parallel function:
(defn factorial [n] (reduce * (range 1 (inc n))
pmap is fairly straight-forward:
(defn pmap-factorial [n psz] (let [parts (partition-all psz (range 1 (inc n)))] (reduce * (pmap #(apply * %) parts))))
However, with pvalues I had to resort to macros that return a computation function.
(defmacro pvalues-factorial [n psz] (let [exprs (for [p (partition-all psz (range 1 (inc n)))] (cons '* p))] `(fn  (reduce * (pvalues ~@exprs)))))
Similar approach with pcalls:
(defmacro pcalls-factorial [n psz] (let [exprs (for [p (partition-all psz (range 1 (inc n)))] `(fn  (* ~@p)))] `(fn  (reduce * (pcalls ~@exprs)))))
So, I had to use macros for
pvalues. Does not seem ideal, but it was the only way I could accomplish the above (and perhaps indicates that
pmaps is the best practice for this use case).
1) How could the code be made more correct / idiomatic?
2) Did I have to resort to macros for pvalues and pcalls, or have I overlooked another way of accomplishing my goal with these functions?