The clojure document gives the following examples:
(take 10 (iterate (partial + 2) 0))
(def powers-of-two (iterate (partial * 2) 1))
(take 10 powers-of-two)
(def fib (map first (iterate (fn [[a b]] [b (+ a b)]) [1 1])))
(take 10 fib)
Anyone can explain the syntax of clojure's iterate function in more detail? I am very confused with all the usage. Why two brackets are there in (fn [[a b]] [b (+ a b)])?
Another example can be found here:
(defn iter [[x y]]
(vector y (+ x y)))
(nth (iterate iter [0 1]) 10000)
One way to translate an imperative for loop to Clojure is to use the for macro. The above function will return all the numbers from 0 to 9 incremented by 1. However, it appears you simply want to iterate over a sequential collection and use each item.
Overview. Clojure is not a lazy language. However, Clojure supports lazily evaluated sequences. This means that sequence elements are not available ahead of time and produced as the result of a computation.
Lazy sequences are regular sequences where each item is computed on demand rather than up front. For example, consider this array of numbers: let numbers = Array(1... 100000) That will hold 100,000 numbers.
iterate
takes a function f
and an initial value x
and produces a lazy sequence. The first element in the seq is x
. Each subsequent element is computed by calling f
with the previous element.
Example 1:
(iterate (partial + 2) 0)
This generates a sequence, starting at 0, where each element is the previous element with 2 added to it. I.e.:
0
(+ 2 0) ; => 2
(+ 2 2) ; => 4
(+ 2 4) ; => 6
; etc
Each element in the seq is passed to (partial + 2)
when generating the following element.
Example 2:
(iterate (partial * 2) 1)
This generates a sequence, starting at 1, where each element is the previous element multiplied by 2. I.e.:
1
(* 2 1) ; => 2
(* 2 2) ; => 4
(* 2 4) ; => 8
(* 2 8) ; => 16
; etc
Again, you can see how each element feeds into the generation of the next one.
Example 3:
(iterate (fn [[a b]] [b (+ a b)]) [1 1])
Firstly, (fn [[a b]] ...)
is a way to destructure a value into parts. In this case, the function accepts a two-element vector and unpacks it into the local variables a
and b
.
The function returns a two-element vector containing b
and the sum of a
and b
(i.e. the second value in the previous pair and the sum of both values in the previous pair).
With this in mind, this iterate
call generates:
[1 1]
[1 (+ 1 1)] ; => [1 2]
[2 (+ 1 2)] ; => [2 3]
[3 (+ 2 3)] ; => [3 5]
[5 (+ 3 5)] ; => [5 8]
; etc
Then (map first ...)
grabs the first value in each pair, which gives you your Fibonacci sequence.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With