DEV Community

Nick Bauman
Nick Bauman

Posted on

1 1

From loop recur to reduce

In Clojure, do you find yourself reaching for a loop recur but you know you should be using reduce? Here's a really simple way to break out of that habit.

Let's start with and example. Starting with a2d which is the result of invoking (to-array-2d [[11 2 4] [4 5 6] [10 8 -12]]) and len is the size of the matrix. Which is 3.

This function, written with a loop/recur, calculates the "diagonal sum" of the values of a square matrix of some size.

(defn accu [a2d len]
 (reduce +
  (loop [vals []
         i    (- len 1)]
   (if (> len (count vals))
    (recur (conj vals (aget a2d i i)) (dec i))
    vals))))
Enter fullscreen mode Exit fullscreen mode

So invoking this function:

(accu (to-array-2d [[11 2 4] [4 5 6] [10 8 -12]]) 3)
=> 4
Enter fullscreen mode Exit fullscreen mode

Returns 4 because 11 + 5 + -12 = 4

So what does the reduce version look like?

(defn accu [a2d len]
 (reduce +
  (reduce #(conj %1 (aget a2d %2 %2)) [] (reverse (range len)))))
Enter fullscreen mode Exit fullscreen mode

Notice how the relevant code is almost exactly the same. Both use (conj vals (aget a2d i i)) (dec i) to solve the problem. The loop/recur version has much more housekeeping and is not as fast as the reduce version.

Sentry image

Hands-on debugging session: instrument, monitor, and fix

Join Lazar for a hands-on session where you’ll build it, break it, debug it, and fix it. You’ll set up Sentry, track errors, use Session Replay and Tracing, and leverage some good ol’ AI to find and fix issues fast.

RSVP here →

Top comments (0)

Sentry image

See why 4M developers consider Sentry, “not bad.”

Fixing code doesn’t have to be the worst part of your day. Learn how Sentry can help.

Learn more

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay