Reputation: 1453
(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
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
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