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
> <[email protected]> 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 [email protected]
> Note that posts from new members are moderated - please be patient with your
> first post.
> 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
--
“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: [email protected]
************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 [email protected]
Note that posts from new members are moderated - please be patient with your
first post.
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