Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Clojure: Idiomatic way to recur with values based on conditionals

Tags:

clojure

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?

like image 839
David Williams Avatar asked Dec 26 '22 04:12

David Williams


1 Answers

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))
like image 155
DanLebrero Avatar answered May 12 '23 12:05

DanLebrero