So I was trying this:
user=> (Integer/toBinaryString ^int (.charValue \c))
"1100011"
user=>
And I thought... Well, that looks promising, so let's try this now:
user=> (map #(Integer/toBinaryString ^int (.charValue %)) "some")
ClassCastException java.lang.Character cannot be cast to java.lang.Number user/eval1209/fn--1210 (form-init3852254868488042860.clj:1)
user=> ; Tried this as well. But without luck:
user=> (map #(Integer/toBinaryString ^int (.charValue %)) (.toCharArray "some"))
ClassCastException java.lang.Character cannot be cast to java.lang.Number user/eval1249/fn--1250 (form-init3852254868488042860.clj:1)
user=>
oops! WTF is going on?
I have the thing working after introducing a hack:
user=> (map #(Integer/toBinaryString ^int (.charValue (Character/valueOf %))) "some")
("1110011" "1101111" "1101101" "1100101")
user=> ; Or alternatively:
user=> (map (fn [^Character c] (Integer/toBinaryString ^int (.charValue c))) "some")
("1110011" "1101111" "1101101" "1100101")
user=> ; Or:
user=> (map #(Integer/toBinaryString ^int (.charValue ^Character %)) "some")
("1110011" "1101111" "1101101" "1100101")
user=>
So, does anyone know why this just won't work without calling Character/valueOf
or explicitly casting?
Type hints aren't meant to change a program's semantics. The supposed way to convert a character to a number in Clojure is the int
function.
Example:
user=> (map #(-> % int Integer/toBinaryString) "some")
("1110011" "1101111" "1101101" "1100101")
So to be clear, in Clojure, char
s are supposed to always be autoboxed into Character
s which aren't numbers. The weird part in your code is therefore not when treating char
s as numbers doesn't work, but when it does, because in those cases the type hints change the semantics of your code which they aren't supposed to.