8

Can anyone help me better understand how to write a stream?

I understand that a stream is an infinite sequence of values and the way I have learned programming them is a representing them as a thunk that when called produces a pair of (1) the first element in the sequence and (2) a thunk that represents the stream for the second-through-infinity elements

For example:

(define powers-of-two
    (letrec ([f (lambda (x) (cons x (lambda () (f (* x 2)))))])
        (lambda () (f 2))))

I understand here that it is just producing a powers of two and to access these for example calling (car (powers-of-two)) would result in 2 and calling (car ((cdr (powers-of-two)))) would result in 4

Now I am trying to write a stream called red-blue that alternates between strings red and blue but I am a little confused about how to construct it

kfem
  • 189
  • 3
  • 11
  • so you've done it, congrats! Check out the Scheme section in http://c2.com/cgi/wiki?SieveOfEratosthenesInManyProgrammingLanguages for a working example of SICP-styled streams. There is only one macro rule there, you can apply it manually throughout. – Will Ness Oct 27 '12 at 09:35

4 Answers4

14

It looks like you were asking how to build your own custom streams with thunks, which others have already answered. Just in case, it's worth noting that Racket has a stream library built-in and most Racketeers would use that for streams.

Here's an example:

#lang racket
(require racket/stream)
(define reds (stream-cons "red" reds))
(define red-blues (stream-add-between reds "blue"))

;; show ten of them
(for ([i 10] [e (in-stream red-blues)])
  (displayln e))
Asumu Takikawa
  • 8,447
  • 1
  • 28
  • 43
6

For a general understanding of streams in Scheme, I'd recommend section §3.5 Streams in the SICP book. It'll teach you the basic concepts to solve stream-related problems such as the one in the question.

Regarding the problem in the question, here's the general idea to solve it:

  • Build two infinite streams, one producing only the string "red" and the other "blue"
  • Combine both streams taking one element from one and then one element from the other (alternating), this procedure is called interleave in SICP
Óscar López
  • 232,561
  • 37
  • 312
  • 386
6

I wrote SRFI-41 which describes streams, provides an implementation, and gives many examples. The streams there differ from those in SICP, and are "better" in a way explained in the SRFI.

user448810
  • 17,381
  • 4
  • 34
  • 59
1

I am a newbie at this but the following solutions seems to work as well:

 (define red-then-blue
   (letrec ([f (lambda (x) (cons x(lambda ()(f(cond [(string=? x "red") "blue"]
                                              ["red"])))))])
   (lambda () (f "red"))))
Komal Waseem
  • 1,089
  • 3
  • 17
  • 24