11
votes

How to cast a character to int in Clojure?

I am trying to write a rot 13 in clojure, so I need to have something to cast my char to int. I found something called (int), so I put:

(int a)

Get: CompilerException java.lang.RuntimeException: Unable to resolve symbol: a in this context, compiling:(NO_SOURCE_PATH:13:1)

Then I put:

(int 'a)

Get: ClassCastException clojure.lang.Symbol cannot be cast to `java.lang.Character clojure.lang.RT.intCast (RT.java:1087)

Then:

(rot13 ''a')

Get: ClassCastException clojure.lang.PersistentList cannot be cast to java.lang.Character clojure.lang.RT.intCast (RT.java:1087)

And:

(rot13 "a")

Get:

ClassCastException java.lang.String cannot be cast to java.lang.Character  clojure.lang.RT.intCast (RT.java:1087)

So what is the right way to do it?

btw, I always get confused with all these clojure syntax. But I can never find any source only help me with my problem. Any suggestions? Thank you!!

3
I believe you are looking for a "character literal" such as \a (the error message says it wants a Character, not an integer).user2864740
Thank you! That solves my problem. First time on stackoverflow and this is a good place!zaolian
Use the documentation, particularly regarding the reader.Alex Taggart

3 Answers

20
votes

Clojure will convert characters to int automatically if you ask nicely. It will convert it using ascii equivalence (well unicode in fact).

(int \a);;=>97
(int \b);;=>98
(int \c);;=>99

However, if you want to convert a Clojure char that is also a number to an int or long :

(Character/digit \1 10) ;; => 1
(Character/digit \2 10) ;; => 2

A non-digit char will be converted to -1 :

(Character/digit \a 10) ;;=> -1

Which is ok in this case, since \-1 is not a character.

(Character/digit \-1 10);;=>java.lang.RuntimeException: Unsupported character: \-1

It could be convenient also to note that - would convert to -1, although I wound not rely on it too much :

(Character/digit \- 10);;=>-1

The second parameter is obviously the base. Ex :

(Character/digit \A 16);;=>10
12
votes

What you are looking for is a character literal \a. A character literal is denoted by a single character, or 16-bit unicode code point, prefixed by the \ reader macro.

(int \a) ;; => 97

(int \0) ;; => 48

(int \u0030) ;; => 48


With (int a), a is a symbol. As such, the runtime tried and failed to resolve what that symbol was bound to.


With (int 'a), a is also a symbol, but, because you declared it a symbol with the single quote ('), the runtime took it literally and tried and faild to cast the clojure.lang.Symbol to a java.lang.Character.


With (rot13 ''a'), 'a' declares a' as a symbol. But, the extra ' prefixing it makes the runtime treat the expression that declared the a' literally. 'a' expands to (quote a'), so the "literal literal", ''a', expands to the list (quote a').

''a' ;; => (quote a')

(second ''a') ;; => a'


With (rot13 "a"), a is a string. Strings cannot be cast to characters, but they can be treated as collections of characters. So, (rot13 (first "a")) would work as intended.

-1
votes

Not sure why the long discussions above.

(Integer/parseInt s)