Racket Values • booleans: #t, #f • numbers: The Pros of cons : – integers: 42 , 0, -273 Programming with Pairs and Lists – ra3onals: 2/3 , -251/17 – floa3ng point (including scien3fic nota3on): 98.6 , -6.125 , 3.141592653589793, 6.023e23 – complex: 3+2i , 17-23i , 4.5-1.4142i Note: some are exact , the rest are inexact . See docs. • strings: "cat" , "CS251" , " αβγ " , CS251 Programming "To be\nor not\nto be" Languages • characters: #\a , #\A , #\5 , #\space , #\tab , #\newline Fall 2017, Lyn Turbak • anonymous func3ons: (lambda (a b) (+ a (* b c))) Department of Computer Science What about compound data? Wellesley College Pairs and Lists 2 Box-and-pointer diagrams for cons trees cons Glues Two Values into a Pair (cons v1 v2 ) v1 v2 A new kind of value: Conven3on: put “small” values (numbers, booleans, characters) inside a box, • pairs (a.k.a. cons cells): (cons V1 V2 ) and draw a pointers to “large” values (func3ons, strings, pairs) outside a box. e.g., (cons (cons 17 (cons "cat" #\a)) In Racket, - (cons 17 42) (cons #t ( λ (x) (* 2 x)))) type Command-\ to get λ char - (cons 3.14159 #t) - (cons "CS251" ( λ (x) (* 2 x)) - (cons (cons 3 4.5) (cons #f #\a)) 17 #t • Can glue any number of values into a cons tree! #\a (λ (x) (* 2 x)) "cat" Pairs and Lists 3 Pairs and Lists 4
Evalua3on Rules for cons cons evalua3on example Big step seman,cs: (cons (cons {(+ 1 2)} (< 3 4)) E1 ↓ V1 (cons (> 5 6) (* 7 8))) ⇒ (cons (cons 3 {(< 3 4)}) E2 ↓ V2 [cons] (cons (> 5 6) (* 7 8))) (cons E1 E2 ) ↓ (cons V1 V2 ) ⇒ (cons (cons 3 #t) (cons {(> 5 6)} (* 7 8))) ⇒ (cons (cons 3 #t) (cons #f {(* 7 8)})) Small-step seman,cs: ⇒ (cons (cons 3 #t) (cons #f 56)) cons has no special evalua3on rules. Its two operands are evaluated le\-to-right un3l a value (cons V1 V2 ) is reached: (cons E1 E2 ) ⇒ * (cons V1 {E2} ) ; first evaluate E1 to V1 step-by-step ⇒ * (cons V1 V2 ) ; then evaluate e2 to v2 step-by-step Pairs and Lists 5 Pairs and Lists 6 Prac3ce with car and cdr car and cdr Write expressions using car , cdr , and tr that extract the five leaves of this tree: • car extracts the le\ value of a pair (define tr (cons (cons 17 (cons "cat" #\a)) (car (cons 7 4)) ⇒ 7 (cons #t ( λ (x) (* 2 x)))) tr ⟼ (cons (cons 17 (cons "cat" #\a)) • cdr extract the right value of a pair (cons #t ( λ (x) (* 2 x)))), … (cdr (cons 7 4)) ⇒ 4 tr ⟼ Why these names? 17 #t • car from “contents of address register” #\a (λ (x) (* 2 x)) • cdr from “contents of decrement register” "cat" Pairs and Lists 7 Pairs and Lists 8
cadr and friends Evalua3on Rules for car and cdr Big-step seman,cs: • (caar e ) means (car (car e )) E ↓ (cons V1 V2 ) • (cadr e ) means (car (cdr e )) E ↓ (cons V1 V2 ) [car] [cdr] • (cdar e ) means (cdr (car e )) (car E ) ↓ V1 (cdr e ) ↓ v2 • (cddr e ) means (cdr (cdr e )) Small-step seman,cs: • (caaar e ) means (car (car (car e ))) (car (cons V1 V2 )) ⇒ V1 [car] � • (cddddr e ) means (cdr (cdr (cdr (cdr e )))) (cdr (cons V1 V2 )) ⇒ V2 [cdr] Pairs and Lists 9 Pairs and Lists 10 Printed Representa3ons in Racket Interpreter Seman3cs Puzzle > (lambda (x) (* x 2)) According to the rules on the previous page, what is the #<procedure> result of evalua3ng this expression? > (cons (+ 1 2) (* 3 4)) (car (cons (+ 2 3) (* 5 #t))) '(3 . 12) Note: there are two ``natural” answers. Racket gives one, > (cons (cons 5 6) (cons 7 8)) but there are languages that give the other one! '((5 . 6) 7 . 8) > (cons 1 (cons 2 (cons 3 4))) '(1 2 3 . 4) What’s going on here? Pairs and Lists 11 Pairs and Lists 12
Display Nota3on and Doged Pairs display vs. print in Racket > (display (cons 1 (cons 2 null))) • The display nota,on for (cons V1 V2 ) is ( DN1 . DN2 ) , where DN1 and DN2 are the display nota3ons for V1 and V2 (1 2) • In display nota3on, a dot “eats” a paren pair that follows it > (display (cons (cons 5 6) (cons 7 8))) directly: ((5 . 6) 7 . 8) ((5 . 6) . (7 . 8)) > (display (cons 1 (cons 2 (cons 3 4)))) becomes ((5 . 6) 7 . 8) (1 2 3 . 4) (1 . (2 . (3 . 4))) becomes (1 . (2 3 . 4)) > (print(cons 1 (cons 2 null))) '(1 2) becomes (1 2 3 . 4) Why? Because we’ll see this makes lists print predly. > (print(cons (cons 5 6) (cons 7 8))) • The Racket interpreter puts a single quote mark before the '((5 . 6) 7 . 8) display nota3on of a top-level pair value. (We’ll say more about > (print(cons 1 (cons 2 (cons 3 4)))) quota3on later.) '(1 2 3 . 4) Pairs and Lists 13 Pairs and Lists 14 Func3ons Can Take and Return Pairs Lists In Racket, a list is just a recursive pattern of pairs. (define ( swap-pair pair) (cons (cdr pair) (car pair))) A list is either (define ( sort-pair pair) • The empty list null , whose display notation is () ( if (< (car pair) (cdr pair)) pair • A nonempty list (cons Vfirst Vrest ) whose ( swap pair))) - first element is Vfirst What are the values of these expressions? - and the rest of whose elements are the sublist Vrest • (swap-pair (cons 1 2)) E.g., a list of the 3 numbers 7, 2, 4 is wrigen • (sort-pair (cons 4 7)) • (sort-pair (cons 8 5)) (cons 7 (cons 2 (cons 4 null))) Pairs and Lists 15 Pairs and Lists 16
Box-and-pointer nota3on for lists list sugar Treat list as syntac3c sugar: Nota3on for null in box-and-pointer A list of n values is drawn like this: • (list) desugars to null diagrams • (list E1 …) desugars to (cons E1 (list …)) � V1 V2 Vn For example: A pair slot Vn containing null (list (+ 1 2) (* 3 4) (< 5 6)) can also be desugars to (cons (+ 1 2) (list (* 3 4) (< 5 6))) with a slash through the slot desugars to (cons (+ 1 2) (cons (* 3 4) (list (< 5 6)))) For example: desugars to (cons (+ 1 2) (cons (* 3 4) (cons (< 5 6) (list)))) desugars to (cons (+ 1 2) (cons (* 3 4) (cons (< 5 6) null))) 7 2 4 7 2 4 * This is a white lie, but we can pretend it’s true for now Pairs and Lists 17 Pairs and Lists 18 Display Nota3on for Lists list and small-step evalua3on The “dot eats parens” rule makes lists display nicely: It is some3mes helpful to both desugar and resugar with list : (list 7 2 4) (list (+ 1 2) (* 3 4) (< 5 6)) desugars to (cons {(+ 1 2)} (cons (* 3 4) desugars to (cons 7 (cons 2 (cons 4 null)))) (cons (< 5 6) null))) displays as (before rule) (7 . (2 . (4 . ()))) ⇒ (cons 3 (cons {(* 3 4)} (cons (< 5 6) null))) ⇒ (cons 3 (cons 12 (cons {(< 5 6)} null))) displays as (a\er rule) (7 2 4) ⇒ (cons 3 (cons 12 (cons #t null))) prints as '(7 2 4) resugars to (list 3 12 #t) In Racket: Heck, let’s just informally write this as: > (display (list 7 2 4)) (list {(+ 1 2)} (* 3 4) (< 5 6)) (7 2 4) ⇒ (list 3 {(* 3 4)} (< 5 6)) > (display (cons 7 (cons 2 (cons 4 null)))) ⇒ (list 3 12 {(< 5 6)}) ⇒ (list 3 12 #t) (7 2 4) Pairs and Lists 19 Pairs and Lists 20
first , rest , and friends Recursive List Func3ons Because lists are defined recursively, it’s natural to process • first returns the first element of a list: them recursively. (first (list 7 2 4)) ⇒ 7 ( first is almost a synonym for car , but requires its Typically (but not always) a recursive func3on recf on a list argument to be a list) argument L has two cases: • rest returns the sublist of a list containing every element • base case: what does recf return when L is empty? but the first: (Use null? to test for an empty list) (rest (list 7 2 4)) ⇒ (list 2 4) • recursive case: if L is the nonempty list (cons Vfirst Vrest ) ( rest is almost a synonym for cdr , but requires its how are Vfirst and (recf Vrest ) combined to give the result argument to be a list) for (recf L) ? • Also have second , third , …, ninth , tenth Note that we always ``blindly” apply recf to Vrest ! Pairs and Lists 21 Pairs and Lists 22 Recursive List Func3ons: Divide/Conquer/Glue (DCG) Recursive List Func3ons: Divide/Conquer/Glue (DCG) strategy for the general case [in words] strategy for the general case [in diagram] Step 1 (concrete example): pick a concrete input list, typically 3 or 4 elements (sum '( 5 7 2 4 )) ⇒ * 18 long. What should the func3on return on this input? E.g. A sum func3on that returns the sum of all the numbers in a list: Divide: what should func3on return for rest of list? (sum '(5 7 2 4)) ⇒ * 18 (wishful thinking!) Step 2 (divide): without even thinking, always apply the func3on to the rest (sum '(7 2 4)) ⇒ * 13 of the list. What does it return? (sum '(7 2 4)) ⇒ * 13 Glue: how to combine the first element of the list with Step 3 (glue): How to combine the first element of the list (in this case, 5 ) with the result of recursively the result from processing the rest (in this case, 13 ) to give the result for processing rest of the list to get the desired result processing the whole list (in this case, 18 )? 5 + (sum '(7 2 4)) ⇒ * 18 for the whole list? Step 4 (generalize): Express the general case in terms of an arbitrary input: combine (define (sum nums) Solu3on for concrete example: 5 + (sum '(7 2 4)) … (+ (first nums) (sum (rest nums)) … ) Generaliza3on of concrete solu3on: (first nums) + (sum (rest nums)) Pairs and Lists 23 Pairs and Lists 24
Recommend
More recommend