If you do not want to follow the macro route, you can always simply abandon cons-stream and rewrite lazy-list as follows:
(define (lazy-list from) (cons from (λ() (lazy-list (+ from 1)))))
This is perhaps the simplest, most pragmatic solution, but it is only useful for creating lazy lists of increasing numbers. You can generalize this by passing a function that will generate sequential list items when called:
(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))))
This works very well:
> (define x (lazy-list 1)) > (car-stream x) 1 > (car-stream (cdr-stream x)) 2
But there is an error in the code:
... continuing from above ... > (car-stream (cdr-stream x)) 3
This error occurs because calling cdr-stream calls generator again. We can solve this by caching the return value of lambda:
(define (lazy-list-gen generator) (cons (generator) (let ((gen-cache #f)) (λ() (cond ((not gen-cache) (set! gen-cache (lazy-list-gen generator)))) gen-cache))))
Now it works as it should:
> (define x (lazy-list 1)) > (car-stream x) 1 > (car-stream (cdr-stream x)) 2 > (car-stream (cdr-stream x)) 2 > (car-stream (cdr-stream (cdr-stream x))) 3 > (car-stream (cdr-stream x)) 2
source share