Hello. I'm stuck with a lazy stream implementation in scheme, maybe
someone can help me?
Here are my base definitions (partially stolen from SICP):
(define-macro (stream-cons p q)
(let
((pv (gensym)) (qv (gensym)))
`(let
((,pv (lambda () ,p)) (,qv (lambda () ,q)))
(lambda (f) (f ,pv ,qv)))))
(define stream-car
(lambda (s) (s (lambda (p q) (p)))))
(define stream-cdr
(lambda (s) (s (lambda (p q) (q)))))
(define stream-for-each
(lambda (func stream)
(if (null? stream)
'done
(begin
(func (stream-car stream))
(stream-for-each func (stream-cdr stream))))))
The following stream "ones" work pretty fine:
(define ones (stream-cons 1 ones))
"stream-for-each" across such list can run infinitely. But when I try to
define something more complex, it works also, but consumes memory. For
example:
(define stream-map
(lambda (func . streams)
(if (or
(null? streams)
(< 0
(apply +
(map (lambda (s) (if (null? s) 1 0)) streams))))
'()
(stream-cons
(apply func (map stream-car streams))
(apply
stream-map
(cons func (map stream-cdr streams)))))))
(define nums (stream-cons 1 (stream-map + ones nums)))
or even
(define number-stream
(lambda (number) (stream-cons number (number-stream number))))
The "stream-for-each" procedure across such streams fails on some big
iteration count, complaining "Exhausted storage" for Pocket Scheme or
even with crash on signal 11 for qscheme.
Is it bug of GC, algorithm or maybe my brain?