tags:

views:

93

answers:

2

In clojure 1.2RC1, I wish to obtain a function based on its name as string and evaluate it.

Function definition

(ns my-ns)

(defn mycar [x] (first x))

The following worked:

((ns-resolve *ns* (symbol "mycar")) '(3 4))
((intern *ns* (symbol "mycar")) '(3 4))
((eval (symbol "mycar")) '(3  4))

but they seem ugly. Is there a better way? If not, which of the above is the most idiomatic?

A: 

I'm not sure about a 'cleaner' way of doing it, but generally with programming shorter = better, so I would use ((eval (symbol "mycar")) '(3 4)). (Also, eval is a more widely known command.)

Josh
+7  A: 

This worked for me without using eval:

user> (defn mycar [x] (first x))
#'user/mycar
user> ((resolve (symbol "mycar")) [1 2 3])
1

This works because resolves finds the mycar var in the current namespace and the var calls the function it's bound to. This is a shorter version of your first example. I'd use it just so that I could avoid using eval.

Rayne
I second the use of `resolve` or `ns-resolve`. Also pay close attention when using `intern`. It's quite is to clobber things using it.
kotarak
Any pointers to more information on "clobbering" caused by intern?
chris
<del>Set a Var with intern and your original meta data on the Var will be gone.</del> Ignore. Seems to be fixed. At least I can't reproduce it anymore.
kotarak