Foundations of Programming Paradigms | 2000 |
10 Modularity, Objects and State |
10.1 Introduction |
10.2 Assignment and Local State |
(define balance 100)
(define (make-simplified-withdraw balance)
10.3 Streams |
|
|
objects with local state | computational objects with local variables |
time variation | time variation in computer |
time variation of state | assignment |
What about (car (cdr (filter-prime? (enumerate-interval 10000 1000000))))?
This expression finds second prime but at what cost?
10.4 Stream Approach |
(define (stream-null? stream )
(null? stream))
10.5 Stream Implementation |
(define (force delayed-object)
(delayed-object)
(define (stream-car stream ) (car stream))
(define (stream-cdr stream) (force (cdr stream)))
(define (stream-enumerate-interval low high)
(if (> low high)
the-empty-stream
(cons-stream low (stream-enumerate-interval (+ low 1) high))))
Therefore (stream-enumerate-interval 10000 1000000)
=>
(cons 10000 (delay (stream-enumerate-interval 10001 1000000)))
If
(define (stream-filter predicate stream)
(cond ((stream-null? stream)
the-empty-stream)
((predicate (stream-car stream))
(cons-stream (stream-car stream)
(stream-filter predicate (stream-cdr stream))))
(else (stream-filter predicate (stream-cdr stream)))))
Then the call to stream-cdr on the delayed object
(cons 10000 (delay (stream-enumerate-interval 10001 1000000))) returns
the delayed object
(cons 10001 (delay (stream-enumerate-interval 10002 1000000)))
Problem, in some situation you may repeatedly evaluate
the same delayed object which is inefficient since you will always return
the same result
Solution is to cache result after first evaluation and
return it
(define (memory-procedure procedure)
(let ((already-run? #f)
(result #f))
(lambda()
(if (not already-run?)
(begin
(set! result (procedure)
(set! already-run? #t)
result)
result))))
and then Special Form (delay <exp>) is made equivalent
to
(memory-procedure (lambda () <exp>))
10.6 Infinite Streams |
(define integers (integers-starting-from 1))
(define no-sevens (stream-filter
(lambda (x) (not (divisible? x 7))) integers))
(stream-ref no-sevens 100) => 117
(define fibs (fib-generator 0 1))
(define (average x y ) (/ (+ x y) 2))
(define (sqrt-stream x)
(define guesses (cons-stream
1.0
(stream-map (lambda (guess) (sqrt-improve guess x) guesses)))
guesses)
(display-stream (sqrt-stream 2))
1.0
1.5
1.4166666
….