Amogh Talpallikar
Amogh Talpallikar

Reputation: 12184

How does Clojure loop form works?

I am new to Clojure an Functional Programming both. I tried my best, understanding the loop construct.

I can use it, I can look at a code written with it and tell the output but what I dont understand is,How does it work ?

is it same as writing an anonymous function with parameters and then keeping recur at the tail with same arity and new values ?

is it an inbuilt macro or something for it ?

Upvotes: 3

Views: 486

Answers (2)

amalloy
amalloy

Reputation: 92012

dbyrne's answer is all true, and good, but I'd like to address your further question "Is it the same as writing an anonymous function with parameters and then recur at the tail with same arity and new values?". Yes, it is exactly like that:

(loop [x 1, y 2]
  (if (whatever x y)
    (recur (inc x) (dec y))
    (* x y)))

is functionally identical to

((fn [x y]
   (if (whatever x y)
     (recur (inc x) (dec y))
     (* x y)))
 1 2)

If loop didn't exist, you could write it as a simple macro that emits this sort of form, but the compiler has a special loop form which is faster.

(defmacro loop [bindings & body]
  (let [bindings (partition 2 bindings)]
    `((fn [~@(map first bindings)]
        (do ~@body))
      ~@(map second bindings))))

Upvotes: 5

dbyrne
dbyrne

Reputation: 61041

Actually, loop is not a function or a macro. It is a special form. It works just like let (which is also a special form) except that it acts as a target for recur.

One way to differentiate functions, macros, and special forms is to examine how their arguments are evaluated:

  • Function arguments are always evaluated, and then the results are passed to the function.
  • Macro arguments are not evaluated until the macro expands to a new unevaluated form.
  • Special form arguments are not evaluated when passed, but the special form may or may not choose to evaluate them internally.

Upvotes: 7

Related Questions