Reputation: 231
I'm learning Clojure and am confused by the following:
(vector "1")
;; returns ["1"]
(map vector '("1" "2" "3"))
;; returns (["1"] ["2"] ["3"])
However:
(Integer/parseInt "1")
;; returns 1
(map Integer/parseInt '("1" "2" "3"))
;; throws error "Unable to find static field: parseInt in class java.lang.Integer"
Instead, I need:
(map #(Integer/parseInt %) '("1" "2" "3"))
;; returns (1 2 3)
If I can use a function like vector
with map
, why can't I use Integer/parseInt
?
Upvotes: 19
Views: 3591
Reputation: 4593
Have a look at the Stack Overflow question Convert a sequence of strings to integers (Clojure). The answer says: You have to wrap Integer/parseInt in an anonymous function because Java methods aren't functions.
Upvotes: -1
Reputation: 5881
You have to wrap it in #()
or (fn ...)
. This is because Integer/parseInt is a Java method and Java methods can't be passed around. They don't implement the IFn
interface.
Clojure is built on Java and sometimes this leaks through, and this is one of those cases.
Upvotes: 24
Reputation: 106401
As others have stated, you need to wrap Integer/parseInt in order to convert it from a Java method into a Clojure function:
(map #(Integer/parseInt %) '("1" "2" "3"))
The reason for this is that Clojure functions must implement the IFn interface in order to be passed as arguments into higher order functions such as map
.
This is a little bit ugly if you are doing this kind of conversion many times, so I'd recommend wrapping your parse-int function as follows:
(defn parse-int [s] (Integer/parseInt s))
(map parse-int '("1" "2" "3"))
As a final alternative, you may want to use the built-in read-string function - this will return integers in your case but would also work for doubles etc.:
(map read-string '("1" "2" "3"))
Upvotes: 6