On Sat, Nov 27, 2010 at 10:42 PM, Andreas Kostler <andreas.koestler.le...@gmail.com> wrote: > Hi all, > Sorry for my noob question (again). I'm trying to understand clojures > binding model. > Typing: > (def state {:status "foo"}) > (def rule '(if (= (:status sate) "foo") (println "foo") (println > ("bar"))) > > (defn fn [] > (let [state {:status "bar"}] > (eval rule))) > > This prints "foo". However, I would have expected the binding of state > created by let would shadow the global binding of state. > Now > > (defn fn1 [] > (binding [state {:status "bar"}] > (eval rule))) > Does the right thing. Can someone explain what's going on here please?
This is eval not seeing local bindings. There is a workaround: (defmacro eval-with-local-vars [vars sexp] (let [quoted-vars (vec (map #(list 'quote %) vars))] `(let [varvals# (vec (interleave ~quoted-vars ~vars))] (eval (list 'clojure.core/let varvals# ~sexp))))) user=> (let [a 1 b 2] (eval-with-local-vars [a b] '(+ a b))) 3 user=> (def state {:status "foo"}) #'user/state user=> (def rule '(if (= (:status state) "foo") (println "foo") (println "bar"))) #'user/rule user=> (let [state {:status "bar"}] (eval rule)) foo nil user=> (let [state {:status "bar"}] (eval-with-local-vars [state] rule)) bar nil -- 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