source: project/wiki/stream-ext @ 8533

Last change on this file since 8533 was 8533, checked in by azul, 13 years ago

tweaks

File size: 29.5 KB
Line 
1[[toc:]]
2[[tags:eggs streams]]
3
4== Introduction
5
6The stream-ext egg provides many convenient extensions to work with [[srfi:40]] streams.
7
8== Author
9
10This egg is made by [[http://azul.freaks-unidos.net/|Alejandro Forero Cuervo]] <azul@freaks-unidos.net>.
11
12== Requires
13
14* [[srfi-40]]
15* [[format-modular]]
16
17== License
18
19The stream-ext egg for Chicken Scheme is in the public domain and may be reproduced or copied without
20permission from its author.  Citation of the source is appreciated.
21
22== Constructors
23
24<procedure name="stream-xcons" args="a b" returns="stream">
25Of utility only as a value to be conveniently passed to higher-order procedures.
26
27<examples>
28<expr>(stream-xcons (stream 'b 'c) 'a)</expr>
29<result>#<stream (a b c)></result>
30<expr>(stream-xcons (stream 2 3 4) 1)</expr>
31<result>#<stream 1 2 3 4></result>
32</examples>
33
34The name stands for "eXchanged CONS."
35</procedure>
36
37<procedure name="stream-cons*" returns="stream" args="a b">
38
39Like {{stream}}, but the last argument
40provides the tail of the constructed stream, returning:
41
42<enscript highlight=scheme>(stream-cons elt1 (stream-cons elt2 (stream-cons ... eltn)))</enscript>
43
44<examples>
45<expr>(stream-cons* 1 2 3 (stream 4))</expr>
46<result>#<stream (1 2 3 4)></result>
47<expr>(stream-cons* (stream 4))</expr>
48<result>#<stream (4)></result>
49</examples>
50
51</procedure>
52
53=== make-stream
54
55 [procedure] (make-stream n [fill])
56
57Returns an {{n}}-element stream, whose elements
58are all the value {{fill}}.
59If the {{fill}} argument is not given,
60the elements of the stream may be arbitrary values.
61
62<enscript highlight=scheme>(make-stream 4 'c)
63=> <stream (c c c c)></enscript>
64
65=== stream-tabulate
66
67 [procedure] (stream-tabulate n init-proc)
68
69Returns an {{n}}-element list.
70Element {{i}} of the list, where 0 <= {{i}} < {{n}},
71is produced by {{(init-proc i)}}.
72
73<enscript highlight=scheme>(stream-tabulate 4 identity)
74=> #<stream (0 1 2 3)></enscript>
75
76=== stream-iota
77
78 [procedure] (stream-iota a b)
79
80Returns a list containing the elements:
81
82<enscript highlight=scheme>(start start+step ... start+(count-1)*step)</enscript>
83
84The {{start}} and {{step}} parameters default
85to {{0}} and {{1}}, respectively.
86This procedure takes its name from the APL primitive.
87
88<enscript highlight=scheme>(stream-iota 5)
89=> #<stream (0 1 2 3 4)>
90(stream-iota 5 0 -0.1)
91=> #<stream (0 -0.1 -0.2 -0.3 -0.4)></enscript>
92
93=== stream-format
94
95 [procedure] (stream-format fmt ...)
96
97Does the same as {{(format #f fmt ...)}},
98but returns the result as a stream of characters rather than a string.
99
100=== stream-lines
101
102 [procedure] (stream-lines str)
103
104Returns a stream with the lines found in the stream of
105characters {{str}}.  Each line is itself returned
106as a stream of characters.  It is an error if {{str}} contains
107elements that are not characters.
108
109<enscript highlight=scheme>(stream-lines (stream #\h #\e #\y #\newline #\y #\o #\u))
110=> #<stream (#<stream (#\h #\e #\y)> #<stream (#\y #\o #\u)>)></enscript>
111
112== Conversion
113
114=== stream->list
115
116 [procedure] (stream->list str)
117
118Returns a list with the elements in stream {{str}}.
119It is an error to pass an infinite stream.
120
121=== list->stream
122
123 [procedure] (list->stream list)
124
125Returns a stream with the elements in list {{list}}.
126The list might be circular (infinite), in which case the resulting
127stream will be infinite as well.
128
129=== stream->string
130
131 [procedure] (stream->string str)
132
133Returns a string with its characters read from
134the stream {{str}}.
135It is an error if {{str}} does not end or if it
136has elements than are not characters.
137
138This function is the inverse of {{string->stream}}.
139
140=== string->stream
141
142 [procedure] (string->stream str)
143
144Returns a finite stream with the characters
145in the string {{str}}.
146
147This function is the inverse of {{stream->string}}.
148
149=== number->stream
150
151 [procedure] (number->stream str)
152
153...
154
155=== stream->number
156
157 [procedure] (stream->number str)
158
159...
160
161=== port->stream
162
163 [procedure] (port->stream [in [reader [close-at-eof]]])
164
165Returns a stream with the contents of the input port {{in}},
166which defaults to the current input port.
167
168{{reader}} is a procedure.  When called, it should read
169and return one element from the port passed as its only argument, advancing the
170read pointer (or return the eof object when no more elements
171are available in the port).  The default value is {{read-char}},
172which results in a stream of characters, but {{read}} and
173{{read-line}} can also be specified.
174
175TODO: Documment close-at-eof.
176
177=== iterator->stream
178
179 [procedure] (iterator->stream proc)
180
181Turns an iterator into a stream.  {{proc}} should be
182a procedure of two arguments.  The first is a one-argument
183procedure that collects objects (adds them to an enumeration)
184and the second is a procedure of no arguments that can be used
185to stop iteration prematurely.
186
187{{iterator->stream}} returns a stream.  The
188iterator {{proc}} is only allowed to run as objects
189are read from the stream (with {{stream-car}} or
190{{stream-cdr}}).
191
192Example:
193
194<enscript highlight=scheme>(define (list->stream alist)
195  (iterator->stream
196    (lambda (collect stop)
197      (for-each collect alist))))</enscript>
198
199== Input and output
200
201=== with-output-to-stream
202
203 [procedure] (with-output-to-stream proc)
204
205Returns a stream of characters, which is built by calling
206{{proc}}, a procedure of no arguments, with its output
207port bound to a custom port.  As characters are read from the
208stream (by {{stream-car}} or {{stream-cdr}}),
209{{proc}} is allowed to execute until
210it writes as many characters as required.  For example,
211if the stream returned is immediately discarded, {{proc}}
212will not called at all.
213
214<enscript highlight=scheme>(with-output-to-stream
215  (lambda ()
216    (format #t "Hey!~%")))
217=> #<stream (#\H #\e #\y #\! #\newline)></enscript>
218
219Remember that {{proc}} is only executed gradually,
220as the values from the stream are required.  As a consequence,
221certain problems could arise by uncareful use of non-reentrant
222functions.
223
224=== write-stream
225
226 [procedure] (write-stream stream [port [writer]])
227
228Write all the elements in the stream {{stream}} to the output port {{port}},
229which defaults to the current output port.
230If the stream is infinite, this function does not return.
231
232{{writer}} is the procedure used to write individual
233elements to the port.  It should receive the element to be written
234and the output port as its only arguments.  The default value is {{write-char}}
235but {{write}} and {{write-line}} can also be used (depending
236on the contents of {{stream}}).
237
238== Predicates
239
240=== stream=
241
242 [procedure] (stream= elt= str1 ...)
243
244Determines stream equality, given an element-equality procedure.
245Stream {{A}} equals stream {{B}} if they are of the
246same length, and their corresponding elements are equal, as determined
247by {{elt=}}.
248If the element-comparison procedure's first argument is from stri,
249then its second argument is from stri+1, i.e. it is always called
250as {{(elt= a b)}} for {{a}} an element of stream {{A}},
251and {{b}} an element of stream {{B}}.
252
253In the n-ary case, every {{stri}} is compared to {{stri+1}}
254(as opposed, for example, to comparing {{str1}} to every {{stri}},
255for {{i}} > 1).
256If there are no list arguments at all, {{stream=}} simply returns true.
257
258The dynamic order in which the {{elt=}} procedure is applied to pairs of
259elements is not specified. For example, if {{stream=}} is applied to three lists,
260{{A}}, {{B}},
261and {{C}}, it may first completely compare
262{{A}} to {{B}},
263then compare {{B}} to {{C}}, or it may
264compare the first elements of {{A}} and {{B}},
265then the first elements of {{B}} and {{C}},
266then the second elements of {{A}} and {{B}}, and so forth.
267
268The equality procedure must be consistent with {{eq?}}.
269That is, it must be the case that:
270
271<enscript highlight=scheme>(eq? x y) => (elt= x y)</enscript>
272
273This implies that two lists which are {{eq?}} are always {{stream=}}
274as well; implementations may exploit this fact to "short-cut" the element-by-element comparisons.
275
276<enscript highlight=scheme>(stream= eq?)
277=> #t       ; Trivial cases
278(stream= eq? (stream 0 1 2))
279=> #t</enscript>
280
281=== stream-prefix=
282
283 [procedure] (stream-prefix= str prefix [=])
284
285Evaluates whether the elements at the beginning of stream
286{{str}} are equal to the elements in the list
287{{prefix}}.
288
289{{eq}} is the function used to compare the individual elements.
290The default is {{equal?}}.
291
292If the prefix of the stream matches {{prefix}}, the
293function returns the contents of {{stream}} following
294it.  False is returned otherwise.
295
296<enscript highlight=scheme>(stream-prefix= (stream 1 2 3 4) '(1 2))
297=> #<stream (3 4)>
298(stream-prefix= (stream 1 2 3 4) '(1 3))
299=> #f</enscript>
300
301== Selectors
302
303=== stream-caar ... stream-cddddr
304
305 [procedure] (stream-caar pair)
306 [procedure] (stream-cadr pair)
307 :
308 [procedure] (stream-cdddar pair)
309 [procedure] (stream-cddddr pair)
310
311These procedures are compositions of
312{{stream-car}} and {{stream-cdr}},
313where for example {{stream-caddr}} could be defined by:
314
315<enscript highlight=scheme>(define (stream-caddr x) (stream-car (stream-cdr (stream-cdr x))))</enscript>
316
317Arbitrary compositions, up to four deep, are provided.
318There are twenty-eight of these procedures in all.
319
320=== stream-ref
321
322 [procedure] (stream-ref str pos)
323
324Returns the element in the stream {{str}} at the
325position {{pos}}.  This is the same as the stream-car
326of {{(stream-drop str pos)}}. It is an error if
327{{str}} has {{pos}} or fewer elements.
328
329<enscript highlight=scheme>(stream-ref (stream 0 1 2 3 4 5) 3)
330=> 3</enscript>
331
332=== stream-first ... stream-tenth
333
334 [procedure] (stream-first str)
335 [procedure] (stream-second str)
336 :
337 [procedure] (stream-ninth str)
338 [procedure] (stream-tenth str)
339
340Synonyms for {{(stream-car str)}},
341{{(stream-cadr str)}}, {{(stream-caddr str)}}, ...
342
343<enscript highlight=scheme>(stream-third (stream 0 1 2 3 4))
344=> 2</enscript>
345
346=== stream-take
347
348 [procedure] (stream-take str count)
349
350Returns a stream with the first {{count}} elements
351in stream {{str}}.  It is an error if {{str}}
352has fewer than {{count}} elements.
353
354<enscript highlight=scheme>(stream-take (stream 1 2 3 4 5) 2)
355=> #<stream (1 2)></enscript>
356
357=== stream-drop
358
359 [procedure] (stream-drop str count)
360
361Returns the sub-stream of {{str}} obtained by omitting
362the first {{count}} elements. It is an error if list has
363fewer than {{count}} elements.
364
365<enscript highlight=scheme>(stream-drop (stream 0 1 2 3 4 5) 3)
366=> #<stream (3 4 5)></enscript>
367
368=== stream-intersperse
369
370 [procedure] (stream-intersperse stream element)
371
372Returns a new stream with the elements in the stream {{stream}}
373but placing {{element}} between each.
374
375<enscript highlight=scheme>(stream-intersperse (stream 0 1 2 3) #f)
376=> #<stream (0 #f 1 #f 2 #f 3)>
377(stream-intersperse (stream 0) 1)
378=> #<stream (0)></enscript>
379
380=== stream-split
381
382 [procedure] (stream-split str pred)
383
384Splits the stream {{str}} into multiple streams, removing
385the elements satisfying predicate {{pred}}.
386This is similar to what {{string-split}} does
387but operates on streams (rather than strings) and returns the result
388as a stream of streams (rather than a list of strings).
389
390Example:
391
392<enscript highlight=scheme>(stream-split (stream 1 2 3 5 7 8 9 10) even?)
393=> #<stream (#<stream (1)> #<stream (3 5 7)> #<stream (9)>)></enscript>
394
395=== stream-last
396
397 [procedure] (stream-last str)
398
399Returns the last element of the non-empty finite stream {{str}}.
400It is an error to pass an empty stream.
401
402<enscript highlight=scheme>(stream-last (stream 'a 'b 'c))
403=> c</enscript>
404
405{{stream-last}} can be defined as:
406
407<enscript highlight=scheme>(define (stream-last stream)
408  (stream-car (stream-last-n stream 1)))</enscript>
409
410=== stream-last-n
411
412[procedure] (stream-last-n stream count)
413
414Returns a stream with the last {{count}}
415elements of the finite stream {{str}}.  If fewer
416than {{count}} elements are available in {{stream}},
417{{stream}} itself is returned.
418
419<enscript highlight=scheme>(stream-null? (stream-last-n (stream #\a #\b #\c #\d) 0))
420=> #t
421(stream-last-n (stream #\a #\b #\c #\d) 1)
422=> #<stream (#\d)>
423(stream-last-n (stream #\a #\b #\c #\d) 3)
424=> #<stream (#\b #\c #\d)>
425(stream-last-n (stream #\a #\b #\c #\d) 20)
426=> #<stream (#\a #\b #\c #\d)></enscript>
427
428=== stream-butlast
429
430 [procedure] (stream-butlast stream)
431
432Returns a stream with all the elements in the
433non-empty stream {{str}} except the last.
434The order of the elements is respected.
435
436<enscript highlight=scheme>(stream-butlast (stream #\a #\b #\c))
437=> #<stream (#\a #\b)></enscript>
438
439{{stream-butlast}} can be defined as:
440
441<enscript highlight=scheme>(define (stream-butlast stream)
442  (stream-car (stream-butlast-n stream 1)))</enscript>
443
444=== stream-butlast-n
445
446 [procedure] (stream-butlast-n stream count)
447
448Returns a stream with all the elements in the
449stream {{stream}} except the last
450{{count}}.  The order of the elements is
451respected.  It is an error if {{stream}}
452has fewer than {{count}} elements.
453
454<enscript highlight=scheme>(stream-butlast-n (stream #\a #\b #\c) 2)
455=> #<stream (#\a)>
456(stream-null? (stream-butlast-n (stream #\a #\b #\c) 3))
457=> #t</enscript>
458
459== Miscellaneous: length, append, concatenate, reverse, zip & count
460
461=== stream-length
462
463 [procedure] (stream-length str)
464
465Returns the length of the argument stream (a non-negative integer n such that
466stream-cdr applied n times to the stream produces the null stream).
467
468This function does not return when {{str}} is an
469infinite streams.
470
471Returns the length of the stream {{str}}.
472This call does not return if {{str}} is an
473infinite stream.
474
475<enscript highlight=scheme>(stream-length (stream 0 1 2 3))
476=> 4</enscript>
477
478=== stream-length>=
479
480 [procedure] (stream-length>= str len)
481
482Returns {{#t}} if the length of the stream {{str}}
483is greater or equal than {{len}}, {{#f}} otherwise.
484
485For finite streams, this is equivalent, albeit faster, to:
486
487<enscript highlight=scheme>(>= (stream-length str) len)</enscript>
488
489However, for infinite streams it is equivalent to {{#t}}
490(whereas the above code would never terminate).
491
492=== stream-append
493
494 [procedure] (stream-append str1 str2 ...)
495
496{{stream-append}} returns a stream consisting of the elements of str1
497followed by the elements of the other stream parameters.
498
499<enscript highlight=scheme>(stream-append (stream 1) (stream 2))
500=> #<stream (1 2)>
501(stream-append (stream 1) (stream 2 3 4))
502=> #<stream (1 2 3 4)>
503(stream-append (stream 'a '(b)) (stream '(c)))
504=> #<stream (a (b) (c))></enscript>
505
506=== stream-concatenate
507
508 [procedure] (stream-concatenate str)
509
510...
511
512=== stream-reverse
513
514 [procedure] (stream-reverse str)
515
516{{stream-reverse}}
517returns a stream consisting of the elements of
518the stream {{str}} in reverse order.
519
520This procedure does not return if {{str}} is an infinite
521stream.
522
523<enscript highlight=scheme>(stream-reverse (stream 1 2 3))
524=> #<stream (3 2 1)>
525(stream-reverse (stream 'a '(b c) 'd '(e (f))))
526=> #<stream ((e (f)) d (b c) a)></enscript>
527
528=== stream-append-reverse
529
530 [procedure] (stream-append-reverse rev-head tail)
531
532{{stream-append-reverse}} returns
533{{(stream-append (stream-reverse rev-head) tail)}}.
534It is
535provided because it is a common operation -- a common list-processing style
536calls for this exact operation to transfer values accumulated in reverse order
537onto the front of another list, and because the implementation is significantly
538more efficient than the simple composition it replaces.
539
540This procedure does not return if {{rev-head}} is an infinite stream.
541
542=== stream-count
543
544 [procedure] (stream-count pred str1 str2 ...)
545
546{{pred}} is a procedure taking as many arguments as there are streams and
547returning a single value. It is applied element-wise to the elements of the
548streams, and a count is tallied of the number of elements that produce a true
549value. This count is returned. count is "iterative" in that it is guaranteed to
550apply {{pred}} to the stream elements in a left-to-right order. The counting stops
551when the shortest list expires.
552
553If all the streams are infinite, this procedure does not return.
554
555<enscript highlight=scheme>(stream-count even? (stream 3 1 4 1 5 9 2 5 6))
556=> 3
557(stream-count < (stream 1 2 4 8) (stream 2 4 6 8 10 12 14 16))
558=> 3
559(stream-count < (stream 3 1 4 1) (make-stream #t 2))
560=> 2</enscript>
561
562== Filtering & Partitioning
563
564=== stream-partition
565
566 [procedure] (stream-partition pred str)
567
568Partitions the elements of stream {{str}} with predicate
569{{pred}}, and returns two values: the stream of in-elements
570and the stream of out-elements.
571The stream is not disordered -- elements occur in the result streams
572in the same order as they occur in the argument stream.
573
574The dynamic order in which the various applications of {{pred}}
575depends on the evaluation of the streams.  {{pred}} might be evaluated
576twice for each element in the argument stream.
577
578<enscript highlight=scheme>(stream-partition symbol? (stream 'one 2 3 'four 'five 6))
579=>
580   #<stream (one four five)>
581   #<stream (2 3 6)></enscript>
582
583=== stream-remove
584
585 [procedure] (stream-remove pred str)
586
587Returns a stream with all the elements in the stream {{str}}
588except those that satisfy predicate pred:
589
590<enscript highlight=scheme>(lambda (pred str) (stream-filter (lambda (x) (not (pred x))) str))</enscript>
591
592The stream is not disordered -- elements that appear in the result list
593occur in the same order as they occur in the argument list.
594
595<enscript highlight=scheme>(stream-remove even? (stream 0 7 8 8 43 -4))
596=> #<stream (7 43)></enscript>
597
598== Searching
599
600=== stream-find
601
602 [procedure] (stream-find pred str)
603
604Return the first element of the stream {{str}}
605that satisfies predicate {{pred}};
606false if no element does.
607
608<enscript highlight=scheme>(stream-find even? (stream 3 1 4 1 5 9))
609=> 4</enscript>
610
611Note that {{stream-find}} has an ambiguity in
612its lookup semantics -- if find returns {{#f}},
613you cannot tell (in general) if it found a {{#f}} element that
614satisfied {{pred}}, or if it did not find any element at all.
615In many situations, this ambiguity cannot arise -- either the list
616being searched is known not to contain any {{#f}} elements, or the
617list is guaranteed to have an element satisfying {{pred}}.
618However, in cases where this ambiguity can arise, you should use
619{{stream-find-tail}} instead of {{stream-find}}
620-- {{stream-find-tail}} has no such ambiguity:
621
622<enscript highlight=scheme>(cond ((stream-find-tail pred lis) => (lambda (pair) ...)) ; Handle (CAR PAIR)
623      (else ...)) ; Search failed.</enscript>
624
625=== stream-find-tail
626
627 [procedure] (stream-find-tail pred str)
628
629Returns the first stream-pair of {{str}}
630whose car satisfies predicate {{pred}}.
631If no pair does, returns false.
632
633<enscript highlight=scheme>(stream-find-tail even? (stream 3 1 37 -8 -5 0 0))
634=> #<stream (-8 -5 0 0)>
635(stream-find-tail even? (stream 3 1 37 -5))
636=> #f</enscript>
637
638{{stream-find-tail}} can be viewed as a general-predicate
639variant of the {{stream-member}} function.  {{stream-member}}
640can be defined as a call to stream-find-tail:
641
642<enscript highlight=scheme>;; (stream-member x str):
643(stream-find-tail (lambda (elt) (equal? x elt)) str)</enscript>
644
645Find-tail is essentially stream-drop-while, where the sense of the
646predicate is inverted: Find-tail searches until it finds an element
647satisfying the predicate; drop-while searches until it finds an
648element that doesn't satisfy the predicate.
649
650=== stream-take-while
651
652 [procedure] (stream-take-while pred str)
653
654Returns the longest initial prefix of stream {{str}}
655whose elements all satisfy the predicate {{pred}}.
656
657<enscript highlight=scheme>(stream-take-while even? (stream 2 18 3 10 22 9))
658=> #<stream (2 18)></enscript>
659
660=== stream-drop-while
661
662 [procedure] (stream-drop-while pred str)
663
664Drops the longest initial prefix of stream {{str}} whose
665elements all satisfy the predicate {{pred}} and returns
666the rest of the stream.
667
668<enscript highlight=scheme>(stream-drop-while even? (stream 2 18 3 10 22 9))
669=> #<stream (3 10 22 9)></enscript>
670
671=== stream-span, stream-break
672
673 [procedure] (stream-span pred str)
674 [procedure] (stream-break pred str)
675
676{{stream-span}} splits the stream {{str}} into the longest
677initial prefix whose elements all satisfy predicate {{pred}}, and the
678remaining tail.  {{stream-break}} inverts the sense of the predicate:
679the tail commences with the first element of the input list that satisfies the
680predicate.
681
682In other words: {{stream-span}} finds the intial span of elements
683satisfying {{pred}}, and {{stream-break}} breaks the list at
684the first element not satisfying {{pred}}.
685
686stream-span is equivalent to:
687
688<enscript highlight=scheme>(values (stream-take-while pred str) (stream-drop-while pred str))</enscript>
689
690Examples:
691
692<enscript highlight=scheme>(stream-span even? (stream 2 18 3 10 22 9))
693=>
694  #<stream (2 18)>
695  #<stream (3 10 22 9)>
696(stream-break even? (stream 3 1 4 1 5 9))
697=>
698  #<stream (3 1)>
699  #<stream (4 1 5 9)></enscript>
700
701=== stream-any
702
703 [procedure] (stream-any pred str1 str2 ...)
704
705Applies the predicate {{pred}}
706across the streams {{str1 ... strn}},
707returning true if the predicate returns true on any application.
708
709If there are {{n}} stream arguments
710{{str1 ... strn}}, then {{pred}}
711must be a procedure taking {{n}} arguments
712and returning a boolean result.
713
714{{stream-any}} applies {{pred}} to the first
715elements of the {{stri}} parameters.
716If this application returns a true value, {{stream-any}}
717immediately returns that value. Otherwise, it iterates, applying
718{{pred}} to the second elements of the {{stri}}
719parameters, then the third, and so forth. The iteration stops when
720a true value is produced or one of the streams runs out of values;
721in the latter case, {{stream-any}} returns #f.
722
723Just like with {{any}} (see SRFI-1), it would be desirable
724to make the last call to {{pred}} a tail call.  However,
725this would force {{stream-any}} to evaluate streams in
726advance.  For this reason, the last call to {{pred}} is
727not a tail call.
728
729Note the difference between {{stream-find}}
730and {{stream-any}} -- {{stream-find}} returns the element that
731satisfied the predicate; {{stream-any}} returns the true value that the
732predicate produced.
733
734Like {{stream-every}}, {{stream-any}}'s name
735does not end with a question mark -- this is to indicate that it
736does not return a simple boolean ({{#t}} or {{#f}}),
737but a general value.
738
739<enscript highlight=scheme>(stream-any integer? (stream 'a 3 'b 2.7))
740=> #t
741(stream-any integer? (stream 'a 3.1 'b 2.7))
742=> #f
743(stream-any < (stream 3 1 4 1 5) (stream 2 7 1 8 2))
744=> #t</enscript>
745
746=== stream-every
747
748 [procedure] (stream-every pred str1 str2 ...)
749
750Applies the predicate across the streams,
751returning true if the predicate returns true on every application.
752
753If there are {{n}} stream arguments
754{{str1 ... strn}}, then {{pred}} must be a procedure
755taking {{n}} arguments and returning a boolean result.
756
757{{stream-every}} applies {{pred}} to the first
758elements of the {{stri}} parameters. If this application
759returns false, {{stream-every}} immediately returns false.
760Otherwise, it iterates, applying {{pred}} to the second
761elements of the {{stri}} parameters, then the third, and
762so forth. The iteration stops when a false value is produced or one
763of the lists runs out of values. In the latter case, every returns
764the true value produced by its final application of pred.
765
766Just like with {{every}} (see SRFI-1), it would be desirable
767to make the last call to {{pred}} a tail call.  However,
768this would force {{stream-every}} to evaluate streams in
769advance.  For this reason, the last call to {{pred}} is
770not a tail call.
771
772If one of the {{stri}}
773has no elements, every simply returns #t.
774
775Like {{stream-any}}, {{stream-every}}'s
776name does not end with a question mark -- this is to indicate
777that it does not return a simple boolean (#t or #f), but a general value.
778
779=== stream-index
780
781 [procedure] (stream-index pred str1 str2 ...)
782
783Return the index of the leftmost elements in the
784streams that satisfies predicate {{pred}}.
785
786If there are {{n}} list arguments {{str1 ... strn}},
787then {{pred}} must be a function taking {{n}} arguments
788and returning a boolean result.
789
790stream-index applies {{pred}} to the first elements of the
791{{stri}} parameters. If this application returns true,
792{{stream-index}} immediately returns zero. Otherwise, it
793iterates, applying {{pred}} to the second elements of the
794{{stri}} parameters, then the third, and so forth. When it
795finds a tuple of list elements that cause {{pred}} to
796return true, it stops and returns the zero-based index of that
797position in the lists.
798
799The iteration stops when one of the lists runs out of values;
800in this case, {{stream-index}} returns {{#f}}.
801
802<enscript highlight=scheme>(stream-index even? (stream 3 1 4 1 5 9))
803=> 2
804(stream-index < (stream 3 1 4 1 5 9 2 5 6) (stream 2 7 1 8 2))
805=> 1
806(stream-index = (stream 3 1 4 1 5 9 2 5 6) (stream 2 7 1 8 2))
807=> #f</enscript>
808
809=== stream-member, stream-memq, stream-memv
810
811 [procedure] (stream-member x str [=])
812 [procedure] (stream-memq x str)
813 [procedure] (stream-memv x str)
814
815These procedures return the first substream of the
816stream {{str}}
817returned by {{(drop str i)}} for {{i}} less
818than the length of {{str}} whose stream-car is
819{{x}}.  If x does not occur in {{str}},
820then either #f is returned (for finite streams) or this
821call does not return.  {{stream-memq}} uses {{eq?}}
822to compare x with the elements of {{str}},
823while {{stream-memv}} uses {{eqv?}},
824and stream-member uses {{equal?}}.
825
826<enscript highlight=scheme>(stream-memq 'a (stream 'a 'b 'c))
827=> (a b c)
828(stream-memq 'b (stream 'a 'b 'c))
829=> (b c)
830(stream-memq 'a (stream 'b 'c 'd))
831=> #f
832(stream-memq (list 'a) (stream 'b '(a) 'c))
833=> #f
834(stream-member (list 'a) (stream 'b '(a) 'c))
835=> ((a) c)
836(stream-memq 101 (stream 100 101 102))
837=> *unspecified*
838(stream-memv 101 (stream 100 101 102))
839=> (101 102)</enscript>
840
841stream-member allows the client to pass in an optional equality procedure {{=}}
842used to compare elements.
843
844The comparison procedure is used to compare the elements {{ei}}
845of {{str}} to the element {{x}} in this way:
846
847<enscript highlight=scheme>(= x ei) ; str is (E1 ...)</enscript>
848
849That is, the first argument is always {{x}},
850and the second argument is one of the list elements.
851Thus one can reliably find the first element of {{str}} that
852is greater than five with {{(stream-member 5 list <)}}.
853
854Note that fully general list searching may be performed with
855the stream-find-tail and stream-find procedures, e.g.
856
857<enscript highlight=scheme>; Find the first pair with an even stream-car:
858(stream-find-tail even? str)</enscript>
859
860== Strings as streams
861
862=== stream-downcase
863
864 [procedure] (stream-downcase str)
865
866Returns a stream identical to the stream of characters {{str}} but
867with all characters converted to lowercase.
868
869=== stream-upcase
870
871 [procedure] (stream-upcase str)
872
873Returns a stream identical to the stream of characters {{str}} but
874with all characters converted to uppercase.
875
876== Deletion
877
878=== stream-delete
879
880 [procedure] (stream-delete x str [=])
881
882{{stream-delete}} returns a stream identical to {{str}}
883but removing all occurences of the element {{x}}.  The comparison
884procedure {{=}}, which defaults to {{equal?}}, is used to
885find them.
886
887The stream is not disordered -- elements that appear in the result stream
888occur in the same order as they occur in the argument stream.
889
890Note that fully general element deletion can be performed with the stream-remove procedure, e.g.:
891
892<enscript highlight=scheme>;; Delete all the even elements from STR:
893(stream-remove even? str)</enscript>
894
895The comparison procedure is used in this way: {{(= x ei)}}. That
896is, {{x}} is always the first argument, and a element from the stream
897is always the second argument.  Thus, one can reliably remove all the numbers
898greater than five from a stream with {{(delete 5 stream <)}}.
899
900=== stream-delete-duplicates
901
902 [procedure] (stream-delete-duplicates str [=])
903
904{{stream-delete-duplicates}} removes duplicate elements from the
905{{str}} stream argument.  If there are multiple equal elements in the
906argument stream, the result stream only contains the first or leftmost of these
907elements in the result. The order of these surviving elements is the same as in
908the original stream -- {{stream-delete-duplicates}} does not disorder
909the stream.
910
911The {{=}} parameter is used to compare the elements of the list; it
912defaults to {{equal?}}. If {{x}} comes before {{y}}
913in list, then the comparison is performed {{(= x y)}}.  The comparison
914procedure will be used to compare each pair of elements in list no more than
915once; the order in which it is applied to the various pairs is not
916specified.
917
918Be aware that, in general, {{stream-delete-duplicates}} runs in time O(n2) for
919n-streams lists. Uniquifying long lists can be accomplished in O(n lg n) time
920by sorting the stream to bring equal elements together, then using a linear-time
921algorithm to remove equal elements. Alternatively, one can use algorithms based
922on element-marking, with linear-time results.
923
924Also note that a list might be kept in memory with the entire contents
925of the stream during the execution of calls to this function.
926
927<enscript highlight=scheme>(stream-delete-duplicates (stream 0 1 0 3 0 1 3 4))
928=> #<stream (0 1 3 4)></enscript>
929
930== Version History
931
932;1.4.1: Small bug fix in {{stream-fold-right}}.
933;1.4 : Add {{stream-downcase}}, {{stream-upcase}}, {{vector->stream}}, {{stream->vector}}, {{stream-sort}}, {{stream-unlines}}, {{stream<}}, {{stream>}}, {{make-infinite-stream}}, {{stream-fold}}, {{stream-fold-right}} and {{stream-fold-right-delay}}.  Made {{make-stream}} and {{stream-tabulate}} receive an optional {{tail}} argument.  Many bug fixes.
934;1.3.1: Replaced use of {{(end-of-file)}} with {{#!eof}}
935;1.3 (r2136) : Made {{stream-reverse}} accept an optional parameter: the end of the list.  Made all parameters to {{stream->port}} optional (the port now defaults to the current input port).  Fixed {{stream-every}}.  Added {{stream->symbol}}, {{symbol->stream}}, {{stream-drop-safe}} and {{stream-take-safe}}.
936;1.2 (r1122) : Added {{list->stream}}, {{number->stream}}, {{stream->number}}, {{stream-intersperse}}, {{stream-last-n}}, {{stream-butlast}}, {{stream-butlast-n}}, {{iterator->stream}}, {{call-with-output-stream}} and {{call-with-input-stream}}; and fixed {{stream-delete-duplicates}}, {{stream-find}} and {{stream-find-tail}}.
937;1.1 : Removed {{stream-filter}} (it's provided by srfi-40).
938;1.0 : First public release.
Note: See TracBrowser for help on using the repository browser.