Shalima Sidhik
Shalima Sidhik

Reputation: 83

ClassCastException in Clojure

I am new to clojure and i have been trying out different programs. Here is my program :

(defn sdsu-reverse [x]
  (loop [n (count x) x x]
  (if (= 0 n)
    (x)
    (recur (- n 1) (conj (next x) (first x))))))

(= (sdsu-reverse [1 2 3 4 5]) [5 4 3 2 1])

I have been getting error : java.lang.ClassCastException: clojure.lang.Cons cannot be cast to clojure.lang.IFn C:\Users\Shalima\Documents\Textbooks\Functional Programming\Programs\sample.clj:44 user/sdsu-reverse

But I cant seem to figure it out. Could you please help me with this ?

Thank you.

Upvotes: 1

Views: 2284

Answers (2)

Chris
Chris

Reputation: 1128

As Alex notes above, you need to replace (x) with x in your if expression. Wrapping x in parentheses treats it as a function when instead you want to return a value.

As for the other issue in your code:

conj is a slightly confusing function.

clojure.core/cons
([x seq])
  Returns a new seq where x is the first element and seq is
    the rest.

Sounds clear enough. But look at what happens when conj is applied to a list versus a vector (source).

user=> (conj [1 2 3] 4)
[1 2 3 4]

user=> (conj '(1 2 3) 4)
(4 1 2 3)

The reason for this has to do with how the vector and list datatypes are constructed. Vectors receive new values from the righthand side; lists, from the lefthand side.

When you call conj (next x) (first x), you effectively are calling conj '(2 3 4) '(1), over and over again. So you end up with the same value that you started at.

A better approach would be to use recursion as follows.

(defn sdsu-reverse [x]
  (if (empty? x)
    nil
    (cons (last x) (sdsu-reverse (drop-last x)))))

I hope this helps.

Edit in response to Leonid's comments.

Leonid is correct that the above will fail for large sequences. Alternatively you could do something like

(defn reverse' 
  ([x] (reverse' x nil))
  ([x acc] (if (empty? x) 
             acc 
             (recur (rest x) (cons (first x) acc)))))

Upvotes: 2

piyushmandovra
piyushmandovra

Reputation: 4381

class cast exception in your code is because you try to make a list from a constant i.e. (x) so just replace it with x you won't get class cast exception.

Upvotes: 0

Related Questions