"Iteration provides an infinite lazy sequence"
(= (range 20) (take 20 (iterate inc 0)))
So my question is why it start from 0 instead of 1 ? How to understand the laziness here ?
"Iteration provides an infinite lazy sequence"
(= (range 20) (take 20 (iterate inc 0)))
So my question is why it start from 0 instead of 1 ? How to understand the laziness here ?
The koan asks for the iteration to begin at zero because range
starts at 0 by default, and that makes for nice looking statement. It is typical and useful in programming to start counting at 0 rather than 1. But, The koan could have been written to start at 1 (or any other number for that matter)
(= (range 1 21) (take 20 (iterate inc 1)))
Here's how iterate is defined
user=> (source iterate)
(defn iterate
"Returns a lazy sequence of x, (f x), (f (f x)) etc. f must be free of side-effects"
{:added "1.0"
:static true}
[f x] (cons x (lazy-seq (iterate f (f x)))))
So, here's how (iterate inc 0)
looks at first
(cons 0, (lazy-seq (iterate inc (inc 0))))
Now when the special lazy-seq element at position 1 (that is, the second position since we count from 0) is first accessed, it is in effect replaced by its expansion.
-- (iterate inc (inc 0))
-> (iterate inc 1)
-> (cons 1, (lazy-seq (iterate inc (inc 1))))
So, the sequence now looks like
-- (cons 0, (lazy-seq (iterate inc (inc 0))))
-> (cons 0, (cons 1 (lazy-seq (iterate inc (inc 1)))))
When the special lazy-seq element at position 2 is first accessed, it is in effect replaced by its expansion.
-- (iterate inc (inc 1))
-> (iterate inc 2)
-> (cons 2, (lazy-seq (iterate inc (inc 2))))
So, the sequence now looks like
-- (cons 0, (cons 1 (lazy-seq (iterate inc (inc 1)))))
-> (cons 0, (cons 1, (cons 2, (lazy-seq (iterate inc (inc 2))))))
Some consequences to be aware, but not typically anything to worry about as a new user
with-
block.(def numbers (iterate inc 0))
and realize a bunch of them, they will remain in memory. Avoid "holding the head" if this is to be a problem.clojure.core/iterate takes two arguments:
the fn
to apply to the last element in the sequence. When applied, it should produce the next element in the sequence
the initial value of the sequence
(iterate inc 0)
has 0
as the initial element of the sequence.
(take 1 (iterate inc 0)) ;; (0)