Search code examples
streamschemelispsicplazy-sequences

Delayed "let" in SICP


SICP indicates cdr is opened up:

enter image description here

In section 3.5.4 , i saw this block:

(define (integral delayed-integrand initial-value dt)
 (define int
  (cons-stream initial-value
             (let ((integrand (force delayed-integrand)))
               (add-streams (scale-stream integrand dt)
                            int))))
int)

Normally if this was something like:

(define (stream-map proc s)
  (if (stream-null? s)
      the-empty-stream
      (cons-stream (proc (stream-car s))
                   (stream-map proc (stream-cdr s)))))

The stream-cdr s would be evaluated as (cons-stream (stream-car (cdr s)) delay<>) even when the actual call would be in a delay. ie even though the stream-map function itself is delayed, the arguments are pre-computed. [Is this correct? - By the applicative model, the arguments should be substituted for ,before the function is "called", but is the call evaluation when delay is forced or when it's just specified]

Then why is let not pre-computed?

What i think? I think let is a lambda function with the variable as the arguments, so it's execution is delayed

(let ((var1 e1) (var2 e2)) e3)

is same as

 Lambda (var1 var2) e3 (with var1 bound to e1 and var2 bound to e2)

Can someone please help me confirm this? Thanks


Solution

  • "the arguments are pre-computed. is this correct?"

    No. (cons-stream a (func (stream-cdr b))) is just like

    (cons-stream a    
        (lambda ()     
           ;; our code is placed here, verbatim, as a whole:
           (func (stream-cdr b))  
        )  
      )
    

    cons-stream is a macro, it just moves pieces of code around.

    The lambda might be enclosed in a memo-proc call for the memoization, to do call-by-need, but it'll still have the code we wrote, like (func (stream-cdr b)), placed inside the lambda, "textually", by cons-stream. Which is a macro, just moving pieces of code around.

    Regarding the snippet which you've added to the question, the authors were just being imprecise. What is meant there is, when (stream-cdr stream) in (stream-filter pred (stream-cdr stream)) will be called, it will produce (cons 10008 (delay .... )), as shown. Not before.

    Where it says "which in this case is" is should have said "which in this case is the same as".

    In section 3.5.1 Streams Are Delayed Lists (also PDF) the book says:

    To make the stream implementation automatically and transparently interleave the construction of a stream with its use, we will arrange for the cdr of a stream to be evaluated when it is accessed by the stream-cdr procedure rather than when the stream is constructed by cons-stream.   [emphasis mine]