Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Recursive lazy sequences in Clojure
(defmacro rec-lazy-seq
"Like lazy-seq, but also takes a single binding form that will be
a reference to the lazy seq object itself, so that the lazy seq can
be defined in terms of itself."
[[name] & body]
`(let [p# (promise)
ls# (lazy-seq
(let [~name (lazy-seq @p#)]
~@body))]
(deliver p# ls#)
ls#))
;; This version of repeat uses a single seq object no matter
;; how much of it you consume; you can even hold on to the head
;; without danger.
(defn repeat
"Returns a lazy sequence containing an infinite number of x's."
[x]
(rec-lazy-seq [s]
(cons x s)))
;; Similarly with cycle, there are only n seq objects (for a collection
;; of n items) no matter how far you consume.
(defn cycle
"Returns a lazy infinite sequence of repetitions of the items in coll."
[coll]
(rec-lazy-seq [s]
(concat coll s)))
;; A haskell-style definition of the fibonacci sequence
(def fibs
(rec-lazy-seq [s]
;; need an extra call to lazy-seq so we don't force it too early
(list* 0 1 (lazy-seq (map +' s (rest s))))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.