Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>If you don't want to go the macro route, you could always just abandon <code>cons-stream</code> and rewrite <code>lazy-list</code> as follows:</p> <pre><code>(define (lazy-list from) (cons from (λ() (lazy-list (+ from 1))))) </code></pre> <p>This is probably the easiest, most pragmatic solution, but it's only good for making lazy lists of incrementing numbers. You could generalize this by passing in a function that will generate successive elements of the list when called:</p> <pre><code>(define (lazy-list-gen generator) (cons (generator) (λ() (lazy-list-gen generator)))) (define (lazy-list from) (lazy-list-gen (λ() (let ((ret from)) (set! from (+ from 1)) ret)))) </code></pre> <p>This works pretty well:</p> <pre><code>&gt; (define x (lazy-list 1)) &gt; (car-stream x) 1 &gt; (car-stream (cdr-stream x)) 2 </code></pre> <p>But there's a bug in the code:</p> <pre><code>... continuing from above ... &gt; (car-stream (cdr-stream x)) 3 </code></pre> <p>This error happens because the call to <code>cdr-stream</code> calls <code>generator</code> again. We can solve this by caching the return value of the lambda:</p> <pre><code>(define (lazy-list-gen generator) (cons (generator) (let ((gen-cache #f)) (λ() (cond ((not gen-cache) (set! gen-cache (lazy-list-gen generator)))) gen-cache)))) </code></pre> <p>Now it works as it should:</p> <pre><code>&gt; (define x (lazy-list 1)) &gt; (car-stream x) 1 &gt; (car-stream (cdr-stream x)) 2 &gt; (car-stream (cdr-stream x)) 2 &gt; (car-stream (cdr-stream (cdr-stream x))) 3 &gt; (car-stream (cdr-stream x)) 2 </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload