<< Previous exercise (4.12) | Index | Next exercise (4.14) >>
This isn't that elegant. The problem is that the way I wrote search-frame it returns the exact cons cell where the match occurred, so there really isn't any way to access the surrounding frame. Could easily be picked up by a garbage collector though.
(define (make-unbound! var env)
(let ((frame (first-frame env)))
(search-frame var
frame
(lambda (res) (and res (set-car! res '()) (set-cdr! res '())))
(lambda () '()))))
I believe 'make-unbound!' should construct a list for the evaluator to check with 'unbound?', and only afterwards it calls the unbinding procedure:
(define (make-unbound! var) (list 'unbound! var)) (define (unbound? exp) (tagged-list? exp 'unbound!)) (define (unbound!-var exp) (cadr exp)) (define (unbound! var env) (define (remove-binding var bindings) (cond ((null? bindings) '()) ((eq? var (caar bindings)) (cdr bindings)) (else (cons (car bindings) (remove-binding var (cdr bindings)))))) (let ((frame (first-frame env))) (set-cdr! frame (remove-binding var (frame-bindings frame)))))
wing
mazj
wing's answer is more 4 times quick than my:
(define (make-unbound! var env) ;4*linear (let ((frame (first-frame env))) (define pairs (filter (lambda (pair) (not (eq? (car pair) var-target))) (map cons (car frame) (cdr frame)))) (set-car! frame (map car pairs)) (set-cdr! frame (map cdr pairs))))