Search code examples
recursionclojuretail-recursiontail-call-optimization

What is the difference between loop/recur and recur by itself?


I'm having trouble finding the answer to this in the Clojure docs. I'm new to Clojure and it seems as though you can use recur in two different ways and essentially get the same result.

Example 1:

(defn my-function [num]
  (if (> num 10)
    num
    (recur (+ num 1))))

Example 2:

(defn my-function [num]
  (loop [cnt num]
    (if (> cnt 10)
      cnt
      (recur (+ cnt 1)))))

From what I can tell, these two forms seem to do the exact same thing. I understand that the reason recur is good generally is that under the right circumstances the compiler can hack together some kind of pseudo-tail-call-optimization, which I really like and would love to make use of as often as possible. So here are my questions:

  1. What is the need for using loop when recur seems to work without it?
  2. Does loop just create a "recursion scope" kind of like how let creates a mini scope?
  3. If so, can I still get the tail recursion benefits without using loop?

Solution

  • Just to answer your questions one by one:

    1. loop allows you to accept and pass arbitrary parameters. Without loop you would be limited with only being able to pass only what function accepts. It would lead to heaps of tiny auxiliary functions

    2. Yep, kind of

    3. It must be a tail call and it's constrained by compiler