3 (require "metacircular2-lazy.rkt")
5 (define env1 (make-environment))
6 (eval '(define (for-each proc items)
9 (begin (proc (car items))
10 (for-each proc (cdr items)))))
12 (eval '(for-each (lambda(x) (newline) (display x)) '(1 2 3)) env1)
18 One can observe the execution of this routine by a small modification to the 2 procedures that constitute
19 the lazy evaluator as follows (the only change is printing of the arguments)
21 (define (actual-value exp env)
22 (display (format "eval expr ~s~%" exp))
24 (force-it (eval exp env)))
26 (define (force-it obj)
27 ;; (display (format "~s~%" obj))
29 [`(thunk ,exp ,env) (begin
30 (display (format "eval's output ~s~%" obj))
32 (actual-value exp env))]
35 As we can observe during the execution, the `begin' gets transformed to `eval-sequence'
36 and then `newline' and `(display x)' are called. Both these are primitive expressions
37 and so the arguments are forced by apply.
39 The trace of the execution of the above definition and the evaluation are listed below.
46 eval expr (null? items)
52 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#)))))
54 eval expr (quote (1 2 3))
58 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#)))))
60 eval expr (lambda (x) (newline) (display x))
69 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#))
77 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#)))))
79 eval expr (quote (1 2 3))
83 eval expr (null? items)
89 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#))
97 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#)))))
99 eval expr (quote (1 2 3))
103 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#))
107 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#)))))
109 eval expr (lambda (x) (newline) (display x))
118 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#))
120 eval expr (car items)
126 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#))
128 eval expr (cdr items)
134 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#)))))
136 eval expr (quote (1 2 3))
140 eval expr (null? items)
146 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#))
148 eval expr (cdr items)
154 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#))
156 eval expr (cdr items)
162 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#)))))
164 eval expr (quote (1 2 3))
168 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#))
172 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#))
176 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#)))))
178 eval expr (lambda (x) (newline) (display x))
187 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#))
189 eval expr (car items)
195 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#))
197 eval expr (cdr items)
203 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#))
205 eval expr (cdr items)
211 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#)))))
213 eval expr (quote (1 2 3))
217 eval expr (null? items)
223 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#))
225 eval expr (cdr items)
231 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#))
233 eval expr (cdr items)
239 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#))
241 eval expr (cdr items)
247 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#)))))
249 eval expr (quote (1 2 3))
255 (define env2 (make-environment))
256 (eval '(define (p1 x)
257 (set! x (cons x '(2)))
260 (eval '(define (p2 x)
264 (p (set! x (cons x '(2)))))
270 With the original evaluator, we get '(1 2) since cons is a primitive and the argument x (a thunk) of cons
271 is forced, giving the value 1. The output of cons, which is '(1 2) is set as the new value of a variable x.
272 x is no longer a thunk at this point. Then x is eval'ed and returned.
274 In the second case, the argument of p2, x, is passed as a thunk. Now, the first statement, the definition
275 of the function p is defined. Now, this function is called with a (set! x ... ) in the second/final statement.
276 This statement is passed as a thunk (i.e. e is a thunk with expr (set! x ... )). As the first statement, e
277 is evaluated. e gets looked up and a thunk is returned. But the expr of thunk e is not evaluated. Now, we lookup
278 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
279 repl (as in my examples where I call eval directly), what is returned is a thunk. x is not modified by the
280 (set! x ...) because it is passed as thunk and has not been evaluated yet.
282 If we modify the eval-sequence according to Cy D's suggestions, then we get '(1 2) for both the statements. This is
283 because the first statement, e, gets forced, which makes the (set! x (cons x '(2))) to evaluate, creating the
284 side effect (x itself is a thunk, but gets forced because cons is a primitive).
291 This is because the display function is a primitive and it forces the thunk anyway.
298 I like the approach in the text.