Getting a Java cast exception


#1

I have the following code, which is a part of Clojure katas:

(ns alphabet-cipher.coder)

(def letters (map char (range 97 123)))

(defn rotate
  [n]
  (-> n
      (split-at letters)
      (reverse)
      (flatten)))

(def cipher-map
  (apply hash-map
         (mapcat #(list (keyword (str %1)) (rotate %2))
                 letters (range 0 26))))

(defn encode
  [keyword message]
  (apply str (map #(nth ((keyword (str %2)) cipher-map)
                        (.indexOf (:a cipher-map) %1))
                  keyword message)))

(encode "meetmebythetree" "sconessconessco")

The code itself doesn’t matter.

What matters is that upon executing this code in repl i get the following:

CompilerException java.lang.ClassCastException: java.base/java.lang.String cannot be cast to clojure.lang.IFn, compiling

What is going on? If I remove arguments in encode function and hardcode both bindings it works just fine, but when passing the arguments it just crashes. encode is definitely a function.


#2

It’s obvious (when you see it - but it took me a while :slight_smile: ): in fn encode, the first parameter is called keyword so it shadows the call to core/keyword and it actually tries calling a string, thence String cannot be cast to IFn.

Suggestion: use a function for your #(...}block, so you can test it autonomously. It took me a while to understand what it was doing. In Clojure, always go for clarity.


#3

Oh god you are right about this one, its just my stupidity. Thanks.