On Tue, 15 Jun 2010 03:24:08 -0700 (PDT)
Quzanti <quza...@googlemail.com> wrote:

> You can use recur to build a hierarchy. What do you mean by you can't
> use it as it is not the last statement?

Exactly that. recur in some sense terminates the current call, and
hence is required to be the last statement in the call.

> I have used recur in all sorts of places in the fn, without noticing
> any restrictions, and built hierarchies.

The restriction is temporal, not spatial. You can put the recur
statement anywhere you want, but there must be no other function
waiting on it's return value. Or, if it weren't a special form, then
it's value would be the value of the function.

So this is legal, with the recur as the last function both temporally
and spatially:

(defn counter [n & result]
  (if (zero? n)
     result
     (recur (dec n) (conj result n))))

And moving the recur spatially still works:

(defn counter2 [n & result]
  (if (> n 0)
     (recur (dec n) (conj result n))
     result))

But if we invert the conj and recur, so that conj uses the "result" of
the recur, it breaks at compile time, even if the recur is spatially
the last statement in the function:

(defn busted-counter [n]
   (if (zero? n)
      []
      (conj (recur (dec n)) n)))

You can, of course, write this as  a conventionally recursive function:

(defn recursive-counter [n]
   (if (zero? n)
      []
      (conj (recursive-counter (dec n)) n)))

But this version *isn't* tail recursive - it'll use up n levels of
stack.

Personally, I like recur. Telling the language "I believe this is a
tail recursive call" means it can tell me I was wrong at compile time,
rather than after it runs out of stack out run time. I hope it stays
around after we get TCE.

       <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 at
http://groups.google.com/group/clojure?hl=en

Reply via email to