CISC-280 Program Development Techniques

Homework 8: Streams

Due: Wednesday, May 19, 2004

Problem 0 -- Printing Infinite Streams - 20 Extra Credit Points (10 for each version)

It is useful to be able to look at finite amounts of an  infinite stream to determine whether or not it is correct. Write two different versions of a print function. The function should take a stream, s, and a number, n, which is the number of elements to be printed.  It should print out the  first n elements of the stream s.  Make one version print on one line, and another print each element on a separate line.

Problem 1 - list->stream - 15 Extra Credit points

Since there is no standard printed representation of streams, there is no way to enter a quoted stream.  It would be nice to be able to pass in a literal list, and have it changed into a stream.  Define the function list->stream that takes a list and returns a stream.

Problem 2 - remove-duplicates -- 50 points

The following procedure returns a list of all the distinct symbols in a given list of symbols. That is, each symbol appears only once in the result list, no matter how many times it appeared in the argument list.

(define (remove-duplicates lst)
  (cond ((null? lst) null)
        ((not (memq (car lst) (cdr lst)))
         (cons (car lst) (remove-duplicates (cdr lst))))
        (else (remove-duplicates (cdr lst)))))

Remove-duplicates checks to see whether the car of the list is an element of the cdr of the list. If so, it ignores the car and returns the result of removing duplicates from the cdr. Otherwise it conses the car onto this result. Remove-duplicates uses the procedure memq from Section 2.3.1, which tests whether a given symbol is in a given list. Memq returns the part of the list beginning with the designated symbol, or false if the symbol is not in the list:

(define (memq item x)
  (cond ((null? x) #f)
        ((eq? item (car x)) x)
        (else (memq item (cdr x)))))

Louis Reasoner suggests that in order to make remove-duplicates work with streams instead of list, all we have to do is modify remove-duplicates and memq by changing cons to cons-stream, car to stream-car, cdr to stream-cdr, and null? to stream-null?.

Part 1 -- Explain what is wrong with Louis's suggestion.

Part 2 -- Complete the following CORRECT definition of a procedure that removes duplicates from a stream.

(define (remove-duplicates stream)
  (if (stream-null? stream)
      the-empty-stream
      (cons-stream <first-element>
                   (stream-filter <predicate> <stream-to-filter>))))
 

Problem 3 -- Infinite Stream - 25 points

Show how to use stream-filter to define the stream of all integers that are not divisible by either 2, 3, or 5.

Problem 4 -- reorder - 25 points

The procedure reorder rearranges the items in one stream (the data stream) into the order specified by another stream (the order stream), which consists of item numbers specifying the desired order. For example, if the data stream starts with 4, 13, 2, 8 and the order stream starts with 3, 1, 4, 2 then the result stream will start with 2, 4, 8, 13. (The first item of the result is the third item of the data, the second item of the result is the first item of the data, and so on.)

Complete the following definition of reorder.

; takes a stream specifying an ordering and a data stream
; creates an output stream that contains the items from the
; data stream in the order specified by the order stream
(define (reorder order-stream data-stream)
  (cond ((stream-null? order-stream) the-empty stream)
        ((stream-null? data-stream) the-empty-stream)
        (else (cons-stream  ))))

What are the first seven numbers in the stream returned by (reorder (stream-cdr fibs) (stream-cdr fibs))