Making Scheme Lazier

Chapter: Making Scheme Lazier

Now we're going to add just one special form to Scheme so that we will be able to work in Scheme with infinite lists such as we met in the previous chapter. At this stage, we are going to stop calling them "infinite lists" and instead use the term "streams". This more accurately reflects the true significance of streams in programming: They are used to model streams of data such as those emanating from a keyboard or being sent to a video or printing device. There are clear applications of this week's lab work in the area of data communications.

Recall that

(define billgates (cons "dollar" billgates))
failed because Scheme wants to evaluate that second argument to cons. By surrounding that second argument with a (lambda () ...) we can prevent its evaluation:
(define billgates (cons "dollar" (lambda () billgates)))
Now Scheme is happy. With the understanding that if we ever need the cdr of the stream billgates we will need to apply it to no arguments, we now have a way to represent streams in Scheme.

But always surrounding the second argument to a cons with a (lambda () ...), and always having to apply it when we need the cdr is inconvenient. We will define two new forms cons$ and cdr$ to enable us to work with streams. For consistency of syntax, we will also define car$, which will be exactly the same as car. We will then have a suite of forms car$, cdr$, cons$ which will allow us to work with streams, just as we already know how to work with lists using the three forms car, cdr, cons.

Q. 7
Can cons$ be a function?


Q. 8
So what can we do?


The file streams.ss contains the basic code for setting up streams. In addition to car$, cdr$ and cons$, we've also implemented the following.

Notice how easy it is to program with streams as compared to lists. For a start, you can forget about "The First Commandment": Always ask null? as the first question in expressing any function.

Q. 9
Why can you forget about the First Commandment?


I have created some sample streams that you may find useful for testing stream functions that you write. You can find the code to create these in somestreams.ss


Exercise 1

Write the functions Here is a transcript showing how your functions should work:
> (load "somestreams.ss")
> (print$ (rember-all 5 (randoms 10)))
0 7 3 1 6 2 2 1 1 4 
Want more? y
8 3 3 1 0 0 8 4 1 9 
Want more? y
6 4 0 2 9 2 8 8 0 4 
Want more? y
3 8 0 4 9 3 7 3 8 7 
Want more? n
done
> (print$ (rember-all #\e (random-chars)))
#\i #\k #\n #\i #\y #\j #\n #\a #\s #\m 
Want more? y
#\z #\y #\z #\h #\y #\z #\y #\d #\y #\g 
Want more? y
#\u #\i #\a #\a #\c #\n #\f #\f #\r #\s 
Want more? y
#\w #\i #\z #\d #\a #\j #\r #\c #\f #\j 
Want more? y
#\n #\u #\q #\f #\m #\q #\c #\k #\o #\a 
Want more? n
done
> (print$ (rember-all 'e (keyboard-stream)))
? a
a ? b
b ? c
c ? d
d ? e
? f
f ? g
g ? a
a ? b
b ? c
c ? d
d ? e
? f

Want more? n
done
> (print$ (subst-all #\e 'the-letter-e (random-chars)))
#\v #\p #\b #\f #\l #\u #\h #\l #\t #\v 
Want more? y
#\d #\l #\p #\j #\q #\a #\i #\i #\n #\l 
Want more? y
#\j #\w the-letter-e #\f #\m #\r #\o #\l #\f #\d 
Want more? y
#\g #\i #\b #\n #\i #\p #\l #\l #\c #\q 
Want more? y
#\l #\l #\u #\f #\l #\b #\u #\c #\u #\o 
Want more? y
#\h #\x #\k #\f #\f the-letter-e #\i the-letter-e #\p #\a 
Want more? n
done
> (print$ (subst-all 'e 'I-hate-the-letter-e (keyboard-stream)))
? a
a ? b
b ? c
c ? d
d ? e
I-hate-the-letter-e ? f
f ? g
g ? h
h ? i
i ? j
j ? k

Want more? n
done
> 



rhyspj@gwu.edu