Project Euler Problem 14 in Clojure
CAVEAT I am not a clojure programmer. (But hopefully you will agree with what I suggest ;))

Put all your code in functions such that all top level forms are defs. Similarly put your tests in deftest forms and run them with run-tests. 

In clojure, too, extract meaningful expressions to their own functions and give them names.
Then promote baked in magic constants in them to parameters so that they are more testable, in REPL and elswhere.

You can use destructuring let to give meaningful names to a function returning a vector.

Applying these general rules

(defn longest-chain [limit]
  (loop [number 1 peak-len 0 peak-val 0]
    (if (&gt;= number limit)
      peak-val
      (do (let [[curr-len curr-val] (count-collatz number)]
        (do (if (&gt; curr-len peak-len)
          (recur (inc number) curr-len curr-val)
          (recur (inc number) peak-len peak-val))))))))))

(defn -main []
  (println "Longest chain is" (longest-chain 1e6)))


Here is how you can rewrite these functions using core library.


(= x 0) is (zero? x)
(zero? (mod num 2)) is (even? x)
repeatedly applying a function without explicit loop/recur is iterate.
You can use for comprehension of a range instead of loop/recur with incing a parameter.
You can also use core library functions that operate on sequences (map, reduce et al) for a more functional style.
You can use threading macros to reduce nesting levels as necessary; and to make your functions read top-down instead of more counter-intuitive inside-out.
You can use (apply max-key k coll) to get "the [value] for which (k x), a number, is greatest."


Code after above changes:

(defn count-collatz [n]
  (let [f (fn [n] (if (even? n) (/ n 2) (+ (* n 3) 1)))]
   (-&gt;&gt; n
     (iterate f)
     (take-while #(&gt; % 1))
     count
     inc)))

(defn longest-chain [limit]
    (-&gt;&gt; limit
      (range 1)
      (map #(vector (count-collatz %) %))
      (apply max-key first)
      second)


Or using the fact that max-key can get arbitrary function as its first parameter, we get:

(defn longest-chain [limit]
  (apply max-key count-collatz (range 1 limit)))