recursive code in clojure and class cast exception

77 views Asked by At
(defn fib [n]
         (if ((= n 0) 0)
           ((= n 1) 1)
           (:else (+ (fib (- n 1)) 
              (fib (- n 2))))))
(fib 10)

ClassCastException java.lang.Boolean cannot be cast to clojure.lang.IFn

The same exception with the following.

(defn A [x y]
 (cond ((= y 0) 0)
       ((= x 0) (* 2 y))
       ((= y 1) 2)
       (:else (A (- x 1) (A x (- y 1))))))
(A  1 10)

Whats wrong with this unable to understand, please explain ?

1

There are 1 answers

0
Scott On BEST ANSWER

You were so close!

(defn A [x y]
  (cond (= y 0) 0
        (= x 0) (* 2 y)
        (= y 1) 2
        :else (A (- x 1)
                 (A x (- y 1)))))

You simply had too many parentheses wrapping the cond forms.

Works fine now:

user=> (A  1 10)
1024

There are some similar issues in your recursive fib function. Pay careful attention to indentation - this will always help you see where your issue lies.

In this particular case the exception ClassCastException java.lang.Boolean cannot be cast to clojure.lang.IFnis being thrown by this line:

((= n 1) 1)

... because (= n 1) is being evaluated to either Boolean true or false, and because this resulting boolean is in the first position of the ((= n 1) 1) form, it means that Clojure will attempt to call the boolean as a function (clojure.lang.IFn).

This is what Clojure is really seeing:

(true 1)

Which is why Clojure is trying to cast a Boolean as an IFn. IFn is a Java interface which represents a callable function.

I hope that makes sense.