On Sat, Jan 17, 2009 at 11:06 AM, Greg Harman <[email protected]> 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 [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
-~----------~----~----~----~------~----~------~--~---