Re: no set-car! in clojure

2015-08-06 Thread Herwig Hochleitner
You could define your own cons type, like Bodil Stokke did for her
microkanren
https://github.com/bodil/microkanrens/blob/77dbdc34cde580e26765138102cbdabbfad85b9d/mk.clj#L13
If you mark its fields with ^:volatile-mutable, you can call (set! (.-a
lst) new-car) on a cons instance.

cheers

-- 
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
--- 
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 clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: no set-car! in clojure

2015-08-06 Thread Francis Avila
There is no equivalent to set-car!, because conses are not mutable. Only 
vars, refs, atoms, and agents are mutable, and they are simply containers 
for immutable values.  You could put a cons inside an atom and put a new 
transformed list into the atom. (Note even among schemes set-car! is highly 
discouraged, and I don't think Racket even has it in core 
anymore: 
http://blog.racket-lang.org/2007/11/getting-rid-of-set-car-and-set-cdr.html)

The idiomatic Clojure way of handling this is to always have an immutable 
environment and contain it in a single environment atom.  When you change 
the environment, you return a new copy of it with your change and put it in 
to the global env atom. The SICP mutates the environment instead. There's 
probably a reason for this (late/dynamic binding?) which would have a 
completely different approach in Clojure.

Some more notes:

(empty? nil) ;=> true

def and defn create namespace-global vars as a side effect--the vars are 
not lexically scoped! This is NOT like scheme's "define." I suspect all of 
your inner uses of def and defn should be let and letfn instead. def and 
defn are used at the top level or (rarely) are used a level or two down to 
close over some private data (e.g. a def inside a let). However, defs are 
practically never inside other defs.

On Thursday, August 6, 2015 at 12:36:20 PM UTC-5, 杨旸 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 
>  
> 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 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
--- 
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 clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: no set-car! in clojure

2015-08-06 Thread James Reeves
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, 杨旸  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
> 
> 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 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
> ---
> 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 clojure+unsubscr...@googlegroups.com.
> 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 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
--- 
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 clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.