Takes a body of expressions that returns an ISeq or nil, and yields
a Seqable object that will invoke the body only the first time seq
is called, and will cache the result and return it on all subsequent
seq calls. See also - realized?
;; The following defines a lazy-seq of all positive numbers. Note that ;; the lazy-seq allows us to make a recursive call in a safe way because ;; the call does not happen immediately but instead creates a closure. user=> (defn positive-numbers ([] (positive-numbers 1)) ([n] (lazy-seq (cons n (positive-numbers (inc n)))))) #'user/positive-numbers user=> (take 5 (positive-numbers)) (1 2 3 4 5)
;; A lazy-seq of Fibonacci numbers (fn = fn-1 + fn-2) ;; The producer function takes exactly two parameters ;; (because we need the last 2 elements to produce a new one) user=> (defn fib [a b] (lazy-seq (cons a (fib b (+ b a))))) user=> (take 5 (fib 1 1)) (1 1 2 3 5)
;; It might be easier to think about the producer function as a function ;; that, given element n, produces element n+1 via a recursive call to ;; itself, wrapped with lazy-seq to delay its execution ;; We might also provide no-argument version of the function that calls ;; itself for the first element(s) of the sequence being generated. ;; => variant of fibonaci with a no-arg version and using cons first: (defn sum-last-2 ([] (sum-last-2 1 2)) ([n m] (cons n (lazy-seq (sum-last-2 m (+ n m)))))) user=> (take 6 (sum-last-2)) (1 2 3 5 8 13)
(defmacro lazy-seq
"Takes a body of expressions that returns an ISeq or nil, and yields
a Seqable object that will invoke the body only the first time seq
is called, and will cache the result and return it on all subsequent
seq calls. See also - realized?"
{:added "1.0"}
[& body]
(list 'new 'clojure.lang.LazySeq (list* '^{:once true} fn* [] body)))
Comments top
No comments for lazy-seq. Log in to add a comment.