David Williams
David Williams

Reputation: 8654

Clojure: Idiomatic way to recur with values based on conditionals

Since recur can only be used in tail position, how do I recur with a value that depends on nested conditionals? Here is an example:

(loop [a (rand-int) b 0]
    (if (< a 300)
       (recur (rand-int) 1))
    (if (a < 10000)
       (recur (rand-int) 5))
    b)

The problem is the recurs do not happen in tail position. So how do I loop with a new value that depends upon an internal conditional. I could make a reference and swap it in the conditionals, then recur in tail position, but is there a way to do it without value mutation?

Upvotes: 4

Views: 95

Answers (1)

DanLebrero
DanLebrero

Reputation: 8593

The recurs can all be in tail position:

(loop [a (rand-int 20000) b 0]
    (if (< a 300)
       (recur (rand-int 20000) 1)
       (if (< a 10000)
         (recur (rand-int 20000) 5)
         b)))

Or perhaps a little bit more readable:

(loop [a (rand-int 20000) b 0]
  (cond 
    (< a 300)   (recur (rand-int 20000) 1)
    (< a 10000) (recur (rand-int 20000) 5)
    :default    b))

Upvotes: 10

Related Questions