How to make a recursive function local to the let body - recursion

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:
(letfn [(power [base exp]
(cond
(= exp 0)
1
(> exp 0) ; Exponent greater than 0
(* base (power base (dec exp)))
:else ; Exponent less than 0
(/ (power base (inc exp)) base)))]
(print (power -2 3)))
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.

letfn is the best solution for your particular case. However, you can also created a named "anonymous" function like so:
(let [power (fn power [base exp] ...)]
(println (power -2 3)))
However, this style doesn't allow for mutually recursive functions, which letfn does.

Besides to good answer of Michel: Using high order function on lazy sequences often allow consise solutions compared to explicit recursion:
(defn power [base exp]
(reduce * (repeat exp base)))

Here is a solution which is an example of Michiel's last statement about using an accumulator. This lets you use recur to gain advantage of tail call optimization. This gives you the advantage of not consuming stack space with each recursion.
(defn pow [base exp]
(letfn [(power [base exp accum]
(cond
(= exp 0) accum
(> exp 0) (recur base (dec exp) (* accum base))
:else (recur base (inc exp) (/ accum base))))]
(power base exp 1)))
user> (pow -3 2)
9
user> (pow -3 3)
-27
If you are simply looking to write a function which does raises a base number to a power don't forget you can call out to methods which already exist in Java. java.util.Math can help you out here.
(Math/pow -2 3)

Related

Clojure java.lang.Long cannot be cast to clojure.lang.IFn error

I trying to write simple factorial function in clojure, but i am getting this error:
java.lang.Long cannot be cast to clojure.lang.IFn
I know this error is usually due to an extra parenthesis, but I am not sure about this case.
First I wrote function in LISP, and it works as it should.
Code:
(defun factorial (n)
(if (= n 1)
1
(* (factorial (1- n)) n )
)
)
(factorial 5)
Then I tried it in clojure, where it doesn't work.
Clojure code:
(defn factorial [n]
(if (= n 1)
1
(* (factorial(n)) n)
)
)
(defn -main
[& args]
(println(factorial 5))
)
You've got an extra set of parens in your recursive call to factorial, probably because you meant to decrement n, it should be
(defn factorial [n]
(if (= n 1)
1
(* (factorial (dec n)) n) ;; <==
)
)
As MarkNFI showed decrementing has its own operator inc.
But to show you the problem in your code:
(defun factorial (n)
(if (= n 1)
1
(* (factorial (1- n)) n ) ;; (1- n) must be changed to (dec n) or (- n 1)
)
)
(factorial 5)
(1- n) is not the way operators in clojure work. You have to place the operator first. So in your case it would be: (- n 1)

Comparing two types of delayed computation

I have an assignment in which i need to explain the impact on the memory using two types of delayed computation. The code solves the hanoi problem.
Type 1:
(define count-4 (lambda (n) (count-4-helper n (lambda (x) x)))
(define count-4-helper (lambda (n cont)
(if (= n 1)
(cont 1)
(count-4-helper (- n 1) (lambda(res) (cont (+ 1 (* 2 res))))))))
Type 2:
(define count-5 (lambda (n) (count-5-helper n (lambda () 1)))
(define count-5-helper (lambda (n cont)
(if (= n 1)
(cont)
(count-5-helper (- n 1) (lambda() (+ 1 (* 2 (cont))))))))
The first case is the classic syntax of delayed computation. The second case is the same only it doesn't get any arguments and just returns the initial value.
The question is which one of those function is tail-recursive?(i think both them are). And how different is their memory consumption? The second should be more effective but i can't really explain.
Thanks for your time.
The answer is in these two lambdas:
(lambda (res) (cont (+ 1 (* 2 res))))
(lambda () (+ 1 (* 2 (cont))))
In one of them but not the other, cont is called in tail position with respect to the lambda.

In Clojure, is it possible to combine memoization and tail call optimization?

In clojure, I would like to write a tail-recursive function that memoizes its intermediate results for subsequent calls.
[EDIT: this question has been rewritten using gcd as an example instead of factorial.]
The memoized gcd (greatest common divisor) could be implemented like this:
(def gcd (memoize (fn [a b]
(if (zero? b)
a
(recur b (mod a b))))
In this implementation, intermediate results are not memoized for subsequent calls. For example, in order to calculate gcd(9,6), gcd(6,3) is called as an intermediate result. However, gcd(6,3) is not stored in the cache of the memoized function because the recursion point of recur is the anonymous function that is not memoized.
Therefore, if after having called gcd(9,6), we call gcd(6,3) we won't benefit from the memoization.
The only solution I can think about will be to use mundane recursion (explicitely call gcd instead of recur) but then we will not benefit from Tail Call Optimization.
Bottom Line
Is there a way to achieve both:
Tail call optimization
Memoization of intermediate results for subsequent calls
Remarks
This question is similar to Combine memoization and tail-recursion. But all the answers there are related to F#. Here, I am looking for an answer in clojure.
This question has been left as an exercise for the reader by The Joy of Clojure (chap 12.4). You can consult the relevant page of the book at http://bit.ly/HkQrio.
in your case it's hard to show memoize do anything with factorial because the intermediate calls are unique, so I'll rewrite a somewhat contrived example assuming the point is to explore ways to avoid blowing the stack:
(defn stack-popper [n i]
(if (< i n) (* i (stack-popper n (inc i))) 1))
which can then get something out of a memoize:
(def stack-popper
(memoize (fn [n i] (if (< i n) (* i (stack-popper n (inc i))) 1))))
the general approaches to not blowing the stack are:
use tail calls
(def stack-popper
(memoize (fn [n acc] (if (> n 1) (recur (dec n) (* acc (dec n))) acc))))
use trampolines
(def stack-popper
(memoize (fn [n acc]
(if (> n 1) #(stack-popper (dec n) (* acc (dec n))) acc))))
(trampoline (stack-popper 4 1))
use a lazy sequence
(reduce * (range 1 4))
None of these work all the time, though I have yet to hit a case where none of them work. I almost always go for the lazy ones first because I find them to be most clojure like, then I head for tail calling with recur or tramplines
(defmacro memofn
[name args & body]
`(let [cache# (atom {})]
(fn ~name [& args#]
(let [update-cache!# (fn update-cache!# [state# args#]
(if-not (contains? state# args#)
(assoc state# args#
(delay
(let [~args args#]
~#body)))
state#))]
(let [state# (swap! cache# update-cache!# args#)]
(-> state# (get args#) deref))))))
This will allow a recursive definition of a memoized function, which also caches intermediate results. Usage:
(def fib (memofn fib [n]
(case n
1 1
0 1
(+ (fib (dec n)) (fib (- n 2))))))
(def gcd
(let [cache (atom {})]
(fn [a b]
#(or (#cache [a b])
(let [p (promise)]
(deliver p
(loop [a a b b]
(if-let [p2 (#cache [a b])]
#p2
(do
(swap! cache assoc [a b] p)
(if (zero? b)
a
(recur b (mod a b))))))))))))
There is some concurrency issues (double evaluation, the same problem as with memoize, but worse because of the promises) which may be fixed using #kotarak's advice.
Turning the above code into a macro is left as an exercise to the reader. (Fogus's note was imo tongue-in-cheek.)
Turning this into a macro is really a simple exercise in macrology, please remark that the body (the 3 last lines) remain unchanged.
Using Clojure's recur you can write factorial using an accumulator that has no stack growth, and just memoize it:
(defn fact
([n]
(fact n 1))
([n acc]
(if (= 1 n)
acc
(recur (dec n)
(* n acc)))))
This is factorial function implemented with anonymous recursion with tail call and memoization of intermediate results. The memoization is integrated with the function and a reference to shared buffer (implemented using Atom reference type) is passed by a lexical closure.
Since the factorial function operates on natural numbers and the arguments for succesive results are incremental, Vector seems more tailored data structure to store buffered results.
Instead of passing the result of a previous computation as an argument (accumulator) we're getting it from the buffer.
(def ! ; global variable referring to a function
(let [m (atom [1 1 2 6 24])] ; buffer of results
(fn [n] ; factorial function definition
(let [m-count (count #m)] ; number of results in a buffer
(if (< n m-count) ; do we have buffered result for n?
(nth #m n) ; · yes: return it
(loop [cur m-count] ; · no: compute it recursively
(let [r (*' (nth #m (dec cur)) cur)] ; new result
(swap! m assoc cur r) ; store the result
(if (= n cur) ; termination condition:
r ; · base case
(recur (inc cur)))))))))) ; · recursive case
(time (do (! 8000) nil)) ; => "Elapsed time: 154.280516 msecs"
(time (do (! 8001) nil)) ; => "Elapsed time: 0.100222 msecs"
(time (do (! 7999) nil)) ; => "Elapsed time: 0.090444 msecs"
(time (do (! 7999) nil)) ; => "Elapsed time: 0.055873 msecs"

Clojure Tail Recursion with Prime Factors

I'm trying to teach myself clojure and I'm using the principles of Prime Factors Kata and TDD to do so.
Via a series of Midje tests like this:
(fact (primefactors 1) => (list))
(fact (primefactors 2) => (list 2))
(fact (primefactors 3) => (list 3))
(fact (primefactors 4) => (list 2 2))
I was able to create the following function:
(defn primefactors
([n] (primefactors n 2))
([n candidate]
(cond (<= n 1) (list)
(= 0 (rem n candidate)) (conj (primefactors (/ n candidate)) candidate)
:else (primefactors n (inc candidate))
)
)
)
This works great until I throw the following edge case test at it:
(fact (primefactors 1000001) => (list 101 9901))
I end up with a stack overflow error. I know I need to turn this into a proper recur loops but all the examples I see seem to be too simplistic and only point to a counter or numerical variable as the focus. How do I make this recursive?
Thanks!
Here's a tail recursive implementation of the primefactors procedure, it should work without throwing a stack overflow error:
(defn primefactors
([n]
(primefactors n 2 '()))
([n candidate acc]
(cond (<= n 1) (reverse acc)
(zero? (rem n candidate)) (recur (/ n candidate) candidate (cons candidate acc))
:else (recur n (inc candidate) acc))))
The trick is using an accumulator parameter for storing the result. Notice that the reverse call at the end of the recursion is optional, as long as you don't care if the factors get listed in the reverse order they were found.
Your second recursive call already is in the tail positions, you can just replace it with recur.
(primefactors n (inc candidate))
becomes
(recur n (inc candidate))
Any function overload opens an implicit loop block, so you don't need to insert that manually. This should already improve the stack situation somewhat, as this branch will be more commonly taken.
The first recursion
(primefactors (/ n candidate))
isn't in the tail position as its result is passed to conj. To put it in the tail position, you'll need to collect the prime factors in an additional accumulator argument onto which you conj the result from the current recursion level and then pass to recur on each invocation. You'll need to adjust your termination condition to return that accumulator.
The typical way is to include an accumulator as one of the function arguments. Add a 3-arity version to your function definition:
(defn primefactors
([n] (primefactors n 2 '()))
([n candidate acc]
...)
Then modify the (conj ...) form to call (recur ...) and pass (conj acc candidate) as the third argument. Make sure you pass in three arguments to recur, i.e. (recur (/ n candidate) 2 (conj acc candidate)), so that you're calling the 3-arity version of primefactors.
And the (<= n 1) case need to return acc rather than an empty list.
I can go into more detail if you can't figure the solution out for yourself, but I thought I should give you a chance to try to work it out first.
This function really shouldn't be tail-recursive: it should build a lazy sequence instead. After all, wouldn't it be nice to know that 4611686018427387902 is non-prime (it's divisible by two), without having to crunch the numbers and find that its other prime factor is 2305843009213693951?
(defn prime-factors
([n] (prime-factors n 2))
([n candidate]
(cond (<= n 1) ()
(zero? (rem n candidate)) (cons candidate (lazy-seq (prime-factors (/ n candidate)
candidate)))
:else (recur n (inc candidate)))))
The above is a fairly unimaginative translation of the algorithm you posted; of course better algorithms exist, but this gets you correctness and laziness, and fixes the stack overflow.
A tail recursive, accumulator-free, lazy-sequence solution:
(defn prime-factors [n]
(letfn [(step [n div]
(when (< 1 n)
(let [q (quot n div)]
(cond
(< q div) (cons n nil)
(zero? (rem n div)) (cons div (lazy-step q div))
:else (recur n (inc div))))))
(lazy-step [n div]
(lazy-seq
(step n div)))]
(lazy-step n 2)))
Recursive calls embedded in lazy-seq are not evaluated before iteration upon the sequence, eliminating the risks of stack-overflow without resorting to an accumulator.

a recursive Fibonacci function in Clojure

I'm a newcomer to clojure who wanted to see what all the fuss is about. Figuring the best way to get a feel for it is to write some simple code, I thought I'd start with a Fibonacci function.
My first effort was:
(defn fib [x, n]
(if (< (count x) n)
(fib (conj x (+ (last x) (nth x (- (count x) 2)))) n)
x))
To use this I need to seed x with [0 1] when calling the function. My question is, without wrapping it in a separate function, is it possible to write a single function that only takes the number of elements to return?
Doing some reading around led me to some better ways of achieving the same funcionality:
(defn fib2 [n]
(loop [ x [0 1]]
(if (< (count x) n)
(recur (conj x (+ (last x) (nth x (- (count x) 2)))))
x)))
and
(defn fib3 [n]
(take n
(map first (iterate (fn [[a b]] [b (+ a b)]) [0 1]))))
Anyway, more for the sake of the exercise than anything else, can anyone help me with a better version of a purely recursive Fibonacci function? Or perhaps share a better/different function?
To answer you first question:
(defn fib
([n]
(fib [0 1] n))
([x, n]
(if (< (count x) n)
(fib (conj x (+ (last x) (nth x (- (count x) 2)))) n)
x)))
This type of function definition is called multi-arity function definition. You can learn more about it here: http://clojure.org/functional_programming
As for a better Fib function, I think your fib3 function is quite awesome and shows off a lot of functional programming concepts.
This is fast and cool:
(def fib (lazy-cat [0 1] (map + fib (rest fib))))
from:
http://squirrel.pl/blog/2010/07/26/corecursion-in-clojure/
In Clojure it's actually advisable to avoid recursion and instead use the loop and recur special forms. This turns what looks like a recursive process into an iterative one, avoiding stack overflows and improving performance.
Here's an example of how you'd implement a Fibonacci sequence with this technique:
(defn fib [n]
(loop [fib-nums [0 1]]
(if (>= (count fib-nums) n)
(subvec fib-nums 0 n)
(let [[n1 n2] (reverse fib-nums)]
(recur (conj fib-nums (+ n1 n2)))))))
The loop construct takes a series of bindings, which provide initial values, and one or more body forms. In any of these body forms, a call to recur will cause the loop to be called recursively with the provided arguments.
You can use the thrush operator to clean up #3 a bit (depending on who you ask; some people love this style, some hate it; I'm just pointing out it's an option):
(defn fib [n]
(->> [0 1]
(iterate (fn [[a b]] [b (+ a b)]))
(map first)
(take n)))
That said, I'd probably extract the (take n) and just have the fib function be a lazy infinite sequence.
(def fib
(->> [0 1]
(iterate (fn [[a b]] [b (+ a b)]))
(map first)))
;;usage
(take 10 fib)
;;output (0 1 1 2 3 5 8 13 21 34)
(nth fib 9)
;; output 34
A good recursive definition is:
(def fib
(memoize
(fn [x]
(if (< x 2) 1
(+ (fib (dec (dec x))) (fib (dec x)))))))
This will return a specific term. Expanding this to return first n terms is trivial:
(take n (map fib (iterate inc 0)))
Here is the shortest recursive function I've come up with for computing the nth Fibonacci number:
(defn fib-nth [n] (if (< n 2)
n
(+ (fib-nth (- n 1)) (fib-nth (- n 2)))))
However, the solution with loop/recursion should be faster for all but the first few values of 'n' since Clojure does tail-end optimization on loop/recur.
this is my approach
(defn fibonacci-seq [n]
(cond
(= n 0) 0
(= n 1) 1
:else (+ (fibonacci-seq (- n 1)) (fibonacci-seq (- n 2)))
)
)
For latecomers. Accepted answer is a slightly complicated expression of this:
(defn fib
([n]
(fib [0 1] n))
([x, n]
(if (< (count x) n)
(recur (conj x (apply + (take-last 2 x))) n)
x)))
For what it's worth, lo these years hence, here's my solution to 4Closure Problem #26: Fibonacci Sequence
(fn [x]
(loop [i '(1 1)]
(if (= x (count i))
(reverse i)
(recur
(conj i (apply + (take 2 i)))))))
I don't, by any means, think this is the optimal or most idiomatic approach. The whole reason I'm going through the exercises at 4Clojure ... and mulling over code examples from Rosetta Code is to learn clojure.
Incidentally I'm well aware that the Fibonacci sequence formally includes 0 ... that this example should loop [i '(1 0)] ... but that wouldn't match their spec. nor pass their unit tests despite how they've labelled this exercise. It is written as an anonymous recursive function in order to conform to the requirements for the 4Clojure exercises ... where you have to "fill in the blank" within a given expression. (I'm finding the whole notion of anonymous recursion to be a bit of a mind bender; I get that the (loop ... (recur ... special form is constrained to tail-recursion ... but it's still a weird syntax to me).
I'll take #[Arthur Ulfeldt]'s comment, regarding fib3 in the original posting, under consideration as well. I've only used Clojure's iterate once, so far.

Resources