Thanks Mike -

So I was doing a little more digging on this and came across an
interesting blog posting:

http://formpluslogic.blogspot.com/2009/07/clojure-lazy-seq-and-recursion.html

discussing the use of recursion vs lazy sequences.

To mimic Brent from his posting I created 2 fn's:

(defn date-seq [d1 d2]
  (let [start (-> d1
                (.dayOfMonth)
                (.withMinimumValue))]
     (cons start (if (joda/before? start d2)
                    (date-seq (.plusMonths start 1) d2)))))

(defn lazy-date-seq [d1 d2]
  (let [start (-> d1
                (.dayOfMonth)
                (.withMinimumValue))]
     (lazy-seq
       (cons start
         (if (joda/before? start d2)
           (lazy-date-seq (.plusMonths start 1) d2))))))

The lazy version worked like a champ and appears (to me) to be more in
the vain of Lisp (with a touch of Haskell).
Is the author of the blog correct about using lazy seq in this way?
Assuming that he is correct and I converted date-seq to a loop/recur
format to use TCO, would one of these be preferable over the other in
terms of idiomatic clojure?


Thanks

Bassel




On May 17, 5:27 pm, Mike Meyer <mwm-keyword-googlegroups.
620...@mired.org> wrote:
> On Mon, 17 May 2010 14:36:23 -0700 (PDT)
>
> Base <basselh...@gmail.com> wrote:
> > Hi All -
>
> > I am trying convert a  function to use loop/recur and am getting the
> > dreded
>
> > "java.lang.UnsupportedOperationException: Can only recur from tail
> > position (repl-1:414)" error
>
> > (at least dreded for newbies...)
>
> The "tail" position means it's the last call at the top level of the
> loop. I.e. - you can't call anything after the recur. In your case
>
>
>
> > The function takes 2 joda dates and returns a sequence of dates
> > starting at the first of the month until it is past the second date.
> > This works using standard recursion but I wanted to use TCO.
>
> > Any help is most appreciated (as usual...!)
>
> > Thanks
>
> > Base
>
> > (def date-seq
> >   (fn [d1 d2]
> >     (loop [b (-> d1
> >                (.dayOfMonth)
> >                (.withMinimumValue))
> >            e d2]
> >      (cons b (if (time/before? b e)
> >                (recur (.plusMonths b 1) e))))))
>
> In this case, you're calling cons with the result of the recur, which
> means it happens "after" the recur, which is the error.
>
> I suspect your original wasn't tail recursive, since the two loop
> arguments are two dates (assuming my guesses about time/before? are
> correct), and the values in the list you returns would be stored on
> the call stack, to be pasted together by the string of conses you've
> left to run after each recursive call.
>
> To make it tail recursive, you need to make the list you're going to
> return one of the arguments of the loop, adjust the code for that,
> then push the cons into the if, sort of like so:
>
> (defn date-seq
>   [d1 d2]
>   (loop [b (-> d1
>              (.dayOfMonth)
>              (.withMinimumValue))
>          e [d2]]
>    (if (time/before? b (first e))
>      (recur (.plusMonths b 1) (conj e b))
>      (reverse b))))
>
> This is just a swag; I'm not familiar enough with Java to reconstruct
> your arguments...
>
>      <mike
> --
> Mike Meyer <m...@mired.org>            http://www.mired.org/consulting.html
> Independent Network/Unix/Perforce consultant, email for more information.
>
> O< ascii ribbon campaign - stop html mail -www.asciiribbon.org
>
> --
> 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 
> athttp://groups.google.com/group/clojure?hl=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
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