How is set-car! modifying my closure environment?

62 views Asked by At

I am coding a meta-circular interpreter and am trying to implement closures. I have a function make-lambda which makes the closure:

(define (make-lambda parameters body env)
 (list 'lambda parameters body env)
)

And a function which handles definitions in which I have a check to see if the definition contains a lambda in which case I would need to create a closure:

(let* ((closure (make-lambda (cadadr defn) (cddadr defn) env)) ; creates a closure
         (var (car defn))
         (binding `(,var . ()))) 
      (display closure) 
      (newline)
      (display "CLOSURE BEFORE: ")
      (display (cadddr closure))
      (newline)
      (set-car! env (cons binding (car env)))
      (display "CLOSURE AFTER: ")
      (display (cadddr closure)) ; why is this different? 
      (newline)
      ;(set-cdr! binding (meta-eval error (cadddr closure) ))
      ;(set-cdr! binding closure)
      (display "NORMAL: ")
      (display env)
      (newline)

    )

I cannot seem to figure out why cadddr closure is different before and after the set-car! call. Any help would be appreciated.

I have tried all sorts of troubleshooting and have some in the code above and still do not know what is going on.

2

There are 2 answers

0
amalloy On

The cadddr of closure is another pointer to env, as you can see from the definition of make-lambda. Since you have modified the list pointed to by env, all references to it, both env and (cadddr closure), will reflect the changed list.

0
molbdnilo On

env and (cadddr closure) are the same list.

This is your structure,

           +---+---+   +---+---+   +---+---+   +---+---+
closure -->| | |  ---->| | |  ---->| | |  ---->| | | X |
           +-|-+---+   +-|-+---+   +-|-+---+   +-|-+---+
             |           |           |           |
             v           v           v           v
            ...         ...         ...        +---+---+   +---+---+
                                        env -->| | |  ---->| | |  ----> ...
                                               +-|-+---+   +-|-+---+
                                                 |           |
                                                 v           v
                                                b_0         b_1

and the result after (set-car! env (cons binding (car env))):

           +---+---+   +---+---+   +---+---+   +---+---+
closure -->| | |  ---->| | |  ---->| | |  ---->| | | X |
           +-|-+---+   +-|-+---+   +-|-+---+   +-|-+---+
             |           |           |           |
             v           v           v           v
            ...         ...         ...        +---+---+
                                        env -->| | |  ----> b_0
                                               +-|-+---+   
                                                 |         
                                                 v         
                                               binding