sicp-4-1-3-4-1-5
Posted on 2015-03-06 20:12:10 +0900 in SICP
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.
(try try)
returnshalted
: then it would fall into the(run-forever)
trap. Contradiction.(try try)
runs forever: then the first condition is false,halted
is returned. Contradiction.
Hide Comments
comments powered by Disqus