Re: some suggestions Matthias Neubauer 13 Feb 2003 17:26 UTC

Phil Bewig <xxxxxx@swbell.net> writes:

> On Wednesday, February 12, 2003 10:17 AM, Richard Kelsey [SMTP:xxxxxx@s48.org] wrote:
> >    Everyone who has seen a preliminary draft of this SRFI had the same
> >    comment that it should be split into "essential" and "library" pieces,
> >    but all had different ideas of where to make the split.
> >
> > I don't care too much about where the split happens as long as the
> > core part isn't too big.  A dozen or so procedures and macros should
> > be enough to be useful while not being overwhelming.
>
> Certainly NULL, CONS, CAR, CDR, NULL?, PAIR? and LAMBDA must be
> in the core, since they all necessarily touch the underlying representation of
> streams.  You probably want STREAM to build finite streams and ITERATE
> to build infinite streams, and REF to access items other than the first.
> MAP, FOR-EACH, FILTER and FOLD-LEFT are useful in their own right and
> also as building blocks for numerous other functions.  That's fourteen.  Does
> that make a useful core?

To my mind, the most intrinsic stream abstraction ever is still
missing in this srfi: UNFOLDR. UNFOLDR is for streams, what FOLDR is
for lists. Whereas it is a highly common task to consume a list to a
single value using a consumer function---typically done by using
FOLDR---, the common pattern for streams is generating a stream
starting from an initial seed value using a generator function.

And that's what UNFOLDR is all about!

So I vote for putting UNFOLDR in the core srfi:
(Be warned: the following code is completely untested und unoptimized!)

;; stream-unfold : (b -> (union (cons a b) #f)) b -> stream(a)
(stream-define (stream-unfold gen-fun seed)
   (let ((res (gen-fun seed)))
     (if res
         (stream-cons (car res)
                      (stream-unfold gen-fun (cdr res)))
         stream-null)))

Other stream generators are then easily defined using unfold, as e.g.

(define (stream-from n)
  (stream-unfold (lambda (s) (cons s (+ s 1)))
                 n))

(define (stream-from-to n m)
  (stream-unfold (lambda (s) (and (<= s m) (cons s (+ s 1))))
                 n))

(define (stream-iterate f a)
  (stream-unfold (lambda (s) (cons s (f s)))
                 a))

(define (list->stream l)
  (stream-unfold (lambda (l) (and (not (null? l)) l))
		 l))

...

Cheers

Matthias

--
Matthias Neubauer                                       |
Universität Freiburg, Institut für Informatik           | tel +49 761 203 8060
Georges-Köhler-Allee 79, 79110 Freiburg i. Br., Germany | fax +49 761 203 8052