Maybe I didn't make myself clear enough. I'm implementing a scheme interpreter. 
The following function sets a variable in the given environment:
(defn set-var! [var val env]
 "Set a variable to a value, in the given or global environment"
 (if-let [val ((keyword var) @env)]
   (reset! env (assoc @env (keyword var) val))
   (set-global-var! var val))
 val)

Set global var shouldn't matter for now. The interpreter looks like that:

(defn interp [x env]
 "Interpret (evaluate) the expression x in the environment env."
 (cond
  (symbol? x) (get-var x env)
  (literal? x) x
  :else
  (let [form (first x)]
    (cond
     (= form 'quote) (second x)
     (= form 'begin) (last (map #(interp % env) (rest x)))
     (= form 'set!)  (set-var! (second x) (interp (nth x 2) env) env)
     (= form 'if)    (if (interp (second x) env)
                       (interp (nth x 2) env)
                       (interp (nth x 3) env))
     (= form 'lambda)     (let [parms (second x)
                           code (maybe-add 'begin (rest (rest x)))]
                       (println parms " " code)
                       (fn [& args] (interp code (extend-env parms args env))))
     :else ;; a procedure application
     (apply (interp (first x) env)
            (map #(interp % env) (rest x)))))))

Now (interp '(begin (set! a 30) (* a a)) (atom {:a 10 :* *})) returns 100 
instead of the expected 900.

I hope this makes things clearer. 
AndreasOn 18/01/2011, at 9:37 PM, MiltondSilva wrote:

> Not sure if I understand your question/problem but, this:
> 
> "How can I avoid the binding of changeling to the initial value of the
> atom and have the anonymous function passed to map use the current
> (possibly changed) value of changeling? "
> 
> You are binding a reference not the actual value of the atom. To pass
> the value you would deref it with '@' -> #(foo % @changeling)
> 
> On Jan 18, 10:44 am, Andreas Kostler
> <andreas.koestler.le...@gmail.com> wrote:
>> Hi all,
>> Suppose I have the following function:
>> (defn foo [x changeling]
>>   (cond
>>     (= (first x) 'bar)
>>       (map #(foo % changeling) (rest x))))
>> 
>> (def foobar (atom {:something "in-here"}))
>> 
>> Now, changeling gets bound to (atom {:something "in-here"}). The
>> conditional in foo might contain another case that actually changes
>> changeling.
>> How can I avoid the binding of changeling to the initial value of the
>> atom and have the anonymous function passed to map use the current
>> (possibly changed) value of changeling?
>> E.g. x is a list of functions working on changeling like (bar (add-to-
>> changeling :something :else) (do-something-with-changeling)). So bar
>> causes each of the elements of (rest x) to evaluate. add-something-to-
>> changeling adds stuff to changeling, do-something-with-changeling does
>> work depending on the recently added stuff.
>> Andreas
> 
> -- 
> 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

--
 “There is a strong correlation between being smart and being a nerd, and an 
even stronger inverse correlation between being a nerd and being popular”
(Paul Graham)
-- 
**********************************************************
Andreas Koestler, Software Engineer
Leica Geosystems Pty Ltd
270 Gladstone Road, Dutton Park QLD 4102
Main: +61 7 3891 9772     Direct: +61 7 3117 8808
Fax: +61 7 3891 9336
Email: andreas.koest...@leica-geosystems.com

************www.leica-geosystems.com*************

when it has to be right, Leica Geosystems

Please  consider the environment before printing this email.





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