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

Reply via email to