basav
basav

Reputation: 1453

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

(defn is-member? [a lst] 
((cond 
        (empty? lst) false
        (= a (first lst)) true
        :else (is-member? a (rest lst))
    )))

(is-member? :b '(:a :b :c))

When I execute the above code I get error

ClassCastException java.lang.Boolean cannot be cast to clojure.lang.IFn user/is-member? (NO_SOURCE_FILE:28)

Why? I understand that if an expression is enclosed in parentheses then that means it will be evaluated as a function..

Upvotes: 12

Views: 7664

Answers (2)

mefryar
mefryar

Reputation: 363

As I discovered, even if the cond expression is in single parentheses, you'll get the same ClassCastException if you wrap each conditional test-expression pair in parentheses.

;; INCORRECT
(defn is-member?
  [a lst] 
  (cond 
    ((empty? lst) false)
    ((= a (first lst)) true)
    (:else (is-member? a (rest lst)))))

;; CORRECT
(defn is-member?
  [a lst] 
  (cond 
    (empty? lst) false
    (= a (first lst)) true
    :else (is-member? a (rest lst))))

Upvotes: 0

NielsK
NielsK

Reputation: 6956

You got the cond expression in double parentheses. That causes the final result of cond (true or false) to be called as a function. Fix that and it works.

=> (defn is-member?
     [a lst] 
     (cond 
       (empty? lst) false
       (= a (first lst)) true
       :else (is-member? a (rest lst))))
#'user/is-member?

=> (is-member? :b '(:a :b :c))
true

The most idiomatic way to do this in Clojure, by the way, is using some.

=> (some #{:b} [:a :b :c])
:b

This returns the actual first value, but because of Clojure's truthiness it can be used in conditionals in much the same way as true and false.

Upvotes: 18

Related Questions