sicp-4-1-3-4-1-5

Posted on 2015-03-06 20:12:10 +0900 in SICP Lisp

4.11

(define (make-frame variables values)
  (if (= (length variables) (length values))
    (map cons variables values)
    (error "length mismatch -- MAKE-FRAME" variables values)))

(define (frame-variables frame) (map car frame))
(define (frame-values frame) (map cdr frame))

4.12

I can only come up with a find-binding-frame function and manually controls its process under different situations. But Zhang come up with a more higher level abstraction which only expose two functions to all the rest logic, which is null-action and eq-action. Clean and robust!

(define (env-loop var null-action eq-action env)
  (define (scan vars vals)
    (cond ((null? vars)
           (null-action env))
          ((eq? var (car vars))
           (eq-action vals))
          (else (scan (cdr vars) (cdr vals)))))
  (if (eq? env the-empty-environment)
    (error "Unbound variable" var)
    (let ((frame (first-frame env)))
      (scan (frame-variables frame)
            (frame-values frame)))))

(define (set-variable-value! var val env)
  (define (null-action e)
    (env-loop var null-action eq-action (enclosing-environment e)))
  (define (eq-action vs)
    (set-car! vs val))
  (env-loop var null-action eq-action env))

(define (lookup-variable-value var env)
  (define (null-action e)
    (env-loop var null-action eq-action (enclosing-environment e)))
  (define eq-action car)
  (env-loop var null-action eq-action env))

(define (define-variable! var val env)
  (define (null-action e)
    (add-binding-to-frame! var val (first-frame e)))
  (define (eq-action vs)
    (set-car! vs val))
  (env-loop var null-action eq-action env))

4.13

 (define (make-unbound variable env)
   (let ((vars (frame-variables (first-frame env)))
         (vals (frame-values (first-frame env))))
     (define (unbound vars vals new-vars new-vals)
       (cond ((null? vars)
              (error "variable is not in the environment -- MAKE-UNBOUND"
                     variable))
             ((eq? (car vars) variable)
              (set-car! env
                        (cons (append new-vars (cdr vars))
                              (append new-vals (cdr vals)))))
             (else (unbound (cdr vars) (cdr vals)
                            (append  new-vars (list (car vars)))
                            (append  new-vals (list (car vals)))
     (unbound vars vals '() '())))

4.14

((application? exp)
 (apply (eval (operator exp) env)
        (list-of-values (operands exp) env)))

(define (apply procedure arguments)
  (cond ((primitive-procedure? procedure)
         (apply-primitive-procedure procedure arguments))
        ...)

(define (apply-primitive-procedure proc args)
  (apply-in-underlying-scheme
   (primitive-implementation proc) args))

When eval '(map + '(1 2) '(3 4)), primitive procedure + is evaluated as '(primitive +). Then expression becomes (apply-in-underlying-scheme map '(primitive +) '(1 2) '(3 4)), then failed.

4.15

(define (run-forever) (run-forever))
(define (try p)
  (if (halts? p p)
    (run-forever)
    'halted))

There are two possible outcomes to run (try try), either returns halted or runs forever.

  1. (try try) returns halted: then it would fall into the (run-forever) trap. Contradiction.
  2. (try try) runs forever: then the first condition is false, halted is returned. Contradiction.
----------------------------------- 本文内容遵从CC版权协议转载请注明出自kamelzcs -----------------------------------
«  | sicp-4-1 »

Hide Comments

comments powered by Disqus