Solution to 4.30. Extremely enlightening!
authorRamakrishnan Muthukrishnan <vu3rdd@gmail.com>
Wed, 30 May 2012 17:05:29 +0000 (22:35 +0530)
committerRamakrishnan Muthukrishnan <vu3rdd@gmail.com>
Wed, 30 May 2012 17:05:29 +0000 (22:35 +0530)
src/sicp/ex4_30.rkt [new file with mode: 0644]
src/sicp/metacircular2-lazy.rkt

diff --git a/src/sicp/ex4_30.rkt b/src/sicp/ex4_30.rkt
new file mode 100644 (file)
index 0000000..6b971b5
--- /dev/null
@@ -0,0 +1,300 @@
+#lang racket
+
+(require "metacircular2-lazy.rkt")
+
+(define env1 (make-environment))
+(eval '(define (for-each proc items)
+         (if (null? items)
+             'done
+             (begin (proc (car items)) 
+                    (for-each proc (cdr items)))))
+      env1)
+(eval '(for-each (lambda(x) (newline) (display x)) '(1 2 3)) env1)
+
+#|
+
+Part a.
+
+One can observe the execution of this routine by a small modification to the 2 procedures that constitute
+the lazy evaluator as follows (the only change is printing of the arguments)
+
+(define (actual-value exp env)
+  (display (format "eval expr ~s~%" exp))
+  (newline)
+  (force-it (eval exp env)))
+
+(define (force-it obj)
+  ;; (display (format "~s~%" obj))
+  (match obj
+    [`(thunk ,exp ,env) (begin
+                          (display (format "eval's output ~s~%" obj))
+                          (newline)
+                          (actual-value exp env))]
+    [_ obj]))
+
+As we can observe during the execution, the `begin' gets transformed to `eval-sequence'
+and then `newline' and `(display x)' are called. Both these are primitive expressions
+and so the arguments are forced by apply.
+
+The trace of the execution of the above definition and the evaluation are listed below.
+|#
+
+#|
+
+eval expr for-each
+
+eval expr (null? items)
+
+eval expr null?
+
+eval expr items
+
+eval's output (thunk (quote (1 2 3)) #0=(#hash((newline . (primitive #<procedure:newline>)) (false . #f) (cons . (primitive #<procedure:cons>)) (cdr . (primitive #<procedure:cdr>)) (display . (primitive #<procedure:display>)) (car . (primitive #<procedure:car>)) (/ . (primitive #<procedure:/>)) (null? . (primitive #<procedure:null?>)) (list . (primitive #<procedure:list>)) (+ . (primitive #<procedure:+>)) (true . #t) (= . (primitive #<procedure:=>)) (- . (primitive #<procedure:->)) (> . (primitive #<procedure:>>)) (* . (primitive #<procedure:*>)) (< . (primitive #<procedure:<>)) (for-each . (procedure (proc items) ((if (null? items) (quote done) (begin (proc (car items)) (for-each proc (cdr items))))) #0#)))))
+
+eval expr (quote (1 2 3))
+
+eval expr proc
+
+eval's output (thunk (lambda (x) (newline) (display x)) #0=(#hash((newline . (primitive #<procedure:newline>)) (false . #f) (cons . (primitive #<procedure:cons>)) (cdr . (primitive #<procedure:cdr>)) (display . (primitive #<procedure:display>)) (car . (primitive #<procedure:car>)) (/ . (primitive #<procedure:/>)) (null? . (primitive #<procedure:null?>)) (list . (primitive #<procedure:list>)) (+ . (primitive #<procedure:+>)) (true . #t) (= . (primitive #<procedure:=>)) (- . (primitive #<procedure:->)) (> . (primitive #<procedure:>>)) (* . (primitive #<procedure:*>)) (< . (primitive #<procedure:<>)) (for-each . (procedure (proc items) ((if (null? items) (quote done) (begin (proc (car items)) (for-each proc (cdr items))))) #0#)))))
+
+eval expr (lambda (x) (newline) (display x))
+
+eval expr newline
+
+
+eval expr display
+
+eval expr x
+
+eval's output (thunk #0=(car items) (#hash((proc . (thunk (lambda (x) (newline) (display x)) #1=(#hash((newline . (primitive #<procedure:newline>)) (false . #f) (cons . (primitive #<procedure:cons>)) (cdr . (primitive #<procedure:cdr>)) (display . (primitive #<procedure:display>)) (car . (primitive #<procedure:car>)) (/ . (primitive #<procedure:/>)) (null? . (primitive #<procedure:null?>)) (list . (primitive #<procedure:list>)) (+ . (primitive #<procedure:+>)) (true . #t) (= . (primitive #<procedure:=>)) (- . (primitive #<procedure:->)) (> . (primitive #<procedure:>>)) (* . (primitive #<procedure:*>)) (< . (primitive #<procedure:<>)) (for-each . (procedure (proc items) ((if (null? items) (quote done) (begin (proc #0#) (for-each proc (cdr items))))) #1#)))))) (items . (thunk (quote (1 2 3)) #1#))) . #1#))
+
+eval expr (car items)
+
+eval expr car
+
+eval expr items
+
+eval's output (thunk (quote (1 2 3)) #0=(#hash((newline . (primitive #<procedure:newline>)) (false . #f) (cons . (primitive #<procedure:cons>)) (cdr . (primitive #<procedure:cdr>)) (display . (primitive #<procedure:display>)) (car . (primitive #<procedure:car>)) (/ . (primitive #<procedure:/>)) (null? . (primitive #<procedure:null?>)) (list . (primitive #<procedure:list>)) (+ . (primitive #<procedure:+>)) (true . #t) (= . (primitive #<procedure:=>)) (- . (primitive #<procedure:->)) (> . (primitive #<procedure:>>)) (* . (primitive #<procedure:*>)) (< . (primitive #<procedure:<>)) (for-each . (procedure (proc items) ((if (null? items) (quote done) (begin (proc (car items)) (for-each proc (cdr items))))) #0#)))))
+
+eval expr (quote (1 2 3))
+
+1eval expr for-each
+
+eval expr (null? items)
+
+eval expr null?
+
+eval expr items
+
+eval's output (thunk #0=(cdr items) (#hash((proc . (thunk (lambda (x) (newline) (display x)) #1=(#hash((newline . (primitive #<procedure:newline>)) (false . #f) (cons . (primitive #<procedure:cons>)) (cdr . (primitive #<procedure:cdr>)) (display . (primitive #<procedure:display>)) (car . (primitive #<procedure:car>)) (/ . (primitive #<procedure:/>)) (null? . (primitive #<procedure:null?>)) (list . (primitive #<procedure:list>)) (+ . (primitive #<procedure:+>)) (true . #t) (= . (primitive #<procedure:=>)) (- . (primitive #<procedure:->)) (> . (primitive #<procedure:>>)) (* . (primitive #<procedure:*>)) (< . (primitive #<procedure:<>)) (for-each . (procedure (proc items) ((if (null? items) (quote done) (begin (proc (car items)) (for-each proc #0#)))) #1#)))))) (items . (thunk (quote (1 2 3)) #1#))) . #1#))
+
+eval expr (cdr items)
+
+eval expr cdr
+
+eval expr items
+
+eval's output (thunk (quote (1 2 3)) #0=(#hash((newline . (primitive #<procedure:newline>)) (false . #f) (cons . (primitive #<procedure:cons>)) (cdr . (primitive #<procedure:cdr>)) (display . (primitive #<procedure:display>)) (car . (primitive #<procedure:car>)) (/ . (primitive #<procedure:/>)) (null? . (primitive #<procedure:null?>)) (list . (primitive #<procedure:list>)) (+ . (primitive #<procedure:+>)) (true . #t) (= . (primitive #<procedure:=>)) (- . (primitive #<procedure:->)) (> . (primitive #<procedure:>>)) (* . (primitive #<procedure:*>)) (< . (primitive #<procedure:<>)) (for-each . (procedure (proc items) ((if (null? items) (quote done) (begin (proc (car items)) (for-each proc (cdr items))))) #0#)))))
+
+eval expr (quote (1 2 3))
+
+eval expr proc
+
+eval's output (thunk proc (#hash((proc . (thunk (lambda (x) (newline) (display x)) #0=(#hash((newline . (primitive #<procedure:newline>)) (false . #f) (cons . (primitive #<procedure:cons>)) (cdr . (primitive #<procedure:cdr>)) (display . (primitive #<procedure:display>)) (car . (primitive #<procedure:car>)) (/ . (primitive #<procedure:/>)) (null? . (primitive #<procedure:null?>)) (list . (primitive #<procedure:list>)) (+ . (primitive #<procedure:+>)) (true . #t) (= . (primitive #<procedure:=>)) (- . (primitive #<procedure:->)) (> . (primitive #<procedure:>>)) (* . (primitive #<procedure:*>)) (< . (primitive #<procedure:<>)) (for-each . (procedure (proc items) ((if (null? items) (quote done) (begin (proc (car items)) (for-each proc (cdr items))))) #0#)))))) (items . (thunk (quote (1 2 3)) #0#))) . #0#))
+
+eval expr proc
+
+eval's output (thunk (lambda (x) (newline) (display x)) #0=(#hash((newline . (primitive #<procedure:newline>)) (false . #f) (cons . (primitive #<procedure:cons>)) (cdr . (primitive #<procedure:cdr>)) (display . (primitive #<procedure:display>)) (car . (primitive #<procedure:car>)) (/ . (primitive #<procedure:/>)) (null? . (primitive #<procedure:null?>)) (list . (primitive #<procedure:list>)) (+ . (primitive #<procedure:+>)) (true . #t) (= . (primitive #<procedure:=>)) (- . (primitive #<procedure:->)) (> . (primitive #<procedure:>>)) (* . (primitive #<procedure:*>)) (< . (primitive #<procedure:<>)) (for-each . (procedure (proc items) ((if (null? items) (quote done) (begin (proc (car items)) (for-each proc (cdr items))))) #0#)))))
+
+eval expr (lambda (x) (newline) (display x))
+
+eval expr newline
+
+
+eval expr display
+
+eval expr x
+
+eval's output (thunk #0=(car items) (#hash((proc . (thunk proc #3=(#hash((proc . (thunk (lambda (x) (newline) (display x)) #1=(#hash((newline . (primitive #<procedure:newline>)) (false . #f) (cons . (primitive #<procedure:cons>)) (cdr . (primitive #<procedure:cdr>)) (display . (primitive #<procedure:display>)) (car . (primitive #<procedure:car>)) (/ . (primitive #<procedure:/>)) (null? . (primitive #<procedure:null?>)) (list . (primitive #<procedure:list>)) (+ . (primitive #<procedure:+>)) (true . #t) (= . (primitive #<procedure:=>)) (- . (primitive #<procedure:->)) (> . (primitive #<procedure:>>)) (* . (primitive #<procedure:*>)) (< . (primitive #<procedure:<>)) (for-each . (procedure (proc items) ((if (null? items) (quote done) (begin (proc #0#) (for-each proc #2=(cdr items))))) #1#)))))) (items . (thunk (quote (1 2 3)) #1#))) . #1#))) (items . (thunk #2# #3#))) . #1#))
+
+eval expr (car items)
+
+eval expr car
+
+eval expr items
+
+eval's output (thunk #0=(cdr items) (#hash((proc . (thunk (lambda (x) (newline) (display x)) #1=(#hash((newline . (primitive #<procedure:newline>)) (false . #f) (cons . (primitive #<procedure:cons>)) (cdr . (primitive #<procedure:cdr>)) (display . (primitive #<procedure:display>)) (car . (primitive #<procedure:car>)) (/ . (primitive #<procedure:/>)) (null? . (primitive #<procedure:null?>)) (list . (primitive #<procedure:list>)) (+ . (primitive #<procedure:+>)) (true . #t) (= . (primitive #<procedure:=>)) (- . (primitive #<procedure:->)) (> . (primitive #<procedure:>>)) (* . (primitive #<procedure:*>)) (< . (primitive #<procedure:<>)) (for-each . (procedure (proc items) ((if (null? items) (quote done) (begin (proc (car items)) (for-each proc #0#)))) #1#)))))) (items . (thunk (quote (1 2 3)) #1#))) . #1#))
+
+eval expr (cdr items)
+
+eval expr cdr
+
+eval expr items
+
+eval's output (thunk (quote (1 2 3)) #0=(#hash((newline . (primitive #<procedure:newline>)) (false . #f) (cons . (primitive #<procedure:cons>)) (cdr . (primitive #<procedure:cdr>)) (display . (primitive #<procedure:display>)) (car . (primitive #<procedure:car>)) (/ . (primitive #<procedure:/>)) (null? . (primitive #<procedure:null?>)) (list . (primitive #<procedure:list>)) (+ . (primitive #<procedure:+>)) (true . #t) (= . (primitive #<procedure:=>)) (- . (primitive #<procedure:->)) (> . (primitive #<procedure:>>)) (* . (primitive #<procedure:*>)) (< . (primitive #<procedure:<>)) (for-each . (procedure (proc items) ((if (null? items) (quote done) (begin (proc (car items)) (for-each proc (cdr items))))) #0#)))))
+
+eval expr (quote (1 2 3))
+
+2eval expr for-each
+
+eval expr (null? items)
+
+eval expr null?
+
+eval expr items
+
+eval's output (thunk #0=(cdr items) (#hash((proc . (thunk proc #2=(#hash((proc . (thunk (lambda (x) (newline) (display x)) #1=(#hash((newline . (primitive #<procedure:newline>)) (false . #f) (cons . (primitive #<procedure:cons>)) (cdr . (primitive #<procedure:cdr>)) (display . (primitive #<procedure:display>)) (car . (primitive #<procedure:car>)) (/ . (primitive #<procedure:/>)) (null? . (primitive #<procedure:null?>)) (list . (primitive #<procedure:list>)) (+ . (primitive #<procedure:+>)) (true . #t) (= . (primitive #<procedure:=>)) (- . (primitive #<procedure:->)) (> . (primitive #<procedure:>>)) (* . (primitive #<procedure:*>)) (< . (primitive #<procedure:<>)) (for-each . (procedure (proc items) ((if (null? items) (quote done) (begin (proc (car items)) (for-each proc #0#)))) #1#)))))) (items . (thunk (quote (1 2 3)) #1#))) . #1#))) (items . (thunk #0# #2#))) . #1#))
+
+eval expr (cdr items)
+
+eval expr cdr
+
+eval expr items
+
+eval's output (thunk #0=(cdr items) (#hash((proc . (thunk (lambda (x) (newline) (display x)) #1=(#hash((newline . (primitive #<procedure:newline>)) (false . #f) (cons . (primitive #<procedure:cons>)) (cdr . (primitive #<procedure:cdr>)) (display . (primitive #<procedure:display>)) (car . (primitive #<procedure:car>)) (/ . (primitive #<procedure:/>)) (null? . (primitive #<procedure:null?>)) (list . (primitive #<procedure:list>)) (+ . (primitive #<procedure:+>)) (true . #t) (= . (primitive #<procedure:=>)) (- . (primitive #<procedure:->)) (> . (primitive #<procedure:>>)) (* . (primitive #<procedure:*>)) (< . (primitive #<procedure:<>)) (for-each . (procedure (proc items) ((if (null? items) (quote done) (begin (proc (car items)) (for-each proc #0#)))) #1#)))))) (items . (thunk (quote (1 2 3)) #1#))) . #1#))
+
+eval expr (cdr items)
+
+eval expr cdr
+
+eval expr items
+
+eval's output (thunk (quote (1 2 3)) #0=(#hash((newline . (primitive #<procedure:newline>)) (false . #f) (cons . (primitive #<procedure:cons>)) (cdr . (primitive #<procedure:cdr>)) (display . (primitive #<procedure:display>)) (car . (primitive #<procedure:car>)) (/ . (primitive #<procedure:/>)) (null? . (primitive #<procedure:null?>)) (list . (primitive #<procedure:list>)) (+ . (primitive #<procedure:+>)) (true . #t) (= . (primitive #<procedure:=>)) (- . (primitive #<procedure:->)) (> . (primitive #<procedure:>>)) (* . (primitive #<procedure:*>)) (< . (primitive #<procedure:<>)) (for-each . (procedure (proc items) ((if (null? items) (quote done) (begin (proc (car items)) (for-each proc (cdr items))))) #0#)))))
+
+eval expr (quote (1 2 3))
+
+eval expr proc
+
+eval's output (thunk proc (#hash((proc . (thunk proc #2=(#hash((proc . (thunk (lambda (x) (newline) (display x)) #0=(#hash((newline . (primitive #<procedure:newline>)) (false . #f) (cons . (primitive #<procedure:cons>)) (cdr . (primitive #<procedure:cdr>)) (display . (primitive #<procedure:display>)) (car . (primitive #<procedure:car>)) (/ . (primitive #<procedure:/>)) (null? . (primitive #<procedure:null?>)) (list . (primitive #<procedure:list>)) (+ . (primitive #<procedure:+>)) (true . #t) (= . (primitive #<procedure:=>)) (- . (primitive #<procedure:->)) (> . (primitive #<procedure:>>)) (* . (primitive #<procedure:*>)) (< . (primitive #<procedure:<>)) (for-each . (procedure (proc items) ((if (null? items) (quote done) (begin (proc (car items)) (for-each proc #1=(cdr items))))) #0#)))))) (items . (thunk (quote (1 2 3)) #0#))) . #0#))) (items . (thunk #1# #2#))) . #0#))
+
+eval expr proc
+
+eval's output (thunk proc (#hash((proc . (thunk (lambda (x) (newline) (display x)) #0=(#hash((newline . (primitive #<procedure:newline>)) (false . #f) (cons . (primitive #<procedure:cons>)) (cdr . (primitive #<procedure:cdr>)) (display . (primitive #<procedure:display>)) (car . (primitive #<procedure:car>)) (/ . (primitive #<procedure:/>)) (null? . (primitive #<procedure:null?>)) (list . (primitive #<procedure:list>)) (+ . (primitive #<procedure:+>)) (true . #t) (= . (primitive #<procedure:=>)) (- . (primitive #<procedure:->)) (> . (primitive #<procedure:>>)) (* . (primitive #<procedure:*>)) (< . (primitive #<procedure:<>)) (for-each . (procedure (proc items) ((if (null? items) (quote done) (begin (proc (car items)) (for-each proc (cdr items))))) #0#)))))) (items . (thunk (quote (1 2 3)) #0#))) . #0#))
+
+eval expr proc
+
+eval's output (thunk (lambda (x) (newline) (display x)) #0=(#hash((newline . (primitive #<procedure:newline>)) (false . #f) (cons . (primitive #<procedure:cons>)) (cdr . (primitive #<procedure:cdr>)) (display . (primitive #<procedure:display>)) (car . (primitive #<procedure:car>)) (/ . (primitive #<procedure:/>)) (null? . (primitive #<procedure:null?>)) (list . (primitive #<procedure:list>)) (+ . (primitive #<procedure:+>)) (true . #t) (= . (primitive #<procedure:=>)) (- . (primitive #<procedure:->)) (> . (primitive #<procedure:>>)) (* . (primitive #<procedure:*>)) (< . (primitive #<procedure:<>)) (for-each . (procedure (proc items) ((if (null? items) (quote done) (begin (proc (car items)) (for-each proc (cdr items))))) #0#)))))
+
+eval expr (lambda (x) (newline) (display x))
+
+eval expr newline
+
+
+eval expr display
+
+eval expr x
+
+eval's output (thunk #0=(car items) (#hash((proc . (thunk proc #4=(#hash((proc . (thunk proc #3=(#hash((proc . (thunk (lambda (x) (newline) (display x)) #1=(#hash((newline . (primitive #<procedure:newline>)) (false . #f) (cons . (primitive #<procedure:cons>)) (cdr . (primitive #<procedure:cdr>)) (display . (primitive #<procedure:display>)) (car . (primitive #<procedure:car>)) (/ . (primitive #<procedure:/>)) (null? . (primitive #<procedure:null?>)) (list . (primitive #<procedure:list>)) (+ . (primitive #<procedure:+>)) (true . #t) (= . (primitive #<procedure:=>)) (- . (primitive #<procedure:->)) (> . (primitive #<procedure:>>)) (* . (primitive #<procedure:*>)) (< . (primitive #<procedure:<>)) (for-each . (procedure (proc items) ((if (null? items) (quote done) (begin (proc #0#) (for-each proc #2=(cdr items))))) #1#)))))) (items . (thunk (quote (1 2 3)) #1#))) . #1#))) (items . (thunk #2# #3#))) . #1#))) (items . (thunk #2# #4#))) . #1#))
+
+eval expr (car items)
+
+eval expr car
+
+eval expr items
+
+eval's output (thunk #0=(cdr items) (#hash((proc . (thunk proc #2=(#hash((proc . (thunk (lambda (x) (newline) (display x)) #1=(#hash((newline . (primitive #<procedure:newline>)) (false . #f) (cons . (primitive #<procedure:cons>)) (cdr . (primitive #<procedure:cdr>)) (display . (primitive #<procedure:display>)) (car . (primitive #<procedure:car>)) (/ . (primitive #<procedure:/>)) (null? . (primitive #<procedure:null?>)) (list . (primitive #<procedure:list>)) (+ . (primitive #<procedure:+>)) (true . #t) (= . (primitive #<procedure:=>)) (- . (primitive #<procedure:->)) (> . (primitive #<procedure:>>)) (* . (primitive #<procedure:*>)) (< . (primitive #<procedure:<>)) (for-each . (procedure (proc items) ((if (null? items) (quote done) (begin (proc (car items)) (for-each proc #0#)))) #1#)))))) (items . (thunk (quote (1 2 3)) #1#))) . #1#))) (items . (thunk #0# #2#))) . #1#))
+
+eval expr (cdr items)
+
+eval expr cdr
+
+eval expr items
+
+eval's output (thunk #0=(cdr items) (#hash((proc . (thunk (lambda (x) (newline) (display x)) #1=(#hash((newline . (primitive #<procedure:newline>)) (false . #f) (cons . (primitive #<procedure:cons>)) (cdr . (primitive #<procedure:cdr>)) (display . (primitive #<procedure:display>)) (car . (primitive #<procedure:car>)) (/ . (primitive #<procedure:/>)) (null? . (primitive #<procedure:null?>)) (list . (primitive #<procedure:list>)) (+ . (primitive #<procedure:+>)) (true . #t) (= . (primitive #<procedure:=>)) (- . (primitive #<procedure:->)) (> . (primitive #<procedure:>>)) (* . (primitive #<procedure:*>)) (< . (primitive #<procedure:<>)) (for-each . (procedure (proc items) ((if (null? items) (quote done) (begin (proc (car items)) (for-each proc #0#)))) #1#)))))) (items . (thunk (quote (1 2 3)) #1#))) . #1#))
+
+eval expr (cdr items)
+
+eval expr cdr
+
+eval expr items
+
+eval's output (thunk (quote (1 2 3)) #0=(#hash((newline . (primitive #<procedure:newline>)) (false . #f) (cons . (primitive #<procedure:cons>)) (cdr . (primitive #<procedure:cdr>)) (display . (primitive #<procedure:display>)) (car . (primitive #<procedure:car>)) (/ . (primitive #<procedure:/>)) (null? . (primitive #<procedure:null?>)) (list . (primitive #<procedure:list>)) (+ . (primitive #<procedure:+>)) (true . #t) (= . (primitive #<procedure:=>)) (- . (primitive #<procedure:->)) (> . (primitive #<procedure:>>)) (* . (primitive #<procedure:*>)) (< . (primitive #<procedure:<>)) (for-each . (procedure (proc items) ((if (null? items) (quote done) (begin (proc (car items)) (for-each proc (cdr items))))) #0#)))))
+
+eval expr (quote (1 2 3))
+
+3eval expr for-each
+
+eval expr (null? items)
+
+eval expr null?
+
+eval expr items
+
+eval's output (thunk #0=(cdr items) (#hash((proc . (thunk proc #3=(#hash((proc . (thunk proc #2=(#hash((proc . (thunk (lambda (x) (newline) (display x)) #1=(#hash((newline . (primitive #<procedure:newline>)) (false . #f) (cons . (primitive #<procedure:cons>)) (cdr . (primitive #<procedure:cdr>)) (display . (primitive #<procedure:display>)) (car . (primitive #<procedure:car>)) (/ . (primitive #<procedure:/>)) (null? . (primitive #<procedure:null?>)) (list . (primitive #<procedure:list>)) (+ . (primitive #<procedure:+>)) (true . #t) (= . (primitive #<procedure:=>)) (- . (primitive #<procedure:->)) (> . (primitive #<procedure:>>)) (* . (primitive #<procedure:*>)) (< . (primitive #<procedure:<>)) (for-each . (procedure (proc items) ((if (null? items) (quote done) (begin (proc (car items)) (for-each proc #0#)))) #1#)))))) (items . (thunk (quote (1 2 3)) #1#))) . #1#))) (items . (thunk #0# #2#))) . #1#))) (items . (thunk #0# #3#))) . #1#))
+
+eval expr (cdr items)
+
+eval expr cdr
+
+eval expr items
+
+eval's output (thunk #0=(cdr items) (#hash((proc . (thunk proc #2=(#hash((proc . (thunk (lambda (x) (newline) (display x)) #1=(#hash((newline . (primitive #<procedure:newline>)) (false . #f) (cons . (primitive #<procedure:cons>)) (cdr . (primitive #<procedure:cdr>)) (display . (primitive #<procedure:display>)) (car . (primitive #<procedure:car>)) (/ . (primitive #<procedure:/>)) (null? . (primitive #<procedure:null?>)) (list . (primitive #<procedure:list>)) (+ . (primitive #<procedure:+>)) (true . #t) (= . (primitive #<procedure:=>)) (- . (primitive #<procedure:->)) (> . (primitive #<procedure:>>)) (* . (primitive #<procedure:*>)) (< . (primitive #<procedure:<>)) (for-each . (procedure (proc items) ((if (null? items) (quote done) (begin (proc (car items)) (for-each proc #0#)))) #1#)))))) (items . (thunk (quote (1 2 3)) #1#))) . #1#))) (items . (thunk #0# #2#))) . #1#))
+
+eval expr (cdr items)
+
+eval expr cdr
+
+eval expr items
+
+eval's output (thunk #0=(cdr items) (#hash((proc . (thunk (lambda (x) (newline) (display x)) #1=(#hash((newline . (primitive #<procedure:newline>)) (false . #f) (cons . (primitive #<procedure:cons>)) (cdr . (primitive #<procedure:cdr>)) (display . (primitive #<procedure:display>)) (car . (primitive #<procedure:car>)) (/ . (primitive #<procedure:/>)) (null? . (primitive #<procedure:null?>)) (list . (primitive #<procedure:list>)) (+ . (primitive #<procedure:+>)) (true . #t) (= . (primitive #<procedure:=>)) (- . (primitive #<procedure:->)) (> . (primitive #<procedure:>>)) (* . (primitive #<procedure:*>)) (< . (primitive #<procedure:<>)) (for-each . (procedure (proc items) ((if (null? items) (quote done) (begin (proc (car items)) (for-each proc #0#)))) #1#)))))) (items . (thunk (quote (1 2 3)) #1#))) . #1#))
+
+eval expr (cdr items)
+
+eval expr cdr
+
+eval expr items
+
+eval's output (thunk (quote (1 2 3)) #0=(#hash((newline . (primitive #<procedure:newline>)) (false . #f) (cons . (primitive #<procedure:cons>)) (cdr . (primitive #<procedure:cdr>)) (display . (primitive #<procedure:display>)) (car . (primitive #<procedure:car>)) (/ . (primitive #<procedure:/>)) (null? . (primitive #<procedure:null?>)) (list . (primitive #<procedure:list>)) (+ . (primitive #<procedure:+>)) (true . #t) (= . (primitive #<procedure:=>)) (- . (primitive #<procedure:->)) (> . (primitive #<procedure:>>)) (* . (primitive #<procedure:*>)) (< . (primitive #<procedure:<>)) (for-each . (procedure (proc items) ((if (null? items) (quote done) (begin (proc (car items)) (for-each proc (cdr items))))) #0#)))))
+
+eval expr (quote (1 2 3))
+
+'done
+|#
+
+;; part b
+(define env2 (make-environment))
+(eval '(define (p1 x)
+         (set! x (cons x '(2)))
+         x)
+      env2)
+(eval '(define (p2 x)
+         (define (p e)
+           e
+           x)
+         (p (set! x (cons x '(2)))))
+      env2)
+(eval '(p1 1) env2)
+(eval '(p2 1) env2)
+
+#|
+With the original evaluator, we get '(1 2) since cons is a primitive and the argument x (a thunk) of cons
+is forced, giving the value 1. The output of cons, which is '(1 2) is set as the new value of a variable x.
+x is no longer a thunk at this point. Then x is eval'ed and returned.
+
+In the second case, the argument of p2, x, is passed as a thunk. Now, the first statement, the definition
+of the function p is defined. Now, this function is called with a (set! x ... ) in the second/final statement.
+This statement is passed as a thunk (i.e. e is a thunk with expr (set! x ... )). As the first statement, e
+is evaluated. e gets looked up and a thunk is returned. But the expr of thunk e is not evaluated. Now, we lookup
+x and it is returned. x is the thunk with the expr `1'. This thunk is returned. If we don't force thunk in the 
+repl (as in my examples where I call eval directly), what is returned is a thunk. x is not modified by the 
+(set! x ...) because it is passed as thunk and has not been evaluated yet.
+
+If we modify the eval-sequence according to Cy D's suggestions, then we get '(1 2) for both the statements. This is
+because the first statement, e, gets forced, which makes the (set! x (cons x '(2))) to evaluate, creating the
+side effect (x itself is a thunk, but gets forced because cons is a primitive). 
+
+|#
+
+;; part c
+#|
+
+This is because the display function is a primitive and it forces the thunk anyway.
+
+|#
+
+;; part d
+#|
+
+I like the approach in the text.
+
+|#
\ No newline at end of file
index b41ab4bae60c3eba689ca2f9ae59341f345d8f71..5e036ee8e3f75dea131396188a6a48b6fbc5fc26 100644 (file)
@@ -97,7 +97,9 @@
         (list '/ /)
         (list '= =)
         (list '> >)
-        (list '< <)))
+        (list '< <)
+        (list 'newline newline)
+        (list 'display display)))
 
 (define (primitive-procedure-names)
   (map car primitive-procedures))
 (define (procedure-environment p) (cadddr p))
 
 (define (apply procedure arguments env)
+  ;;(display (format "~s~%" arguments))
   (match procedure
     [`(primitive ,f ...)  (apply-primitive-procedure procedure (list-of-arg-values arguments env))]
     [`(procedure ,f ...)  (eval-sequence
 
 ;; thunks
 (define (actual-value exp env)
+  ;(display (format "eval expr ~s~%" exp))
+  ;(newline)
   (force-it (eval exp env)))
 
 (define (force-it obj)
+  ;; (display (format "~s~%" obj))
   (match obj
-    [`(thunk ,exp ,env) (actual-value exp env)]
+    [`(thunk ,exp ,env) (begin
+                          ;(display (format "eval's output ~s~%" obj))
+                          ;(newline)
+                          (actual-value exp env))]
     [_ obj]))
 
 (define (delay-it exp env)