Hi Karl,

The other solutions seem higher level, but it's worth noting that
destructuring -- (let [[x & xs] lst] ...) -- uses next and is therefore
not fully lazy in that you will peek ahead by one into the lazy
sequence, so to speak.  You have to use explicit first / rest to get
that:
;; with destructuring
(defn flatten [lst]
  (lazy-seq
    (if (empty? lst) lst
        (let [[x & xs] lst]
          (if (list? x)
            (concat (flatten x) (flatten xs))
            (cons x (flatten xs)))))))

;; explicit first / rest
(defn flatten-2 [lst]
  (lazy-seq
    (if-let [x (first lst)]
      (let [xs (rest lst)]
        (if (seq? x)
          (concat (flatten-2 x) (flatten-2 xs))
          (cons x (flatten-2 xs)))))))

;; returns a fresh, unevaluated, lazy seq each time
(defn lazy-integers []
  (map #(do (print (str "[" % "] ")) %)
       (iterate inc 0)))

Then:

user> (take 5 (flatten (lazy-integers)))
([0] [1] [2] 0 [3] 1 [4] 2 [5] 3 4)

user> (take 5 (flatten-2 (lazy-integers)))
([0] [1] 0 [2] 1 [3] 2 [4] 3 4)

So, flatten-2 never looks at the 6th element, 5, when it returns the
first 5.  It's fully lazy in that it only evaluates the elements needed
for the result.

Of course, this is not a problem unless the lazy seq contains
computationally intensive or has side effects that need to be accounted
for in other ways.

-Sudish

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to