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))

現在のフレームまたはそれを囲む環境のいずれかで、指定されたシンボルで見つかった最初のバインディングを削除します。シンボルが最初からバインドされていない場合は、何もしません。この方法でバインド解除操作を実装することを選択したので、囲んでいる環境での (可能な) バインドはそのまま保持されます。

evalプロシージャを使用して特別なフォームmake-unbound!を評価することをプロシージャで指定することを忘れないでくださいeval-make-unbound

また、Racket の可変ペア ライブラリを使用して実装を行ったことに注意してください。したがって、私が使用しているプロシージャ名には、名前のどこかに余分なものが含まれていることがあります。つまり、可変ペアmに対して定義されているということです。例: . 前の手順のいずれかが見つからない場合は、名前から を削除して、もう一度やり直してください。mcar, mcdr, set-mcar!, set-mcdr!, massqm

于 2013-04-19T18:38:02.743 に答える