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