Welcome! Please see the About page for a little more info on how this works.

0 votes
in Clojure by
edited by

I am learning clojure, it's my 2nd day with the language, and writing some simple functions:

(defn fib_effi
(cond (= n 0) 0
      (= n 1) 1
     :else ((defn fib_iter [i fibi_n_prev fibi_n]
               (if (= i n) fibi_n
                   (fib_iter (+ i 1) fibi_n (+ fibi_n fibi_n_prev))))
             (fib_iter 1 0 1))))
(fib_effi 3)

I am getting the error message:

  1. Unhandled clojure.lang.ArityException
    Wrong number of args (1) passed to:

Is there anything I am missing?

1 Answer

+2 votes
selected by
Best answer

First off, defn (and def) always produce global, top-level bindings of names to values so you should never use them inside another defn (or def).

Second, you have:

 (defn fib_iter ...)
 (fib_iter ...)

The ( .. ) delineate a function call so you have the first element (the (defn .. ) form) which is then called as a function with the second element (the (fib_iter .. ) form) as an argument. But fib_iter is declared to take three arguments (i, fibi_n_prev, and fibi_n) and you are effectively calling it with just one argument.

You should use let for local bindings, so you would have (let [fib_iter (fn [i fibi_n_prev fibi_n] .. )] (fib_iter 1 0 1)) and you should find that will work.