How to call function (or Java method) using string name?

1,124 views
Skip to first unread message

timc

unread,
Apr 26, 2009, 10:46:40 AM4/26/09
to Clojure
Is there a way of invoking functions, or java methods "by name" in
Clojure?
Or, put another way, why does this work:

(+ 1 2)

but this does not:

((symbol "+") 1 2)

Similarly, this works

(. javaObj (methodName param))

but this does not:

(. javaObj ((symbol "methodName") param))


I suppose this really comes down to the question: what is a symbol?
And, is the thing at the head of the list (+ 1 2 3) a symbol?

[In Icon, for example, there is no difference between

"funcName"(1,2,3) and funcName(1,2,3), or indeed:

x := "funcName"
x(1,2,3)

which is VERY useful.]

Stuart Sierra

unread,
Apr 26, 2009, 12:21:05 PM4/26/09
to Clojure
This will work:
((resolve (symbol "+")) 1 2 3)

To answer your question, a symbol is just a symbol, it doesn't have a
value. (In Common Lisp, symbols have values, but in Clojure they do
not.) In Clojure, values belong to Vars. "resolve" will find the Var
that is named by the symbol. When you write (+ 1 2 3), the compiler
automatically resolves the "+" to get the Var #'clojure.core/+

To invoke Java methods by name, use the Java Reflection API:
http://java.sun.com/docs/books/tutorial/reflect/index.html

-Stuart Sierra

timc

unread,
Apr 26, 2009, 1:50:29 PM4/26/09
to Clojure
Thanks Stuart.

I have figured out another way, which is much more general (and uses
the lowest level of how Clojure works).

(defn evalStr [s] (clojure.lang.Compiler/eval (clojure.lang.RT/
readString s)))

will (attempt to) execute any valid form (i.e. the string that is the
source of the form).

Thus: (evalStr "(+ 1 2)") --> 3

Stuart Sierra

unread,
Apr 26, 2009, 3:05:18 PM4/26/09
to Clojure
Yes. The following should also work, without calling into Clojure
implementation methods:
(defn eval-string [s]
(eval (read-string s)))

-Stuart Sierra

fft1976

unread,
Apr 27, 2009, 3:49:05 AM4/27/09
to Clojure


On Apr 26, 9:21 am, Stuart Sierra <the.stuart.sie...@gmail.com> wrote:
> "resolve" will find the Var
> that is named by the symbol.  

Can there be Vars without names? Can I have a vector of Vars?

Christophe Grand

unread,
Apr 27, 2009, 3:55:26 AM4/27/09
to clo...@googlegroups.com
fft1976 a écrit :

You can, see with-local-vars for example.

Stuart Sierra

unread,
Apr 27, 2009, 11:28:56 AM4/27/09
to Clojure
On Apr 27, 3:49 am, fft1976 <fft1...@gmail.com> wrote:
> Can there be Vars without names? Can I have a vector of Vars?

Vars always have names, but you can create temporary Vars using with-
local-vars. If you want to create a vector of unnamed, mutable
objects, you probably want Refs or Atoms instead.

-Stuart Sierra

Richard Lyman

unread,
Apr 27, 2009, 1:41:21 PM4/27/09
to clo...@googlegroups.com
There's a section on the wiki with almost the exact same title:

http://en.wikibooks.org/wiki/Clojure_Programming/Examples#Invoking_Java_method_through_method_name_as_a_String

If I'm understanding the question correctly that should do what you're wanting to do.

-Rich

timc

unread,
Apr 27, 2009, 3:00:52 PM4/27/09
to Clojure
Thanks again!

On Apr 27, 6:41 pm, Richard Lyman <richard.ly...@gmail.com> wrote:
> There's a section on the wiki with almost the exact same title:
>
> http://en.wikibooks.org/wiki/Clojure_Programming/Examples#Invoking_Ja...
>
> If I'm understanding the question correctly that should do what you're
> wanting to do.
>
> -Rich
>
Reply all
Reply to author
Forward
0 new messages