From 4c9dc3138b634feb8de1a629f7808c99448fd3b9 Mon Sep 17 00:00:00 2001 From: Felix Martin Date: Sat, 23 Jan 2021 14:02:35 -0500 Subject: [PATCH] Answer till 4.18 --- ex-4_11-xx.scm | 104 ++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 91 insertions(+), 13 deletions(-) diff --git a/ex-4_11-xx.scm b/ex-4_11-xx.scm index 591b7f6..2e4ccc5 100644 --- a/ex-4_11-xx.scm +++ b/ex-4_11-xx.scm @@ -190,7 +190,7 @@ (display "[answered]\n") -(display "\nex-4.16\n") +(display "\nex-4.16 - scan-out-defines\n") (define (lookup-variable-value var env) (let ((pair (find-pair-env var env))) @@ -201,20 +201,98 @@ (error "Unassigned variable" var) value))))) -(define env-0 the-empty-environment) -(define env-1 (extend-environment '(a b) '(1 2) env-0)) -(define env-2 (extend-environment '(c d) '(3 *unassigned*) env-1)) - (define (scan-out-defines body) - (cond - ((null? body) '()) - ((definition? (car body)) (cons (car body) (scan-out-defines (cdr body)))) - (else (scan-out-defines (cdr body))))) + (define (get-defines body) + (cond + ((null? body) '()) + ((definition? (car body)) (cons (car body) (get-defines (cdr body)))) + (else (get-defines (cdr body))))) + (define (expression->new-expression exp) + (if (definition? exp) + (define->set exp) + exp)) + (define (define->let-assignment def) + (list (definition-variable def) '*unassigned*)) + (define (define->set def) + (list 'set! (definition-variable def) (definition-value def))) + (let* ((defines (get-defines body)) + (let-assignments (map define->let-assignment defines)) + (let-expression (list 'let let-assignments)) + (expressions (map expression->new-expression body))) + (append let-expression expressions))) -(define body '((define x 3) - (if #t 1 2) - (define b 2))) +(define body + '((define x 3) + (if #t 1 2) + (define b 2) + (display "hello"))) -(display (scan-out-defines body)) (newline) +(define body-transformed + '(let ((x *unassigned*) + (b *unassigned*)) + (set! x 3) + (if #t 1 2) + (set! b 2) + (display "hello"))) + +(assert (scan-out-defines body) body-transformed) + +; I would install scan-out-defines into make-procedure. We might run into a +; situation where we update the body of a procedure and call procedure-body +; twice. + +(define (make-procedure parameters body env) + (list 'procedure parameters (scan-out-defines body) env)) (display "\nex-4.17\n") + +; Why is there an extra frame in the transformed program? We have implemented +; let via an additional transformation. Therefore, there is another +; lambda-expression that results in an extra frame. + +; Explain why this difference in environment structure can never make a +; difference in the behavior of a correct program? The transformation keeps the +; order of the assignments. Hence, the behavior will not change. + +; Design a way to make the interpreter implement the ``simultaneous'' scope +; rule for internal definitions without constructing the extra frame? We could +; simply add a list of (define symbol *unassigned*) at the beginning of the +; body and get the same behavior without an extra frame. + +(display "[answered]\n") + +(display "\nex-4.18 - alternative-scan-out\n") + +(define (solve f y0 dt) + (define y (integral (delay dy) y0 dt)) + (define dy (stream-map f y)) + y) + +; Transformation from text: +(lambda (f y0 dt) + (let ((y '*unassigned*) + (dy '*unassigned*)) + (set! y (integral (delay dy) y0 dt)) + (set! dy (stream-map f y)) + y)) + +; Transformation from this exercise: +(lambda (f y0 dt) + (let ((y '*unassigned*) + (dy '*unassigned*)) + (let ((a (integral (delay dy) y0 dt)) + (b (stream-map f y))) + (set! y a) + (set! dy b) + y))) + +; The second transformation will not work because when b is evaluated y is not +; yet assigned. The first transformation works because y was already set when +; dy is set. + +(display "[answered]\n") + +(display "\nex-4.19\n") + +; (display "\nex-4.20\n") +