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
-~----------~----~----~----~------~----~------~--~---

Reply via email to