Thunfische
Thunfische

Reputation: 1157

Factorial iterative illegal argument - clojure

    (defn fac [n]
      (def result 1)
      (loop [i n c 1]
        (if (<= c 5)
          result
          (recur (* c i) (inc c))
          )
        )
      (println result)
      )

    (fac 5)

Error:Exception in thread "main" java.lang.IllegalArgumentException: loop requires a vector for its binding.

I am trying to write a function that evaluates a numbers factorial. Where is my mistake? It gives me 1 as answer

Upvotes: 0

Views: 51

Answers (1)

Thumbnail
Thumbnail

Reputation: 13483

At first sight:

  • Don't use a def inside a defn.
  • The REPL will print the result of evaluating a function. Use it.

This gets us to

(defn fac [n]
  (loop [i n c 1]
    (if (<= c 5)
      result
      (recur (* c i) (inc c)))))

... which doesn't compile, because result is floating.

There are a few corrections required:

  • Return i, not result.
  • Start i at 1, not n.
  • Turn the test around: > instead of <=.

We end up with

(defn fac [n]
  (loop [i 1, c 1]
    (if (> c n)
      i
      (recur (* c i) (inc c)))))

... which works:

(fac 5)
=> 120

Edited to correct one-off error and improve explanation.

Upvotes: 1

Related Questions