Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I pass a static method to comp in clojure?

It seems as though I'm having problems accessing Integer.parseInt in comp. I can access it normally like this:

user=> (Integer/parseInt "123")
123

But if I put it in comp, I get an error:

user=> (def vect-to-int (comp Integer/parseInt (partial apply str)))
java.lang.Exception: Unable to find static field: parseInt in class java.lang.Integer (NO_SOURCE_FILE:3)

It sounds to me like it's trying to find a field on Integer when it should be looking for a method. How can I use Integer.parseInt like this? And is there a better way to convert a vector of chars into an int?

like image 677
Jason Baker Avatar asked Feb 05 '10 17:02

Jason Baker


2 Answers

Clojure functions are java methods but java methods are not clojure functions For instance Clojure functions have meta-data and such. If you want to use a java method where a Clojure function is called for then you have two choices in wrapping it up, memfn and fun or #( ) memfn is an obsolete function that wrapped up a java method in a clojure function (its good to know it exists even if its not used often). The generally accepted way to wrap up java methods is:

#(. instance method arg1 argN)  

or for static methods

#(Class/MethodName arg1 argN)
like image 200
Arthur Ulfeldt Avatar answered Nov 05 '22 14:11

Arthur Ulfeldt


(def vec-to-int (comp #(Integer/parseInt %) (partial apply str)))

Or

(def vec-to-int #(Integer/parseInt (apply str %)))

partial and comp usually aren't as succinct in Clojure as using #() to make an anonymous fn. Personally I'd write it this way:

(defn vec-to-int [x] (Integer/parseInt (apply str x)))

You can do this with plain def, but what do you gain using def instead of defn, really? Using def obscures the fact that you're defining a function. defn also sets up additional metadata for you (arglists) that def doesn't.

In any case, this is a more general way to do what you're doing:

(def vec-to-int #(bigint (apply str %)))

And still more general:

(def vec-to-int #(read-string (apply str %)))

Depends whether you want to be able to handle things other than Integers.

like image 7
Brian Carper Avatar answered Nov 05 '22 14:11

Brian Carper