Download presentation
Presentation is loading. Please wait.
Published byDortha Bruce Modified over 9 years ago
1
TeachScheme, ReachJava Adelphi University Thursday morning July 15, 2010
2
Lists of structs An employee-list is either empty, or (cons employee employee-list) An employee is… See employees.scm as starting point Since an emp-list has a part which is an emp, function-on-emp-list calls function-on-emp on that part
3
Lists of structs Write total-salary which takes in a list of employees & adds up their salaries Write any-over-100k? which takes in a list of employees & tells whether any of them earn over $100,000/year Write count-over-100k which takes in a list of employees & tells how many of them earn over $100,000/year Write give-10%-raises which takes in a list of employees & returns a similar list in which everybody's salary has increased by 10% Write fire-over-100k which takes in a list of employees & returns a list of the ones who don't earn over $100,000/year. Write highest-paid, which takes in a non-empty list of employees & returns the highest-paid one. (If there's a tie, return the first of the highest-paid employees.)
4
Lists of unions An animal-list is either empty, or (cons animal animal-list) An animal is either a dog, or a fish A dog is… A fish is… See animals.scm as a starting point Since a list of animals has a part which is an animal, function-on- animal-list calls function-on-animal (which in turn calls function-on-dog, function-on-fish, etc.)
5
Lists of unions Write count-tigers, which takes in a list of animals and returns how many of them are tigers Write extract-fish, which takes in a list of animals and returns a list of only the fish, in the same order they were in before Write lookup-age, which takes in a list of animals and a string, and if there is a dog with that name in the list, returns the dog's age. (If there's more than one, use the first one you find.) If not, return -1.
6
New topic: Natural numbers A natural number is eitherdefinition by choices! 0, or (+ 1 natural-number)definition by (recursive) part! Examples: 0, (+ 1 0), (+ 1 (+ 1 0)), etc. We use the names 0, 1, 2, etc. for short. To get the previous natural-number from a non-zero natural- number n, use (- n 1)
7
Natural numbers #| (check-expect (function-on-natural 0) …) (check-expect (function-on-natural 1) …) (check-expect (function-on-natural 5) …) (define (function-on-natural n) (cond [(= n 0) …] [else ; n non-zero natural number ; (- n 1) natural number ; (function-on-natural (- n 1)) … … )) |#
8
Natural numbers Example: count-down : natural -> list-of-numbers (check-expect (count-down 0) (list 0)) (check-expect (count-down 1) (list 1 0)) (check-expect (count-down 5) (list 5 4 3 2 1 0))
9
Natural numbers (define (count-down n) (cond [(= n 0) …] [else ; n non-zero natural ; (- n 1) natural ; (count-down (- n 1)) list of nums … ))
10
Natural numbers (define (count-down n) (cond [(= n 0) …] [else ; n non-zero natural5 ; (- n 1) natural4 ; (count-down (- n 1)) list of nums(list 4 3 2 1 0) ; right answer list of nums(list 5 4 3 2 1 0) … ))
11
Natural numbers (define (count-down n) (cond [(= n 0) (list 0)] [else ; n non-zero natural5 ; (- n 1) natural4 ; (count-down (- n 1)) list of nums(list 4 3 2 1 0) ; should be list of nums(list 5 4 3 2 1 0) (cons n (count-down (- n 1))) ))
12
Exercises Define a function sqr-table which takes in a natural number and produces a list of posns, each containing a number and its square. The x coordinates should go from the given number down to 1, inclusive. For example, (sqr-table 4) should be (list (make-posn 4 16) (make-posn 3 9) (make-posn 2 4) (make-posn 1 1))
13
Exercises Define a function row-of-dots which takes in a natural number and produces a picture of that many radius-10 orange dots side by side. Define a function orange-pile which takes in a natural number and produces a picture like
14
Trees (not in PP, but see HtDP) Ancestor family trees (binary) Descendant family trees (n-ary) two or three mutually-referential data types; write two or three mutually-referential functions Binary search trees Expression trees File hierarchy trees HTML/XML parse trees Skip 25 slides (study on your own after workshop)
15
Family trees, version 1 A person has a string(name), number(birth- year), string(eye-color), mother, and father. What types are mother and father? Obviously, "person". So let's go through the design recipe… (define-struct person (name birth-year eye- color mother father))
16
Family trees, version 1 ; Contracts for functions that come "for free": ; make-person : string num string person person -> person ; person-name : person -> string ; person-birth-year : person -> number ; person-eye-color : person -> string ; person-mother : person -> person ; person-father : person -> person
17
Family trees, version 1 ; Examples of the data type: (make-person "Fred" 1924 "brown" ? ?) In order to create a person we need to already have two other persons. Problem! In addition, in any real family tree, you eventually run out of information and have to say "unknown".
18
Family trees, version 2 A person has a string(name), number(birth-year), string(eye-color), mother, and father. What types are mother and father? "family tree", or "ftree" for short. An ftree is either unknown or a person.
19
Family trees, version 2 A person has a string(name), number(birth-year), string(eye-color), mother, and father. What types are mother and father? "family tree", or "ftree" for short. An ftree is either unknown or a person.
20
Family trees, version 2 (define-struct person (name birth-year eye-color mother father)) ; make-person : string num string ftree ftree -> person ; person-name : person -> string ; person-birth-year : person -> number ; person-eye-color : person -> string ; person-mother : person -> ftree ; person-father : person -> ftree ; person? : anything -> boolean (define-struct unknown ()) ; make-unknown : nothing -> unknown ; unknown? : anything -> boolean
21
Family trees, version 2 ; Examples of data types (define unk (make-unknown)) ; is an unknown, and therefore an ftree (define fred (make-person "Fred" 1924 "brown" unk unk) ; is a person (define mary (make-person "Mary" 1922 "green" unk unk)) (define anne (make-person "Anne" 1944 "blue" mary fred)) (define bob (make-person "Bob" 1939 "blue" unk unk)) (define phil (make-person "Phil" 1966 "hazel" anne bob))
22
Family trees, version 2 (define (function-on-person p) ; p a person ; (person-name p) a string ; (person-birth-year p) a number ; (person-eye-color p) a string ; (person-mother p) an ftree ; (function-on-ftree (person-mother p)) whatever ; (person-father p) an ftree ; (function-on-ftree (person-father p)) whatever ) (define (function-on-ftree ft) ; ft an ftree, i.e. person or unknown (cond [(unknown? ft) ; base case ] [(person? ft) (function-on-person ft)] ))
23
Family trees, version 2 Or we could collapse the two into one big function: (define (function-on-ftree ft) ; ft an ftree, i.e. person or unknown (cond [(unknown? ft) ; base case ] [(person? ft) ; ft a person ; (person-name ft) a string ; (person-birth-year ft) a number ; (person-eye-color ft) a string ; (person-mother ft) an ftree ; (function-on-ftree (person-mother ft)) whatever ; (person-father p) an ftree ; (function-on-ftree (person-father ft)) whatever ]) )
24
Writing functions on ftrees & persons Write a function count-people which takes in an ftree & returns how many persons are in it ; count-people : ftree -> number ; Data analysis: already done ; Can write either as two mutually recursive functions, or as one recursive function
25
Writing functions on ftrees & persons (check-expect (count-people unk) 0) (check-expect (count-people fred) 1) (check-expect (count-people anne) 3) (check-expect (count-people phil) 5)
26
Writing functions on ftrees & persons (define (function-on-person p) ; p a person ; (person-name p) a string ; (person-birth-year p) a number ; (person-eye-color p) a string ; (person-mother p) an ftree ; (function-on-ftree (person-mother p)) whatever ; (person-father p) an ftree ; (function-on-ftree (person-father p)) whatever ) (define (function-on-ftree ft) ; ft an ftree, i.e. person or unknown (cond [(unknown? ft) ; base case ] [(person? ft) (function-on-person ft)] ))
27
Writing functions on ftrees & persons (define (count-people-person p) ; p a person ; (count-people (person-mother p)) number ; (count-people (person-father p)) number ) (define (count-people ft) ; ft an ftree, i.e. person or unknown (cond [(unknown? ft) 0 ] [(person? ft) (count-people-person ft)] ))
28
Writing functions on ftrees & persons (define (count-people-person p) ; p a person ; (count-people (person-mother p)) number ; (count-people (person-father p)) number (+ 1 (count-people (person-mother p)) (count-people (person-father p))) ) (define (count-people ft) ; ft an ftree, i.e. person or unknown (cond [(unknown? ft) 0 ] [(person? ft) (count-people-person ft)] ))
29
Writing functions on ftrees & persons Or, collapsing the two into one big function,… (define (function-on-ftree ft) ; ft an ftree, i.e. person or unknown (cond [(unknown? ft) ; base case ] [(person? ft) ; ft a person ; (person-name ft) a string ; (person-birth-year ft) a number ; (person-eye-color ft) a string ; (person-mother ft) an ftree ; (function-on-ftree (person-mother ft)) whatever ; (person-father p) an ftree ; (function-on-ftree (person-father ft)) whatever ]) )
30
Writing functions on ftrees & persons Or, collapsing the two into one big function,… (define (count-people ft) ; ft an ftree, i.e. person or unknown (cond [(unknown? ft) 0 ] [(person? ft) ; ft a person ; (person-name ft) a string ; (person-birth-year ft) a number ; (person-eye-color ft) a string ; (person-mother ft) an ftree ; (count-people (person-mother ft)) number ; (person-father p) an ftree ; (count-people (person-father ft)) number ]) )
31
Writing functions on ftrees & persons Or, collapsing the two into one big function,… (define (count-people ft) ; ft an ftree, i.e. person or unknown (cond [(unknown? ft) 0 ] [(person? ft) ; (count-people (person-mother ft)) number ; (count-people (person-father ft)) number (+ 1 (count-people (person-mother ft)) (count-people (person- father ft))) ]) )
32
Your turn Write a function count-blue-eyed that takes in a ftree and returns the number of blue-eyed people in it Write a function count-generations that takes in an ftree and returns the maximum number of generations back it goes (0 for unknown, 1 for a person w/no ancestors, etc.) Write a function eye-colors that takes in an ftree and returns a list of all the eye colors (duplicates are OK)
33
Family trees, version 3 This time we'll work from ancestors to descendants, rather than vice versa. A person has a string(name), number (birth- year), string(eye-color), and children. What type is "children"? A list of persons (possibly empty)
34
Family trees, version 3 A person has a string(name), number (birth- year), string(eye-color), and a list-of-person (children). A list-of-person is either empty, or (cons person list-of-person)
35
Family trees, version 3 (define-struct person (name birth-year eye-color children)) ; make-person : string num string list-of-person -> person ; person-name : person -> string ; person-birth-year : person -> num ; person-eye-color : person -> string ; person-children : person -> list of person
36
Family trees, version 3 Examples of the new data type… (define steve (make-person "Steve" 1964 "brown" empty)) (define paul (make-person "Paul" 1967 "green" empty)) (define jeb (make-person "Jeb" 1981 "brown" empty)) (define al (make-person "Al" 1940) "brown" (list steve paul jeb)) ; etc. etc.
37
Family trees, version 3: templates (define (function-on-person p) ; p a person ; (person-name p) string ; (person-birth-year p) number ; (person-eye-color p) string ; (person-children p) list of persons... ) (define (function-on-person-list folx) (cond [(empty? folx)...] [(cons? folx) ; (first folx) person ; (rest folx) person-list ; (function-on-person (first folx)) whatever ; (function-on-person-list (rest folx)) whatever... ]))
38
Family trees, version 3 Note that since a person has a part of type person-list, function-on-person will call function-on-person- list. Note that since a person-list has a part of type person and a part of type person-list, function-on-person-list will call both function-on-person and function-on- person-list. This time you can't collapse the two into one big function. Try writing the corresponding functions for these trees
39
Your turn Write a function count-blue-eyed that takes in a person and returns the number of blue-eyed people descended from that person (including that person) Write a function count-generations that takes in a person and returns the maximum number of generations down it goes (1 for a person w/no children, 2 for a person w/children but no grandchildren, etc.) Write a function eye-colors that takes in a person and returns a list of all the eye colors (duplicates are OK) of that person and his/her descendants Write a function most-kids that takes in a person and returns the largest number of children in any family descended from the person
40
New topic: Local variables Recall largest function. Try it on (list 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) and on (list 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20) Why is one so slow? (depending on how you wrote it) Use Stepper to see
41
Local variables Problem: recomputing recursive call. Solution: Call once, use result twice. One way: use helper function larger : number number -> number Another way: define local variable to hold result, then use variable twice.
42
Local variables Switch languages to “Intermediate Student” Syntax rule: (local [(define var expr) (define var expr) …] expr) Defines the variables for just long enough to evaluate the final expr. (local [(define x 3) (define y 5)] (* x y)) ; returns 15, but x and y are undefined afterwards
43
distance with locals ; distance : posn posn -> number (define (distance here there) (sqrt (+ (sqr (- (posn-x here) (posn-x there))) (sqr (- (posn-y here) (posn-y there))))))
44
distance with locals ; distance : posn posn -> number (define (distance here there) (local [(define xdiff (- (posn-x here) (posn-x there))) (define ydiff (- (posn-y here) (posn-y there)))] (sqrt (+ (sqr xdiff) (sqr ydiff))))) Actually somewhat longer, but arguably easier to understand because intermediate values have names
45
largest with locals (define (largest nums) (cond [(empty? (rest nums)) (first nums)] [(cons? (rest nums)) (local [(define maxrest (largest (rest nums)))] (cond [(>= (first nums) maxrest) (first nums)] [else maxrest]) )] ))
46
When to use locals to give names to important intermediate values to avoid recomputing expensive expressions (especially recursive ones) to define things that are only of interest within a particular function (Note: can also define functions & structs inside a local!)
47
New topic: Abstracting functions Consider… add-1-to-each : list-of-numbers -> list-of-numbers cube-each : list-of-numbers -> list-of-numbers animal-weights : list-of-animals -> list-of-numbers convert-grades : list-of-numbers -> list-of-strings substitute : string string list-of-strings -> list-of-strings give-10%-raises : list-of-employees -> list-of-employees All take in a list, do some operation to each element of it, & return a list of the results. All have almost identical code, differing only in the operation.
48
Abstracting functions When several functions have similar code, differing in one thing, turn that thing into a parameter. ; do-to-each : operation list -> list More precisely, ; do-to-each : (X->Y) list-of-X -> list-of-Y where X and Y are any data types (Requires Intermediate Student language) Work this out together Predefined version is named map
49
With map,... (define (add-1-to-each nums) (map add1 nums)) (define (cube-each nums) (map cube nums)) (define (animal-weights zoo) (map animal-weight zoo)) ; where animal-weight is a helper function we write (define (convert-grades nums) (map convert-grade nums)) ; where convert-grade is a helper function we write (define (give-10%-raises emps) (map give-10%-raise emps)) substitute is a little trickier; we'll come back to this.
50
Abstracting functions Consider… count-elements count-over-100 count-earning-over-100k count-tigers All take in a list and return how many elements meet a certain criterion. General version: ; count-if : test list -> number More precisely, ; count-if : (X->boolean) list-of-X -> number
51
Exercise Re-define count-elements count-over-100 count-dogs (in a list of animals) using count-if instead of recursion. You may need to write some one-line helper functions.
52
Abstracting functions Consider… remove-evens fire-over-100k keep-positives extract-fish All take in a list and extract from it the elements that meet a certain criterion General version: ; filter : test list -> list More precisely, ; filter : (X->boolean) list-of-X -> list-of-X Predefined, but we could have written it easily
53
Exercise Re-define remove-evens keep-positives extract-fish using filter instead of recursion. You may need to write some one-line helper functions.
54
Abstracting functions Consider… add-up multiply-up total-salary any-over-100? all-over-100? sort All take in a list and combine its elements, starting from the empty and mixing in one more element at a time. They differ in the answer to the empty case, and in how they combine things. General form: ; foldr : (X Y->Y) Y list-of-X -> Y (predefined, but we could have…) (define (add-up L) (foldr + 0 L)) (define (any-over-100? L) (foldr or false L))
55
Examples and Exercise ; foldr : (X Y->Y) Y list-of-X -> Y (define (add-up L) (foldr + 0 L)) (define (any-over-100? L) (foldr or false L)) Re-define multiply-up total-salary any-over-100? all-over-100? sort using foldr instead of recursion. You may need to write some one-line helper functions.
56
Functions on the Fly Calling a function like map, count-if, filter, or foldr often requires making up a function just to pass in — otherwise useless. Example: (define (add-3-to-each nums) (map add3 nums)) (define (add3 x) (+ x 3) This is silly.
57
Functions on the Fly: local Example: (define (add-3-to-each nums) (local [(define (add3 x) (+ x 3))] (map add3 nums))) add3 is "hidden" inside add-3-to-each; doesn't "pollute" rest of world.
58
Functions on the Fly: lambda Switch languages to “Intermediate Student with Lambda” Syntax rule: (lambda (params) expr) is a (nameless) function that takes in values for the params and evaluates the expr Example: (define (add-3-to-each nums) (map (lambda (x) (+ x 3)) nums))) add3 isn't even named.
59
Functions on the Fly More natural example ; add-to-each : number list-of-numbers -> list-of-numbers Can't do this with a separate function, because we don't know what it's supposed to add until add-to-each is called. Easy to do with either local or lambda. (define (add-to-each num nums) (local [(define (addit x) (+ x num))] (map addit nums))) (define (add-to-each num nums) (map (lambda (x) (+ x num)) nums))
60
Exercises Write a function remove-over that takes a number and a list of numbers, and removes all the numbers over the specified number. No recursion; use a higher-order function instead. Use local or lambda to specify its function argument. Re-write substitute using a higher-order function instead of recursion. Use local or lambda to specify its function argument. Re-write insert-in-order using a higher-order function instead of recursion. (Tricky!)
61
Functions returning functions Suppose we had lots of occasions to produce a function like add3 or add17. Can do it each time with local or lambda, or… … automate it with a function! Then… (define (add-to-each num nums) (map (make-adder num) nums))
62
Functions returning functions ; make-adder : num -> (num -> num) (check-expect ((make-adder 3) 4) 7) (check-expect ((make-adder -6) 29) 23) (check-expect (map (make-adder 2) (list 3 4 5)) (list 5 6 7)) (define (make-adder to-add) (local [(define (f x) (+ x to-add))] f))
63
Functions returning functions ; make-adder : num -> (num -> num) (check-expect ((make-adder 3) 4) 7) (check-expect ((make-adder -6) 29) 23) (check-expect (map (make-adder 2) (list 3 4 5)) (list 5 6 7)) (define (make-adder to-add) (lambda (x) (+ x to-add)))
64
Extra credit exercises Define a function twice that takes in a function f:X->X and returns the function g(x) = f(f(x)). For example, (define add2 (twice add1)) (define 4 th -root (twice sqrt)) Define a function iterate that takes in a function f:X->X and a natural number n and returns the function f (n), i.e. f composed with itself n times. For example, (define add5 (iterate add1 5))
65
Abstracting functions I try to introduce this stuff in Scheme because it's a powerful programming tool in any language it's enormously easier in Scheme than in C++ or Java it blows people's minds
66
I/O, sequential programming, and mutation Not covered this week; see Picturing Programs
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.