If you cannot define a class (possibly programmatically in a macro) at compile time, you need to resort to using reflection. This will do the same as eval when it tries to compile the code. See clojure.lang.Reflector/invokeStaticMethod : https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Reflector.java#L198
(import 'clojure.lang.Reflector) ;; Here, you can pass *any string you have at runtime* (Reflector/invokeStaticMethod Integer "parseInt" (into-array ["1"]))
This can be used in arbitrary ways at runtime, since it is not a macro or a special form. For example, a method name can be provided by the user through a graphical interface or although a socket is at run time.
If you have a class name at compile time, you can use a macro, as suggested by Nicholas. However, there is no need to create code similar to (Integer/parseInt "1") , as it is just syntactic sugar for simpler (and macros) . special form: (. Integer parseInt "1") .
However, the only "real work" performed by this macro is to convert a string to a character. You are probably just using a special form . in an external macro (one that somehow acquires method names, for example, by getting passed as arguments or reading them from var or from a configuration file).
;; Use ordinary Clojure functions to construct this (def the-static-methods {:foo ["Integer" "parseInt"], :bar ["Long" "parseLong"]}) ;; Macros have access to all previously defined values (defmacro generate-defns [] (cons `do (for [[name-keyword [class-string method-string]] the-static-methods] `(defn ~(symbol (name name-keyword)) [x
source share