sicp-ex-3.55



<< Previous exercise (3.54) | Index | Next exercise (3.56) >>


meteorgan

  
  
 (define (partial-sums s) 
   (cons-stream (stream-car s) 
                (add-streams (stream-cdr s) (partial-sums s)))) 

this will cause recalculation.

More specifically, "Defining streams implicitly" all use something like (define a (cons-stream first a)) if using recursion up to this exercise. Notice in this form 2 a's are the same variable.

But in the above definition, the call of (partial-sums s) inside itself will create one totally new env in the global environment and can't reuse the calculation with each other. You can check this by doing something like (trace add-streams):

 (trace add-streams) 
  
 (define (partial-sums S) 
   (cons-stream (stream-car S) (add-streams (stream-cdr S) (partial-sums S)))) 
  
 (define (test) 
   (define ps (partial-sums (list->stream (iota 5)))) 
   (stream-ref ps 2) 
   ) 
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
 ; ref 1:  
 ; (add-streams {1 ...} (cons-stream 0 (add-streams {1 ...} ...))) (**) 
 ; -> (cons-stream (map + 1 0) (stream-map + {2 ...} (**))) 
 ; ref 2 (here (**) refer to the above result but will be recalculated):  
 ; (stream-map + {2 ...} (**)) (***) 
 ; -> (cons-stream (map + 2 1) (stream-map + {3 ...} (***))) 
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;  
 (test) 
 ;; run 2 duplicate `add-streams`. 
  
 (define (partial-sums S) 
   (define res (cons-stream (stream-car S) (add-streams (stream-cdr S) res))) 
   res 
   ) 
 (test) 
 ;; only 1 `add-streams` as expected since the 2nd `add-streams` is avoided due to res having already calculated that one and can be reused. 

---

Also see http://community.schemewiki.org/?sicp-ex-3.63 as xdavidliu says in http://community.schemewiki.org/?sicp-ex-3.61.




huntzhan

  
  
 (define (partial-sums s) 
   (add-streams s (cons-stream 0 (partial-sums s)))) 
  

Mathieu Borderé

@huntzhan: nice, very elegant


lertecc

Must have self-reference to avoid recalculation:

  
 (define (partial-sums s) 
   (define ps (add-streams s (cons-stream 0 ps))) 
   ps) 
  

dekuofa1995

My solution:

  
 (define (partial-sums S) 
   (cons-stream (stream-car S) 
                (add-streams (partial-sums (stream-cdr S)) 
                             S))) 

j-minster

dekuofa1995's solution is wrong. For his, (partial-sums integers) returns 1, 3, 7, 12... correct solution should return (partial-sums integers) => 1, 3, 6, 10...

 (define (partial-sums s) 
   (cons-stream (stream-car s) 
                (add-streams (partial-sums s) 
                             (stream-cdr s))))