0

我正在尝试操作 Scheme 评估器并编写一个make-unbound!从环境中取消绑定变量的过程:

(define (make-unbound! var env)
  (let ((frame (first-frame env)))
      (define (scan vars vals)
        (let ((new-frame 
                (make-frame 
                  (zip 
                    (filter (lambda (x) (not (eq? x (car vars)))) vars)
                    (filter (lambda (x) (not (eq? x (car vals)))) vals))
                  env)))
        (cond ((null? vars) 
               (display '(No frame to unbind)))
              ((eq? var (car vars))
               (set-car! vars new-frame)) ; the problem seems to be here
              (else (scan (cdr vars) (cdr vals))))))
      (scan (frame-variables frame)
            (frame-values frame))))

问题似乎出在我设置变量汽车的位置。但我不确定它应该改成什么......

4

1 回答 1

1

这看起来像 SICP 的练习 4.13。make-unbound!可以使用 Racket 像这样评估特殊形式:

(define (remove-association! key lst)
  (define (loop prev l)
    (cond ((null? l) lst)
          ((equal? (mcar (mcar l)) key)
           (set-mcdr! prev (mcdr l))
           lst)
          (else (loop l (mcdr l)))))
  (cond ((null? lst) '())
        ((eq? (mcar (mcar lst)) key) (mcdr lst))
        (else (loop lst (mcdr lst)))))

(define (unbind-variable! var env)
  (define (env-loop env)
    (define (scan bindings)
      (cond ((massq var bindings)
             (set-mcar! env (remove-association! var bindings)))
            (else (env-loop (enclosing-environment env)))))
    (unless (eq? env the-empty-environment)
      (scan (first-frame env))))
  (env-loop env))

(define (unbound-variable exp)
  (cadr exp))

(define (eval-make-unbound! exp env)
  (unbind-variable! (unbound-variable exp)
                    env))

它会删除与给定符号一起找到的第一个绑定,无论是在当前帧中还是在其任何封闭环境中。如果符号一开始是未绑定的,则它什么也不做。我选择以这种方式实现 unbind 操作,以便封闭环境中的(可能的)绑定保持不变。

不要忘记在过程中指定要使用该过程评估eval特殊形式。make-unbound!eval-make-unbound

另外,请注意,我使用 Racket 的可变对库实现了我的实现,因此我使用的过程名称有时m在其名称中的某处有一个额外的地方,这意味着:它们是为可变对定义的。例如:mcar, mcdr, set-mcar!, set-mcdr!, massq。如果没有找到之前的任何过程,只需m从名称中删除 并重试。

于 2013-04-19T18:38:02.743 回答