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

Reply via email to