120 likes | 195 Views
Abstraction. Lab 3 Karl Lieberherr. Abstractions in Scheme for traversing and processing data. lists map: same function applied to all elements records explicitly enumerate relevant elements Example: BusRoute example (Lab 1) (define (proc-towns towns) (map proc-town towns))
E N D
Abstraction Lab 3 Karl Lieberherr
Abstractions in Scheme for traversing and processing data • lists • map: same function applied to all elements • records • explicitly enumerate relevant elements • Example: BusRoute example (Lab 1) • (define (proc-towns towns) (map proc-town towns)) • (define (proc-town town) (proc-busStops(Town-busStops town)))
Abstractions in Scheme for traversing and processing data unions: explicitly enumerate relevant alternatives in cond clause. ;; capacity checking example (define (weight-item l) (cond [(Simple? l) (Simple-weight l)] [(Container? l) (weight-container l)]))
compacting information: variants of map • (andmap p alox) • determine whether p holds for every item on alox • (ormap p alox) • determine whether p holds for at least one item on alox
Compacting information with fold • (foldr + 0 (map weight-item l)) (Capacity checking example) • Two versions: foldr and foldl • Very flexible because compacting function is a parameter (+ above)
Container capacity example (define-struct Container (contents capacity)) (define-struct Simple (name weight))
A more interesting use of map and fold (define (check ac) (wv-violations ((make-Container-Visitor (lambda (name weight) (make-wv weight 0)) (lambda (wvs capacity) (let* ((totals (foldr (lambda (wv1 wv2) (make-wv (+ (wv-weight wv1) (wv-weight wv2)) (+ (wv-violations wv1) (wv-violations wv2)))) (make-wv 0 0) wvs)) (total-weight (wv-weight totals)) (total-violations (wv-violations totals))) (make-wv total-weight (if (> total-weight capacity) (+ 1 total-violations) total-violations))))) ac)))
Functional Visitor: does traversal (define (make-Container-Visitor simple-visitor container-visitor) (define (visitor c) (cond ((Simple? c) (simple-visitor (Simple-name c) (Simple-weight c))) ((Container? c) (container-visitor (map visitor (Container-contents c)) (Container-capacity c))) (else ???))) visitor)
filter ;; filter : (X -> boolean) (listof X) -> (listof X) (eliminate-expensive u toys) Question: does it make sense to generalize filter to any kind of Scheme structure? • consider a container c • filter-struct : (X -> boolean) (structure containing X) -> (structure containing X)
Exercise: filter • Design a dir structure (HTDP 224 -226) and filter out all files whose size is greater than 100. • Choose a structure that minimizes conditionals.
apply: from help desk procedure: (apply proc arg1 ... args) proc must be a procedure and args must be a list. Calls proc with the elements of the list (append (list arg1 ...) args) as the actual arguments. (apply + (list 3 4)) ===> 7 (define compose (lambda (f g) (lambda args (f (apply g args))))) ((compose sqrt *) 12 75) ===> 30
Exercise: apply and eliminate lambda (define compose (lambda (f g) (lambda args (f (apply g args))))) (define (compose2 f g) (lambda args (f (apply g args)))) (define (compose3 f g) (local (define (myf args) (f (apply g args)))) myf)) ((compose sqrt *) 12 75) ((compose2 sqrt *) 12 75) ((compose3 sqrt *) '(12 75)) How can we write compose3 without requiring the ‘?