Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why aren't recursive calls automagically replaced by recur?

In the following (Clojure) SO question: my own interpose function as an exercise

The accepted answers says this:

Replace your recursive call with a call to recur because as written it will hit a stack overflow

(defn foo [stuff]
  (dostuff ... )
  (foo (rest stuff)))

becomes:

(defn foo [stuff]
  (dostuff ...)
  (recur (rest stuff)))

to avoid blowing the stack.

It may be a silly question but I'm wondering why the recursive call to foo isn't automatically replaced by recur?

Also, I took another SO example and wrote this ( without using cond on purpose, just to try things out):

(defn is-member [elem ilist]
  (if (empty? ilist)
    false
    (if (= elem (first ilist))
      true
      (is-member elem (rest ilist)))))

And I was wondering if I should replace the call to is-member with recur (which also seems to work) or not.

Are there cases where you do recurse and specifically should not use recur?

like image 343
SyntaxT3rr0r Avatar asked Sep 29 '11 15:09

SyntaxT3rr0r


1 Answers

There's pretty much never a reason not to use recur if you have a tail-recursive method, although unless you're in a performance-sensitive area of code it just won't make any difference.

I think the basic argument is that having recur be explicit makes it very clear whether a function is tail-recursive or not; all tail-recursive functions use recur, and all functions that recur are tail-recursive (the compiler will complain if you try to use recur from a non-tail-position.) So it's a bit of an aesthetic decision.

recur also helps distinguish Clojure from languages which will do TCO on all tail calls, like Scheme; Clojure can't do that effectively because its functions are compiled as Java functions and the JVM doesn't support it. By making recur a special case, there's hopefully no inflated expectations.

I don't think there would be any technical reason why the compiler couldn't insert recur for you, if it were designed that way, but maybe someone will correct me.

like image 196
mqp Avatar answered Nov 15 '22 04:11

mqp