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 -~----------~----~----~----~------~----~------~--~---