Download presentation
Presentation is loading. Please wait.
1
Streams Sections 3.5.1,3.5.2 Pages 316-334
Lecture 16 Streams Sections 3.5.1,3.5.2 Pages
2
delay and force (delay <exp>) ==> a promise to evaluate exp
(force <delayed object>) ==> evaluate the delayed object and return the result (define x (delay (+ 1 1))) x #<promise> (force x) 2 (delay <exp>) is a special form. force is not a special form.
3
What are these mysterious delay and force ?
delay is a special form such that (delay <exp>) is equivalent to (lambda () <exp>) force is a procedure that calls a procedure produced by delay: (define (force delayed-object) (delayed-object))
4
(define x (delay (+ 1 1))) | GE
p: b: (+ 1 1) (force x) | GE (x) | GE 2
5
Streams interface Constructors: the-empty-stream (cons-stream x y)
Selectors: (stream-car (cons-stream x y)) = x (stream-cdr (cons-stream x y)) = y Method: (stream-null? x) cons-stream treats its second argument as a delayed object.
6
Streams via delay and force
(cons-stream <a> <b>) is a special form equivalent to (cons <a> (delay <b>)) (define (stream-car stream) (car stream)) (define (stream-cdr stream) (force (cdr stream)))
7
Let us recall lists (define (enumerate-interval low high)
(if (> low high) ‘() (cons low (enumerate-interval (+ low 1) high)))) (define int123 (enumerate-interval 1 3)) (enumerate-interval 1 3) (cons 1 (enumerate-interval 2 3)) (cons 1 (cons 2 (enumerate-interval 3 3))) (cons 1 (cons 2 (cons 3 enumerate-interval 4 3))) (cons 1 (cons 2 (cons 3 ‘())))
8
Enumerating with streams
(define (stream-enumerate-interval low high) (if (> low high) the-empty-stream (cons-stream low (stream-enumerate-interval (+ low 1) high)))) (define s (stream-enumerate-interval 1 3)) (stream-enumerate-interval 1 3) (cons-stream 1 (stream-enumerate-interval 2 3)) (cons 1 (delay (stream-enumerate-interval 2 3))) (cons 1 (lambda () (stream-enumerate-interval 2 3)))
9
(define s (stream-enumerate-interval 1 3)) | GE
low 1 high 3 p:low high b: (if (> low high) the-empty-stream (cons-stream . . . ) p: b: (stream-enumerate_interval 2 3) (cons-stream 1 (stream-enumerate-interval 2 3)) | E1 (cons 1 (lambda () (stream-enumerate-interval 2 3)) | E1
10
Calling stream-cdr (define s1 (stream-cdr s)) (stream-cdr s)
(stream-cdr (cons 1 (lambda () (str-enu-int 2 3)))) (force (cdr (cons 1 (lambda () (str-enu-int 2 3))))) (force (lambda () (str-enu-int 2 3))) ((lambda () (str-enu-int 2 3))) (str-enu-int 2 3) (cons-stream 2 (str-enu-int 3 3)) (cons 2 (delay (str-enu-int 3 3))) (cons 2 (lambda () (str-enu-int 3 3)))
11
(define s1 (stream-cdr s)) | GE (force (cdr s)) | GE
str-enu-int: GE s1: s: low 2 high 3 E1 low 1 high 3 p:low high b: (if (> low high) the-empty-stream (cons-stream . . . ) 1 p: b:(str-enu-int 2 3) 2
12
Normal (Lazy) order evaluation?
Apply operator with unevaluated argument sub-expressions. Evaluate a sub-expression only when value is needed to print by primitive procedure (that is, primitive procedures are "strict" in their arguments) Streams are like lists in Normal order evaluation. Well, almost. The car is not delayed.
13
stream-ref, stream-map
(define (stream-ref s n) (if (= n 0) (stream-car s) (stream-ref (stream-cdr s) (- n 1)))) (define (stream-map proc s) (if (stream-null? s) the-empty-stream (cons-stream (proc (stream-car s)) (stream-map proc (stream-cdr s))))
14
Stream-filter (define (stream-filter pred stream)
(cond ((stream-null? stream) the-empty-stream) ((pred (stream-car stream)) (cons-stream (stream-car stream) (stream-filter pred (stream-cdr stream)))) (else (stream-filter pred (stream-cdr stream)))))
15
Applicative vs. Normal order evaluation.
(car (cdr (filter prime? (enu-int )))) (stream-car (stream-cdr (stream-filter prime?(str-enu-int )))) Both return the second prime larger than 10 (which is 13) With lists it takes about operations With streams about three.
16
How does it work? - I (stream-car (stream-car (stream-cdr
(stream-filter prime? (str-enu-int )))) (stream-car (stream-cdr (stream-filter prime? (cons 10 (delay (str-enu-int )))))) (stream-car (stream-cdr (stream-filter prime? (force (str-enu-int ))))) (stream-car (stream-cdr (stream-filter prime? (cons 11 (delay (str-enu-int ))))))
17
How does it work? - II (stream-car (stream-cdr (cons 11 (delay
(stream-filter prime? (stream-cdr (cons 11 (delay (str-enu-int ))))))))) (stream-car (stream-filter prime? (stream-cdr (cons 11 (delay (str-enu-int )))))) (stream-car (stream-filter prime? (str-enu-int )))
18
How does it work? - III (stream-car (stream-filter prime?
(cons 12 (delay str-enu-int )))) (stream-car (stream-filter prime? (str-enu-int ))) (stream-car (stream-filter prime? (cons 13 (delay str-enu-int )))) (stream-car (cons 13 (delay (stream-filter prime? (stream-cdr (cons 13 (delay str-enu-int ))))))) 13
19
Normal order evaluation does not go well with mutators.
Consider: (set! a 4) (set! b (delay (+ 1 a))) (set! a 0) (force b) The value of a delayed operation depends on the actual time it is called, And this can be very confusing. Scheme does not use Normal order evaluation, except for streams, delay and force.
20
Forcing a delayed object many times
Suppose we have the following scenario: (define x (delay (very-hard-function a))) (force x) We need to call the hard function twice. Scheme will automatically detect that this is the second time we try to evaluate the funtion and use the value we have evaluated before. Scheme makes it look like: (define x (delay (very-hard-function a))) (define b (force x)) b
21
Beware: counter intuitive feature
(define a 1) (define x (delay a)) (set! a 2) (force x) (set! a 3) The result is 2 (rather than 3)
22
How is it done? We redefine delay as follows
(delay <exp>) translates to (memo-proc (lambda () <exp>)) (define (memo-proc proc) (let ((already-run? false) (result false)) (lambda () (if (not already-run?) (begin (set! result (proc)) (set! already-run? true) result) result))))
23
already-run: #f result: #f
(define a 1) | GE (define x (delay a)) | GE (define x (memo-proc (lambda () a))) | GE GE p:proc b:(let .. (lambda () (if (not already-run?)… Memo_proc: x: a:1 proc: p: b:a already-run: #f result: #f p: b:(if (not already-run …
24
already-run: #f result: #f
(set! a 2) | GE 2 (set! a 3) | GE 3 (force x) | GE #t 2 (force x) | GE GE p:proc b:(lambda () (if (not already-run?)… Memo_proc: x: a:1 proc: already-run: #f result: #f p: b:a p: b:(if (not already-run …
25
Infinite streams – Defining all integers.
(define (integers-from n) (cons-stream n (integers-from (+ n 1)))) (define integers (integers-from 1))
26
Defining all integers not divisible by 7
(define (divisible? x y) (= (remainder x y) 0)) (define no-sevens (stream-filter (lambda (x) (not (divisible? x 7))) integers)) (stream-ref no-sevens 100) 117
27
Infinite streams – Fibonachi sequence
(define (fib-seq-from a b) (cons-stream a (fib-seq-from b (+ a b)))) (define fib-seq (fib-seq-from 0 1))
28
What will happen with.. (stream-filter odd?
(stream-filter even? integers)) stream-filter odd? Will keep asking for elements from stream-filter even? And it will run for ever. (stream-null? (stream-filter odd? (stream-filter even? integers))) stream-filter odd? Will keep asking for elements from stream-filter even? And it will run for ever. Stream-filter odd? Will never call stream-cons.
29
The sieve for finding all the primes.
XX 5 100 99 98 97 96 95 94 93 92 91 90 89 88 87 86 85 84 83 82 81 80 79 78 77 76 75 74 73 72 71 60 69 68 67 66 65 64 63 62 61 59 58 57 56 55 54 53 52 51 50 49 48 47 46 45 44 43 42 41 40 39 38 37 36 35 34 33 32 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 XX X 3 XX 7 XX X 2
30
Implementing it with streams.
(define (sieve seq) (cons-stream (stream-car seq) (sieve (stream-filter (lambda (x) (not (divisible? x (stream-car str)))) (stream-cdr str))))) (define primes (sieve (stream-cdr integers)))
31
Does it work? (sieve (2 [3 4 . . . ] ))
(2 [sieve (stream-filter /2 (3 [ ] ))] ) Suppose we ask for the next element: (sieve (stream-filter /2 (3 [ ] ))) (sieve (3 [stream-filter /2 (4 [ ] ) ] )) (3 [sieve (stream-filter /3 (stream-filter /2 (4 [ ]) ) ) ]) And asking for the next one: (sieve (5 [stream-filter /3 [stream-filter /2 (6 [ ])] ])) (5 [sieve (s-f /5 (s-f /3 (s-r /2 (6 [ ]) ) ) ])
Similar presentations
© 2024 SlidePlayer.com. Inc.
All rights reserved.