I’m trying to make a function in Clojure that is local to the body of a (let …) function. I tried the following, but (defn …) defines things in the global namespace.
(let [] (defn power [base exp]
(if (= exp 0)
1
(if (> exp 0)
; Exponent greater than 0
(* base (power base (- exp 1)))
; Exponent less than 0
(/ (power base (+ exp 1)) base))))
(println (power -2 3)))
; Function call outside of let body
(println (power -2 3))
Now, I also tried:
(let [power (fn [base exp]
(if (= exp 0)
1
(if (> exp 0)
; Exponent greater than 0
(* base (power base (- exp 1)))
; Exponent less than 0
(/ (power base (+ exp 1)) base))))]
(println (power -2 3)))
; Function call outside of let body
(println (power -2 3))
But then I get the error:
Exception in thread "main" java.lang.Exception: Unable to resolve symbol: power in this context (math.clj:6)
How do I make a function whose namespace is local to the let body and can recursively call itself?
For this you can use
letfn:Note that I also changed your nested if-construction to cond, I think it is more readable. Also I changed (+ exp 1) and (- exp 1) to (inc exp) and (dec exp) respectively. You can even improve your function more like using recur and an accumulator argument, but maybe that goes beyond the scope of your question. Also see Brian Carper’s comment below.