sicp-ex-4.30



<< Previous exercise (4.29) | Index | Next exercise (4.31) >>


meteorgan

  
  
 ;; a 
 In begin expression, every expression will be evaluated using eval, and display is primitive function, it will call force-it to get x. 
  
 ;; b 
 original eval-sequence: 
 (p1 1) => (1 . 2) 
 (p2 1) => 1  . because (set! x (cons x '(2))) will be delayed, in function p, when evaluating it, it's a thunk. 
  
 Cy's eval-sequence: 
 (p1 1) => (1 . 2) 
 (p2 1) => (1 . 2). thunk (set! x (cons x '(2))) will be forced to evaluate. 
  
 ;; c 
 when using actual-value, it will call (force-it p), if p is a normal value, force-it will return p, just as never call actual-value 
  
 ;; d 
 I like Cy's method. 
  
 ;; d 
 I prefer the original style. In my opinion (and this is an opinion question), a normal order interpreter should ONLY force a thunk that is needed. Since only the final value of the sequence is used (returned) the others are not needed and should not be forced. This is for consistency. 

For d, I feel like the answer to this question hinges on whether this claim is true:

    All items in a sequence except for the last one are only there 
    for the side effects they produce.

This seems like it should be true, because it's easy to see that the value of an expression in non-final position in a sequence is discarded. If this is true, then I think we must prefer Cy's method, as the only sane reason for inclusion of a non-final sequence item would be for its side-effects.


b.

`(p2 1)` returns a thunk, which is a loop containing the current environment.

d.

I prefer evaluating a variable when it is referenced. I think everytime a variable is referenced, it's value is needed.

 ((variable? exp) 
   (force-it (lookup-variable-value exp env)))