Commit 571a86f5 authored by James R. Wilcox's avatar James R. Wilcox
Browse files

L21 code

parent de334d44
; a thunk is a function of zero arguments whose only purpose is to delay evaluation
(define (my-if-fixed branch then-thunk else-thunk)
(if branch (then-thunk) (else-thunk)))
(my-if-fixed true (lambda () 0) (lambda () some-var-doesn't-exist))
; a stream is a thunk that returns a pair (say it with me)
; - first element of pair is first element of the stream
; - second element of the pair is another stream
;
; not quite equivalent to this because of recursion! (variable bindings are not recursive (today))
; (define zeros
; (lambda ()
;
(define (zeros)
; this one is equivalent!
; (cons 0 zeros))
(cons 0 (lambda () (zeros))))
(define first-pair (zeros))
(define first-element (car first-pair))
(define all-but-the-first-element (cdr first-pair))
(define second-pair (all-but-the-first-element))
(define second-element (car second-pair))
(define all-but-the-first-two-elements (cdr second-pair))
(define third-pair (all-but-the-first-two-elements))
(define third-element (car third-pair))
; return a list of the first n elements of the stream
(define (first-n-elements n stream)
(if (= n 0)
nil
(let ((pair (stream)))
(cons (car pair)
(first-n-elements (- n 1) (cdr pair))))))
(first-n-elements 10 zeros)
(define (all-natural-numbers-starting-at k)
(cons k (lambda () (all-natural-numbers-starting-at (+ k 1)))))
; return the infinite sequence 0, 1, 2, ...
(define (all-natural-numbers)
(all-natural-numbers-starting-at 0))
(first-n-elements 10 all-natural-numbers)
(all-natural-numbers-starting-at 0)
; this call evaluates the body of all-natural-numbers-starting-at in the environment:
; [k -> 0]
; (cons k (lambda () (all-natural-numbers-starting-at (+ k 1))))
; (cons 0 <closure whose code is the lambda, and with defining environment [k -> 0]>)
(define pair (all-natural-numbers-starting-at 0))
; ((cdr pair))
(define rest (cdr pair)) ; [rest -> <closure whose code is the lambda,
; and with defining environment [k -> 0]>]
(rest)
; to call a closure, extend defining enviroment with arguments values, then eval body
; so, evaluate
; (all-natural-numbers-starting-at (+ k 1))
; in the environment [k -> 0]
; -> evaluate the body all-natural-numbers-starting-at in its defining environment extended with k -> 1
; -> evaluate (cons k (lambda () (all-natural-numbers-starting-at (+ k 1))))
; in the environment [k -> 1]
; which returns (cons 1 <closure with the lambda code and defenv = [k -> 1]>)
; tour of hall of fame functions on lists
; - map
; - filter
; - fold_left
;
; which of these might make sense on infinite sequences (streams)
; - example of an operation that wouldn't work well: summing all elements
; - map works great: just apply the function to elements of the stream
; - because we can make it return a stream
(define (stream-map f stream)
(lambda ()
(let ((pair (stream)))
(cons (f (car pair)) ; first element of output stream
(stream-map f (cdr pair)))))) ; rest of elements
; should return the stream 1, 2, 3, ...
(define incremented-natural-numbers (stream-map (lambda (n) (+ n 1)) all-natural-numbers))
(first-n-elements 10 incremented-natural-numbers)
; filter
; - doesn't work if there are only finitely many elements of input stream that satisfy predicate
; - (for example: zero elements!)
(define (stream-filter predicate stream)
(let ((pair (stream)))
(if (predicate (car pair))
(lambda ()
(cons (car pair)
(stream-filter predicate (cdr pair))))
(stream-filter predicate (cdr pair)))))
(stream-filter (lambda (x) (= x 17)) all-natural-numbers)
(define empty-stream??? (stream-filter (lambda (x) false) all-natural-numbers))
(empty-stream???)
; (first-n-elements 10 (stream-filter (lambda (x) true) all-natural-numbers))
; fold_left
; - on lists, takes a initial accumulator and a "step function" and iterates the step function
; using elements of the list. at the end, returns final accumulator.
;
; - doesn't make sense on streams!
(define (slow-id n x)
(if (= n 0)
x
(slow-id (- n 1) x)))
(slow-id 10 'hello)
(define (slow-add a b)
(+ (slow-id 10000000 a) b))
(slow-add 2 3)
(define (my-mult a b-thunk)
(match a
(0 0)
(1 (b-thunk))
(_ (+ (b-thunk) (slow-mult (- a 1) b-thunk)))))
(my-mult 0 (lambda () (slow-add 3 4)))
(my-mult 1 (lambda () (slow-add 3 4)))
(my-mult 2 (lambda () (slow-add 3 4)))
(my-mult 0 (let ((n (slow-add 3 4))) (lambda () n)))
(my-mult 1 (let ((n (slow-add 3 4))) (lambda () n)))
(my-mult 2 (let ((n (slow-add 3 4))) (lambda () n)))
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment