Thanks Evan and Lee.... Lee's approach works in my code except for one interesting wrinkle. The item that I pass in ('a' in the example) can only really be used if a particular library is loaded.
So what I'm doing now is taking the code string from the user -- user-string-- and wrapping it like this (format "(do (require '[my.lib :as lib]) (try %s (catch Exception e e)))" user-string) ... bound to expr. And then I get the result... (try ((eval (list 'fn '[a] (read-string expr))) a) (catch Exception e e)) ... This is all presented to the user in a Seesaw UI form. Here's the wrinkle: code that uses any fn from lib throws an exception No such namespace: lib But if I try again with just a (the value) or any other expression like 1, that succeeds. And then if I try the code from the initial attempt *(the exact code that failed in the previous paragraph)* it now also succeeds! Why might that be? On Tue, Jul 31, 2012 at 8:30 PM, Lee Spector <> wrote: > > An approach that doesn't involve dynamic variables is to build, evaluate, > and then call a function that's made out of the given code and takes an > argument for the variable. > > Assuming for the moment that the code is in symbolic form (rather than > string form) like this: > > => (def exp 'a) > #<Var@2dd1082f: a> > > Then you can do something like: > > => (let [a 0] ((eval (list 'fn '[a] exp)) a)) > 0 > > It's easier to see why this is useful with a slightly more complex piece > of code (but it could be anything): > > => (def exp '(+ a 100)) > #<Var@2dd1082f: (+ a 100)> > > => (let [a 0] ((eval (list 'fn '[a] exp)) a)) > 100 > > If your code really is in a string then you want to call read-string on it: > > => (def strexp "(+ a 100)") > #<Var@45d1c3cd: "(+ a 100)"> > > => (let [a 0] ((eval (list 'fn '[a] (read-string strexp))) a)) > 100 > > Of course the outermost "a"s here could and probably should be something > else, since that'd be less confusing (I just used "a" to better match the > original question): > > => (let [foo 0] ((eval (list 'fn '[a] (read-string strexp))) foo)) > 100 > > -Lee > > > On Jul 31, 2012, at 7:32 PM, Evan Mezeske wrote: > > > This thread on SO might be helpful: > http://stackoverflow.com/questions/6221716/variable-scope-eval-in-clojure. > > > > On Tuesday, July 31, 2012 2:02:30 PM UTC-7, Andrew wrote: > > I have a value and a string. The string contains valid Clojure code and > it mentions a variable. I'd like to let-bind that variable to the value and > then evaluate the string. Can this be done? > > > > As a small example, I thought this would work: (let [a 0] (eval 'a))) > > > > Or maybe this: > > user> (let [a 0] (eval 'user/a)) > > > > My initial attempt was this: (let [a 0] (eval (read-string "a"))) > > > > These all result in an exception... > > -- > You received this message because you are subscribed to the Google > Groups "Clojure" group. > To post to this group, send email to clojure@googlegroups.com > Note that posts from new members are moderated - please be patient with > your first post. > To unsubscribe from this group, send email to > clojure+unsubscr...@googlegroups.com > For more options, visit this group at > http://groups.google.com/group/clojure?hl=en > -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en