reflection
play

Reflection Consider the member? function, which has the following - PowerPoint PPT Presentation

Reflection Consider the member? function, which has the following algebraic laws: (member? m ()) == #f (member? m (cons m ks)) == #t (member? m (cons k ks)) == (member? m ks), m != k This algorithm searches for an element in a list. List


  1. Reflection Consider the member? function, which has the following algebraic laws: (member? m ’()) == #f (member? m (cons m ks)) == #t (member? m (cons k ks)) == (member? m ks), m != k This algorithm searches for an element in a list. List other algorithms you are familiar with that operate over a list (or linked list, or an array) and explain briefly what they do.

  2. Predefined list algorithms Some classics: • exists? (Example: Is there a number?) • all? (Example: Is everything a number?) • filter (Example: Select only the numbers) • map (Example: Add 1 to every element) • foldr ( Visit every element; also called reduce , accum , a “catamorphism”)

  3. Defining exists? ; (exists? p? ’()) = #f ; (exists? p? (cons y ys)) = #t, if (p? y) ; (exists? p? (cons y ys)) = (exists? p? ys), otherwise -> (define exists? (p? xs) (if (null? xs) #f (if (p? (car xs)) #t (exists? p? (cdr xs))))) -> (exists? number? ’(1 2 zoo)) #t -> (exists? number? ’(apple orange)) #f

  4. Coding Interlude: exists? Define a list ys and two predicates p1? and p2? such that exists? p1? ys evaluates to #t and exists? p2? ys evalutes to #f . Run the code to confirm your answers are correct. An alternative formulation of the algebraic laws for the exists? function is: ;; (exists? p? ’() = #f ;; (exists? p? (cons x xs)) = (|| (p? x) ;; (exists? p? xs)) Modify the definition of exists? following this algebraic formulation instead, and re-run your

  5. examples.

  6. Defining filter ; (filter p? ’()) == ’() ; (filter p? (cons y ys)) == ; (cons y (filter p? ys)), when (p? y) ; (filter p? (cons y ys)) == ; (filter p? ys), when (not (p? y)) -> (define filter (p? xs) (if (null? xs) ’() (if (p? (car xs)) (cons (car xs) (filter p? (cdr xs))) (filter p? (cdr xs)))))

  7. Running filter -> (filter (lambda (n) (> n 0)) ’(1 2 -3 -4 5 6)) (1 2 5 6) -> (filter (lambda (n) (<= n 0)) ’(1 2 -3 -4 5 6)) (-3 -4)

  8. Coding Interlude: filter Use lambda to define a predicate that returns true iff the argument is a number larger than 9 . Define a list ys that contans a mix of one- and two-digit numbers. Use your lambda function and the filter function defined in the video to produce a new list zs that contains only the elements in ys with at least two-digits. Run your code. How would you modify the code to produce a list with only one-digit numbers?

  9. Your turn: map Complete the algebraic laws for the map function: -> (map add3 ’(1 2 3 4 5)) (4 5 6 7 8) ;; (map f ’()) = ;; (map f (cons y ys)) =

  10. Answers: map -> (map add3 ’(1 2 3 4 5)) (4 5 6 7 8) ; (map f ’()) == ’() ; (map f (cons y ys)) == (cons (f y) (map f ys))

  11. Defining and running map ; (map f ’()) == ’() ; (map f (cons y ys)) == (cons (f y) (map f ys)) -> (define map (f xs) (if (null? xs) ’() (cons (f (car xs)) (map f (cdr xs))))) -> (map number? ’(3 a b (5 6))) (#t #f #f #f) -> (map (lambda(x)(* x x)) ’(5 6 7)) ((25 36 49)

  12. Foldr

  13. Algebraic laws for foldr Idea: � 0 + 0 : x 1 + x n � + : + � � � (foldr (plus zero ’())) = zero (foldr (plus zero (cons y ys))) = (plus y (foldr plus zero ys)) Note: Binary operator + associates to the right. Note: zero might be identity of plus .

  14. Code for foldr Idea: � 0 + 0 : x 1 + x n � + : + � � � -> (define foldr (plus zero xs) (if (null? xs) zero (plus (car xs) (foldr plus zero (cdr xs))))) -> (val sum (lambda (xs) (foldr + 0 xs))) -> (sum ’(1 2 3 4)) 10 -> (val prod (lambda (xs) (foldr * 1 xs))) -> (prod ’(1 2 3 4)) 24

  15. Another view of operator folding ’(1 2 3 4) (cons 1 (cons 2 (cons 3 (cons 4 ’())))) = (foldr + 0 ’(1 2 3 4)) (+ 1 (+ 2 (+ 3 (+ 4 0 )))) = (foldr f z ’(1 2 3 4)) (f 1 (f 2 (f 3 (f 4 z )))) =

  16. Check your understanding: foldr What does the following code evaluate to? -> (define foldr (plus zero xs) (if (null? xs) zero (plus (car xs) (foldr plus zero (cdr xs))))) -> (define combine (x a) (+ 1 a)) -> (foldr combine 0 ’(2 3 4 1)) • 0 • 10 • 24 • 4 Answer: 4 . The plus function for this invocation of

  17. foldr is the function combine , which adds one to an accumulator a for each element x in the list. The zero function for this invocation of foldr is the literal 0 . Hence this invocation of foldr starts with 0 and adds 1 for each element in the list, returning 4 when applied to the list '(2 3 4 1) because that list has four elements. This use of foldr is one way of writing the list length function.

  18. Your turn: Explain the design 1. Functions like exists? , map , filter are subsumed by 2. Function foldr , which is subsumed by 3. Recursive functions Seems redundant: Why?

  19. Currying: The motivation Remember me? q-with-y? = (lambda (z) (q? y z)) Happens so often, there is a function for it: q-with-y? = ((curry q?) y) Called a partial application (one now, one later)

  20. Map/search/filter love curried functions -> (map ((curry +) 3) ’(1 2 3 4 5)) ; add 3 to each element -> (exists? ((curry =) 3) ’(1 2 3 4 5)) ; is there an element equal to 3? -> (filter ((curry >) 3) ’(1 2 3 4 5)) ; keep elements that 3 is greater then

  21. The idea of currying The function curry • Input: a binary function f(x,y) • Output: a function f' – Input: argument x – Output: a function f'' * Input: argument y * Output: f(x,y) What is the benefit? • Functions like exists? , all? , map , and filter expect a function of one argument. To get there, we use currying and partial application. Slogan: Curried functions take their arguments “one-at-a-time.”

  22. What’s the algebraic law for curry ? ... (curry f) ... = ... f ... Keep in mind: All you can do with a function is apply it! (((curry f) x) y) = (f x y) Three applications: so implementation will have three lambda s

  23. From law to code ;; curry : binary function -> value -> function ;; (((curry f) x) y) = (f x y) -> (val curry (lambda (f) (lambda (x) (lambda (y) (f x y))))) -> (val positive? ((curry <) 0))

  24. Check your understanding: curry What does the following code evaluate to? -> (map ((curry +) 3) ’(1 2 3 4 5)) • 15 • 18 • '(4 5 6 7 8) • '(1 2 3 3 4 5) • '(3 4 5 6 7 8) • 4 Answer: '(4 5 6 7 8) . The map function applies its argument function ((curry +) 3) to each element in the list '(1 2 3 4 5) , to produce the list '(4 5 6 7 8) .

  25. The function ((curry +) 3) is the “plus-three” function obtained by partially applying the curried + function to the constant 3 . The + function has to be curried before being applied to 3 because it otherwise takes two arguments at a time, not just one. An invariant of the map function is that it will always return a list with the same length as its argument. -> (exists? ((curry =) 3) ’(1 2 3 4 5)) • '() • #t • #f • 0

  26. Answer: #t . The exists? function applies its argument predicate ((curry =) 3) to each list element until it finds one where the predicate evalutes to true ( #t ). If it reaches the end of the list without finding such an element, it returns false ( #f ). The predicate is the “equal-three?” function, obtained by partially applying the curried equality function to the constant 3 . The equality function has to be curried before being applied to 3 because it otherwise takes two arguments at a time, not just one. -> (filter ((curry >) 3) ’(1 2 3 4 5))

  27. ; tricky • '(1 2) • '(1 2 3) • ’() • '(3 4 5) • '(4 5) Answer: '(1 2) . The filter function applies its argument predicate ((curry > ) 3) to each list element, including in the resulting list only those that evaluate to true ( #t ). The predicate is the “three-is-greater-than?” function, obtained by partially applying the curried greater-than function to the constant 3 . This

  28. question requires careful thought because a quick glance can make it seem like the code is testing whether something is greater than 3 rather than the opposite. The greater-than function has to be curried before being applied to 3 because it otherwise takes two arguments at a time, not just one.

  29. Composing Functions In math, what is the following equal to? (f o g)(x) == ??? Another algebraic law, another function: (f o g) (x) = f(g(x)) (f o g) = \x. (f (g (x)))

  30. One-argument functions compose -> (define o (f g) (lambda (x) (f (g x)))) -> (define even? (n) (= 0 (mod n 2))) -> (val odd? (o not even?)) -> (odd? 3) #t -> (odd? 4) #f

  31. Coding Interlude: compose The predicate null? returns #t iff the argument list is empty, while the function not inverts a boolean. Use the compose function ( o ) to write a predicate that tests whether a list is non-empty. Run your code on both empty and non-empty lists.

  32. Proofs about functions Function consuming A is related to proof about A • Q: How to prove two lists are equal? A: Prove they are both ’() or that they are both cons cells cons-ing equal car’s to equal cdr’s • Q: How to prove two functions equal? A: Prove that when applied to equal arguments they produce equal results.

Download Presentation
Download Policy: The content available on the website is offered to you 'AS IS' for your personal information and use only. It cannot be commercialized, licensed, or distributed on other websites without prior consent from the author. To download a presentation, simply click this link. If you encounter any difficulties during the download process, it's possible that the publisher has removed the file from their server.

Recommend


More recommend