Hello, What about giving back 'lazy-cons (or lcons as a shortcut), with the optional possibility to give the cons an internal name ? This could allow for self-recursive definition, such as this one for a fibonacci generator function as :
user=>(defn fib-fn [] (lcons [fib] 1 (lcons 1 (map + fib (rest fib))))) #'user/fib-fn user=> (take 10 (fib-fn)) (1 1 2 3 5 8 13 21 34 55) If you think it's interesting, see the detailed explanation below, and find the patch to play with it in google groups files section : http://groups.google.com/group/clojure/web/lazy-cons.patch I wanted to try a definition closer to the one I had in my Haskell book. This definition needs the ability for the lazy-seq to reference itself. For example, it can in straight clojure be written as : (def fib (lazy-seq (cons 1 (lazy-seq (cons 1 (map + fib (rest fib))))))) But of course, the above version, while interesting, leaks memory since the lazy seq is bound to a global var. So I've played with clojure core to allow the creation of lazy-sequences that can refer to themselves inside their body, and get rid of the memory leak problem. I've called this 'named-lazy-seq : (named-lazy-seq [a-name] ... ) And since the pattern (lazy-seq (cons ...)) may well be a common one, I've also recreated 'lazy-cons (or lcons for brevity) that is just a macro calling either 'lazy-seq or 'named-lazy-seq depending on its arity : (lazy-cons a-first-elem a-tail) <=> (lazy-seq (cons a-first-elem a-tail)) or (lazy-cons [a-name] a-first-elem a-tail) <=> (named-lazy-seq [a-name] (cons a-first-elem a-tail)) With these additions, one can write the fibonacci lazy sequence as : (lcons [fib] 1 (lcons 1 (map + fib (rest fib)))) and, of course, a fibonacci lazy sequence generator : (defn fib-fn [] (lcons [fib] 1 (lcons 1 (map + fib (rest fib))))) HTH, -- Laurent 2009/2/23 Stuart Halloway <stuart.hallo...@gmail.com> > > Beautiful-thanks. > - Afficher le texte des messages précédents - > > > Using a good old sequence of vectors: > > (defn fibo [] > > (map first (iterate (fn [[a b]] [b (+ a b)]) [0 1]))) > > > > Christophe > > > > Stuart Halloway a écrit : > >> I have updated the sample source from the book ( > http://tinyurl.com/clojure-samples > >> ) to the new laziness. Along the way, I replaced the lazy-cons based > >> implementation of the fibonacci numbers with this: > >> > >> (defn fibo > >> ([] > >> (concat [0 1] (fibo 0 1))) > >> ([a b] > >> (let [n (+ a b)] > >> (lazy-seq > >> (cons n (fibo b n)))))) > >> > >> Is there a better/more idiomatic approach, without resorting to code > >> in clojure-contrib? Test your code against the following expression > >> to > >> flush out stack and heap overflows. > >> > >> (rem (nth (fibo) 1000000) 1000) > >> -> 875 > >> > >> Also, the current 'fibs' implementation in clojure.contrib.seq fails > >> the test above, because it holds the entire sequence as it goes. We > >> should replace it with whatever the community comes up with on this > >> thread. > >> > >> Cheers, > >> Stu > >> > >>> > >> > >> > > > > > > -- > > Professional: http://cgrand.net/ (fr) > > On Clojure: http://clj-me.blogspot.com/ (en) > > > > > > > > > > > > > > --~--~---------~--~----~------------~-------~--~----~ 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 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 -~----------~----~----~----~------~----~------~--~---