On Sat, Jan 17, 2009 at 11:06 AM, Greg Harman <ghar...@gmail.com> wrote: > > Meta: This thread is a revival and continuation of last month's > discussion at: > http://groups.google.com/group/clojure/browse_thread/thread/e1226810b6ac7bfc/8e0f53c141c26fcc?lnk=gst&q=eval+binding#8e0f53c141c26fcc > > --- > > Nathan, did you ever come up with a better way to do this than using a > global var? > > One solution is to use (binding), which still requires a global var, > but gives each eval it's own binding of that var: > > user=> (def x) > #'user/x > user=> (def expr '(+ x 4)) > #'user/expr > user=> (binding [x 3] (eval expr)) > 7 > user=> x > java.lang.IllegalStateException: Var user/x is unbound. > (NO_SOURCE_FILE:0)
I tried this approach with (binding) and I also tried creating anonymous functions from the expressions: (eval (list 'fn '[x] expr)) Creating functions didn't work for me because I used up the PermGen space in the garbage collector with all the classes created to implement them. As best I remember, I got the same outcome with (binding), even though I wasn't creating new functions. The approach that worked for me was to create my own recursive evaluation function: (defn eval-expr [expr] (cond (seq expr) (let [[op & args] expr] (apply @(resolve op) (map eval-expr args))) (= expr 'x) x :else expr)) I'm still using the var x, but it's not inherent to the approach; you could easily add a map of symbols to values as an additional argument. -- Nathan --~--~---------~--~----~------------~-------~--~----~ 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 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 -~----------~----~----~----~------~----~------~--~---