Reputation: 1
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.
Upvotes: 0
Views: 50
Reputation: 66449
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
Upvotes: 1
Reputation: 92117
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.
Upvotes: 0