SICP Study

6A Streams, Part 1

Part 1

Recap

Motivation

(define (sum-odd-squares tree)
  (if (leaf-node? tree)
      (if (odd? tree)
          (square tree)
          0)
      (+ (sum-odd-squares (left-branch tree))
         (sum-odd-squares (right-branch tree)))))
(define (odd-fibs n)
  (define (next k)
    (if (> k n)
        '()
        (let ((f (fib k)))
          (if (odd? f)
              (cons f (next (1+ k)))
              (next (1+ k))))))
  (next 1))
Highlights

Going back to this fundamental principle of computer science that in order to control something, you need the name of it. Abelson

Defining streams

(define (map-stream proc s)
  (if (empty-stream? s)
      the-empty-stream
      (cons-stream (proc (head s))
                   (map-stream proc (tail se)))))

Using the language

(define (sum-odd-squares tree)
  (accumulate +
              0
              (map square
                   (filter odd
                           (enumerate-tree tree)))))
(define (odd-fibs n)
  (accumulate cons
              '()
              (filter odd
                      (map fib
                           (enumerate-interval 1 n)))))

Part 2

More complicated stream processing

(define (prime-sum-pairs n)
  (map
   (lambda (p)
     (list (car p) (cadr p) (+ (car p) (cadr p))))
   (filter
    (lambda (p)
      (prime (+ (car p) (cadr p))))
    (flatmap
     (lambda (i)
       (map
        (lambda (j) (list i j))
        (enumerate-interval 1 (-1+ i))))
     (enumerate-interval 1 n)))))
(define (prime-sum-pairs n)
  (collect
   (list i j (+ i j))
   ((i (enumerate-interval 1 n))
    (j (enumerate-interval 1 (-1+ i))))
   (prime? (+ i j))))

Eight queens puzzle

(define (queens size)
  (define (fill-cols k)
    (if (= k 0)
        (singleton empty-board)
        (collect (adjoin-position try-row k rest-queens)
                 ((rest-queens (fill-cols (-1+ k)))
                  (try-row (enumerate-interval 1 size)))
                 (safe? try-row k rest-queens))))
  (fill-cols size))

Part 3

Streams are not lists

Implementing streams

(define (memo-proc proc)
  (let ((already-run? nil) (result nil))
    (lambda ()
      (if (not already-run?)
          (sequence (set! result (proc))
                    (set! already-run? (not nil))
                    result)
          result))))