As with all Clojure data structures, lists in Clojure are immutable, so they cannot be modified in place.
Also, defs in Clojure are always global to the current namespace, no matter where they are. For this reason, it's generally not a good idea to nest defns. You may want to refer to how other people have approached these problems. For instance: https://github.com/gregsexton/SICP-Clojure/blob/master/src/sicp/ch4.clj - James On 6 August 2015 at 16:40, 杨旸 <[email protected]> wrote: > Hi everyone, > I am current trying to implement a scheme interpreter in clojure following > the instruction on SICP chap4. > > Where I encounter a problem with adding/modifying a def var/fn in > enviroment. > > according to chap4 4.1.3 the set-variable-value! function looks like the > following in scheme: > (define (set-variable-value! var val env) > (define (env-loop env) > (define (scan vars vals) > (cond ((null? vars) > (env-loop (enclosing-environment env))) > ((eq? var (car vars)) > (set-car! vals val)) > (else (scan (cdr vars) (cdr vals))))) > (if (eq? env the-empty-environment) > (error "Unbound variable -- SET!" var) > (let ((frame (first-frame env))) > (scan (frame-variables frame) > (frame-values frame))))) > (env-loop env)) > > > > > But I found there's no set-car! in clojure, which make me have to > re-create the env while loop though the defied variables like: > *https://github.com/zacyang/sicp-in-clj/blob/master/src/sicp/ch4/core.clj > <https://github.com/zacyang/sicp-in-clj/blob/master/src/sicp/ch4/core.clj> > line #348* > > > (defn set-variable-value! > [var-looking-for val-to-be-set env] > > > (defn find-and-change [vars vals] > (cond > (empty? vars) '() > (= (first vars) var-looking-for) (conj (find-and-change (rest vars) > (rest vals)) val-to-be-set) > :else (conj (find-and-change (rest vars) (rest vals)) (first vals)))) > > > (defn env-loop > [e] > > (if (= @env @the-empty-environment) > :ERROR-TRY-SET-UNBOUND-VARIABLE > (let [frame (first-frame e) > frame-vars (frame-variables frame) > frame-vals (frame-values frame)] > > (if (not= @(enclosing-enviroment e) @the-empty-environment) > (extend-enviroment frame-vars frame-vals (env-loop > (enclosing-enviroment e))) > (extend-enviroment > frame-vars > (find-and-change frame-vars frame-vals) > the-empty-environment))))) > > > (env-loop env) > ) > > My question is, is there any good substitution for set-car! in scenarios > where I need just *change* the car and cdr of something created by cons?? > > PS: tried swap! atom , but it will also need to change the whole > environment structure. > > > > > > -- > 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 > --- > You received this message because you are subscribed to the Google Groups > "Clojure" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to [email protected]. > For more options, visit https://groups.google.com/d/optout. > -- 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 --- You received this message because you are subscribed to the Google Groups "Clojure" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. For more options, visit https://groups.google.com/d/optout.
