Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the difference between the Clojure function (nth [coll index]) and the composition (last (take index coll))

I'm trying to work through Stuart Halloway's book Programming Clojure. This whole functional stuff is very new to me.

I understand how

(defn fibo[]
    (map first (iterate (fn [[a b]] [b (+ a b)]) [0 1])))

generates the Fibonacci sequence lazily. I do not understand why

(last (take 1000000 (fibo)))

works, while

(nth (fibo) 1000000)

throws an OutOfMemoryError. Could someone please explain how these two expressions differ? Is (nth) somehow holding on to the head of the sequence?

Thanks!

like image 677
Josh Avatar asked Dec 15 '11 15:12

Josh


2 Answers

I think you are talking about issue that was discussed in google group and Rich Hickey provided patch that solved the problem. And the book, whick was published later, didn't cover this topic.

In clojure 1.3 your nth example works with minor improvements in fibo function. Now, due to changes in 1.3, we should explicitly flag M to use arbitrary precision, or it falls with throwIntOverflow.

(defn fibo[]
  (map first (iterate (fn [[a b]] [b (+ a b)]) [0M 1M])))

And with these changes

(nth (fibo) 1000000)

succeed (if you have enough memory)

like image 192
4e6 Avatar answered Oct 19 '22 04:10

4e6


What Clojure version are you using? Try (clojure-version) on a repl. I get identical results for both expressions in 1.3.0, namely an integer overflow.

For

(defn fibo[]
    (map first (iterate (fn [[a b]] [b (+ a b)]) [(bigint 0) 1])))

I get correct results for both expressions (a really big integer...).

like image 33
Michiel Borkent Avatar answered Oct 19 '22 05:10

Michiel Borkent