How to do recursion in anonymous fn, without tail recursion

Sonia Hamilton picture Sonia Hamilton · May 8, 2012 · Viewed 7.2k times · Source

How do I do recursion in an anonymous function, without using tail recursion?

For example (from Vanderhart 2010, p 38):

(defn power
  [number exponent]
  (if (zero? exponent)
    1
    (* number (power number (- exponent 1)))))

Let's say I wanted to do this as an anonymous function. And for some reason I didn't want to use tail recursion. How would I do it? For example:

( (fn [number exponent] ......))))) 5 3)
125

Can I use loop for this, or can loop only be used with recur?

Answer

Jeremy picture Jeremy · May 8, 2012

The fn special form gives you the option to provide a name that can be used internally for recursion.

(doc fn)
;=> (fn name? [params*] exprs*)

So, add "power" as the name to complete your example.

(fn power [n e]
  (if (zero? e)
    1
    (* n (power n (dec e)))))

Even if the recursion happened in the tail position, it will not be optimized to replace the current stack frame. Clojure enforces you to be explicit about it with loop/recur and trampoline.