How is set! defined in scheme?

后端 未结 6 1167
囚心锁ツ
囚心锁ツ 2020-12-20 05:45

How would you implement your own set! function in Scheme? A set! function is a destructive procedure that changes a value that is defined taking into account th

6条回答
  •  天命终不由人
    2020-12-20 06:35

    As has been mentioned, set! is a primitive and can't be implemented as a procedure. To really understand how it works under the hood, I suggest you take a look at the inner workings of a Lisp interpreter. Here's a great one to start: the metacircular evaluator in SICP, in particular the section titled "Assignments and definitions". Here's an excerpt of the parts relevant for the question:

    (define (eval exp env)
      (cond ...
            ((assignment? exp) (eval-assignment exp env))
            ...
            (else (error "Unknown expression type -- EVAL" exp))))
    
    (define (assignment? exp)
      (tagged-list? exp 'set!))
    
    (define (eval-assignment exp env)
      (set-variable-value! (assignment-variable exp)
                           (eval (assignment-value exp) env)
                           env)
      'ok)
    
    (define (set-variable-value! var val env)
      (define (env-loop env)
        (define (scan vars vals)
          (cond ((null? vars)
                 (env-loop (enclosing-environment env)))
                ((eq? var (car vars))
                 (set-car! vals val))
                (else (scan (cdr vars) (cdr vals)))))
        (if (eq? env the-empty-environment)
            (error "Unbound variable -- SET!" var)
            (let ((frame (first-frame env)))
              (scan (frame-variables frame)
                    (frame-values frame)))))
      (env-loop env))
    

    In the end, a set! operation is just a mutation of a binding's value in the environment. Because a modification at this level is off-limits for a "normal" procedure, it has to be implemented as a special form.

提交回复
热议问题