Discussion 4 Data Abstraction and Sequences Data Abstraction: The idea of data abstraction is to conceal the representation of some data and to instead reveal a standard interface that is more aligned with what the data represents as opposed to how the data is represented. To give a concrete example when you use numbers in Scheme, you don t care how they are represented you just care about whether you know what they mean. Would you prefer to code (* 22 7) to get 154 or (* 10110 111) to get 10011010 (the internal representation)? Whenever you use a certain type of data, we will usually want you to use an Abstract Data Type (ADT). What this means is you create a set of functions that define your new data type. At this point, anyone who wants to use your data type should be able to do so without having to know how you represented your data type. Let s delve into the specifics usually, you need one or more constructors, which construct a new instance of your ADT, and selectors, which allow you to retrieve relevant information from some particular instance of your ADT. We have defined the word ADT and the sentence ADT for you. The code is actually very long, because we have to deal with all of the internal representations for words and sentences. But all you need to know is that you can create a word/sentence with quote, word or sentence, and that you can select the appropriate data from words and sentences using first and butfirst. (Note: You may say that we ve also given you other procedures such as member?, every, keep and so on, but these were all built on top of the initial ADT, so really the ADT itself just consists of the constructors and selectors.) Pairs and Sequences: All you need to know about cons is that is creates a box with two compartments, into which it sticks the two arguments, and that you can get those arguments back with the selectors car and cdr. That s it. The discipline of data abstraction means that you don t need to know the internal representation. How you can think about Scheme printing a pair: It prints a (, recursively prints the car, prints., recursively prints the cdr, and prints ). Once this is done, it goes back, and if it ever sees. (, it throws away the., the (, and the matching ). What do you need to know about list? Just that (list a b c) is the same thing as (cons a (cons b (cons c ()))), and that other invocations of list behave in the same way. (We don t give a procedure definition yet because list takes a variable number
of arguments.) () is the empty list it s a special value that is a list but not a pair. You can check if something is the empty list using the predicate null?. By the way in box-and-pointer diagrams, you should always draw the starting arrow, i.e. an arrow from empty space to the pair which you are drawing. The meaning of this arrow is that the variable that I am talking about points to this pair. Exercise 1: Consider the list (1 2 3 4). Draw the box-and-pointer diagram for this list. Based on this diagram, do only the first step of how Scheme would print this list. (In other words, don t cancel out the. ( when printing the list.) (1. (2. (3. (4. ())))) Now write what Scheme actually prints. (1 2 3 4) Here s the definition of append for two arguments only (the real one can take several): (define (append x y) (if (null? x) y (cons (car x) (append (cdr x) y)))) Exercise 2: Write what Scheme prints. If it is a procedure, write procedure. If it is an error, write error and explain why, based on the definition of append given above. Also, draw a box-and-pointer diagram, if applicable. (append (1 2) 3) (1 2. 3) (append 1 (2 3)) Error The real append procedure is similar it expects all of its arguments to be lists, but it won t error in the case where only the last argument is not a list. Exercise 3: Write what Scheme prints. If it is a procedure, write procedure. If it is an error, write error. Also, draw a box-and-pointer diagram, if applicable. (cons (list 1 2) (list 3 4))
((1 2) 3 4) (append (hello world) (list (its) nice) (cons (to say) (cons (that in) ())) (scheme)) (hello world (its) nice (to say) (that in) scheme) (cons (cons (cons 1 4) 5) (cons 3 (list 4))) (((1. 4). 5) 3 4) Exercise 4: Write a procedure flatten-pairs, which given as input a list of pairs of some type of elements, produces as output a list of the elements (in the same order). For lab 5: write it twice the first time using recursion, and the second time using higher-order functions. > (flatten-pairs ((1. 2) (3. 4) (5. 6))) (1 2 3 4 5 6) > (flatten-pairs (((nested) stuff) ((is) cool))) ((nested) (stuff) (is) (cool)) (define (flatten-pairs lst) (if (null? lst) lst (cons (caar lst) (cons (cdar lst) (flatten-pairs (cdr lst)))))) (define (flatten-pairs lst) (accumulate append () (map (lambda (x) (list (car x) (cdr x))) lst))) Data Abstraction Revisited: Exercise 5: Suppose we want to write a procedure which, given a list of grades (numbers between 0 and 100), finds both the minimum and the maximum grade. Since in Scheme we can only return one thing, we ll invent a new ADT a num-pair. Assuming you have already defined the constructor, make-num-pair, and the selectors, first-num and second-num, write a procedure minmax which takes in a list of numbers and returns a num-pair whose
first-num is the minimum element and whose second-num is the maximum element. You may assume that the input list has at least one number. (Lab 5: Try doing it with both recursion and higher order functions.) (define (minmax grades) (make-num-pair (min_grades grades) (max_grades grades))) (define (min_grades grades) (if (null? (cdr grades)) (car grades) (min (car grades) (min_grades (cdr grades))))) (define (max_grades grades) (if (null? (cdr grades)) (car grades) (max (car grades) (max_grades (cdr grades))))) Instructor Note: Use this to motivate the HOF for lab 5. (define (minmax grades) (make-num-pair (accumulate min (car grades) (cdr grades)) (accumulate max (car grades) (cdr grades)))) Now let s actually write the constructors and selectors. But let s test 3 different types! Write constructors and selectors which represent a num-pair as a pair/list. > (pair? (make-num-pair 50 60)) > (second-num (minmax (89 94 83 95 91 50))) 95 (define make-num-pair cons) (define first-num car) (define second-num cdr) Write constructors and selectors which represent a num-pair as a number. (Hint: Remember that since the numbers represent grades, they must be in the range 0-100, inclusive.) > (number? (make-num-pair 50 60)) > (first-num (minmax (89 94 83 95 91 50))) 50 (define (make-num-pair a b) (+ (* 101 a) b)) (define (first-num pair) (quotient pair 101))
(define (second-num pair) (remainder pair 101)) Write constructors and selectors which represent a num-pair as a procedure. > (procedure? (make-num-pair 50 60)) > (second-num (minmax (89 94 83 95 91 50))) 95 (define (make-num-pair a b) (lambda (m) (if (= m 0) a b))) (define (first-num pair) (pair 0)) (define (second-num pair) (pair 1))