Presentation is loading. Please wait.

Presentation is loading. Please wait.

Pairs and Lists. Data Abstraction. SICP: Sections – 2.2.1

Similar presentations


Presentation on theme: "Pairs and Lists. Data Abstraction. SICP: Sections – 2.2.1"— Presentation transcript:

1 Pairs and Lists. Data Abstraction. SICP: Sections 2.1.1 – 2.2.1
Lecture notes: Chapter 3

2 Box and Pointer Diagram
2 1 a (define a (cons 1 2)) A pair can be implemented directly using two “pointers”. Originally on IBM 704: (car a) Contents of Address part of Register (cdr a) Contents of Decrement part of Register

3 Pair: A primitive data type.
Constructor: (cons a b) Selectors: (car p) (cdr p) Guarantee: (car (cons a b)) = a (cdr (cons a b)) = b Abstraction barrier: We say nothing about the representation or implementation of pairs.

4 Pairs (define x (cons 1 2)) (define y (cons 3 4))
(define z (cons x y)) (car (car z))  1 ;(caar z) (car (cdr z))  3 ;(cadr z)

5 Box and pointer diagrams
(cons (cons 1 (cons 2 3)) 4) 4 1 3 2

6 Compound Data A closure property: The result obtained by creating a compound data structure can itself be treated as a primitive object and thus be input to the creation of another compound object. Pairs have the closure property: We can pair pairs, pairs of pairs etc. (cons (cons 1 2) 3) 3 2 1

7 The empty list (a.k.a. null or nill)
Lists The empty list (a.k.a. null or nill) (cons 1 (cons 3 (cons 2 ’() ))) 1 3 2 List are the glue for putting together many values just as pairs are the glue for pairs of values. Syntactic sugar: (list 1 3 2)

8 Formal Definition of a List
A list is either ’() -- The empty list A pair whose cdr is a list. Lists are closed under the operations cons and cdr: If lst is a non-empty list, then (cdr lst) is a list. If lst is a list and x is arbitrary, then (cons x lst) is a list. מבוא מורחב שיעור 7

9 (cons <x1> (cons <x2> ( … (cons <xn> ’() ))))
Lists (list <x1> <x2> ... <xn>) is syntactic sugar for (cons <x1> (cons <x2> ( … (cons <xn> ’() )))) <x1> <x2> <xn>

10 Lists (examples) The following expressions all result in the same structure: (cons 3 (list 1 2)) (cons 3 (cons 1 (cons 2 ’() ))) (list 3 1 2) 3 1 2 and similarly the following (cdr (list 1 2 3)) (cdr (cons 1 (cons 2 (cons 3 ’() )))) (cons 2 (cons 3 ’() )) (list 2 3) 2 3

11 More Elaborate Lists (list 1 2 3 4) Value:(1 2 3 4)
(cons (list 1 2) (list 3 4)) (list (list 1 2) (list 3 4)) Value:( ) Value:((1 2) 3 4) Value:((1 2) (3 4)) 1 2 3 4 1 3 4 2 1 3 4 2

12 List of Symbols (shorthand)
‘(a b c) translates into (‘a ‘b ‘c)

13 Yet More Examples (define p (cons 1 2)) p (1 . 2)
3 p1 p1 ( ) 1 2 p p2 (define p2 (list p p)) p2 ( (1 . 2) (1 . 2) )

14 The Predicate Null? (null? <z>) null? : anytype -> boolean
#t if <z> evaluates to empty list #f otherwise (null? 2)  #f (null? (list 1))  #f (null? (cdr (list 1)))  #t (null? ’())  #t (null? null)  #t The beauty of list is that cdr allows us to easily move down a list, and we have a simple test to find out when we have reached the end, we get to the empty list, that is, to a list whose value is null. How do we check that we have reached the end, scheme supplies us with the predicate null?

15 The Predicate Pair? pair? : anytype -> boolean
(pair? <z>) #t if <z> evaluates to a pair #f otherwise. (pair? (cons 1 2))  #t (pair? (cons 1 (cons 1 2)))  #t (pair? (list 1))  #t (pair? ’())  #f (pair? 3)  #f (pair? pair?)  #f

16 The Predicate Atom? atom? : anytype -> boolean (define (atom? z)
(and (not (pair? z)) (not (null? z)))) (define (square x) (* x x)) (atom? square)  #t (atom? 3)  #t (atom? (cons 1 2))  #f Not a primitive procedure

17 More examples ? ? (define digits (list 1 2 3 4 5 6 7 8 9))
(define digits1 (cons 0 digits)) digits1 (define l (list 0 digits)) l ? ? ( ) (0 ( ))

18 The procedure length (define digits (list 1 2 3 4 5 6 7 8 9))
(length digits) 9 (define l null) (length l) (define l (cons 1 l)) (length l) 1 (define (length l) (if (null? l) 0 (+ 1 (length (cdr l)))))

19 The procedure append (define (append list1 list2)
(cond ((null? list1) list2) ; base (else (cons (car list1) ; recursion (append (cdr list1) list2)))))

20 Constructor Type: Number * T -> LIST(T) > (make-list 7 ’foo)
(foo foo foo foo foo foo foo) > (make-list 5 1) ( )

21 List type Pairs: For every type assignment TA and type expressions S,S1,S2: TA |- cons:[S1*S2 -> PAIR(S1,S2)] TA |- car:[PAIR(S1,S2) -> S1] TA |- cdr:[PAIR(S1,S2) -> S2] TA |- pair?:[S -> Boolean] TA |- equal?:[PAIR(S1,S2)*PAIR(S1,S2) -> Boolean]

22 For every type environment TEnv and type expression S: TEnv |- list:[Unit -> LIST(S)] TEnv |- cons:[T*LIST(S) -> LIST(S)] TEnv |- car:[LIST(S) -> S] TEnv |- cdr:[LIST(S) -> LIST(S)] TEnv |- null?:[LIST(S) -> Boolean] TEnv |- list?:[S -> Boolean] TEnv |- equal?:[LIST(S)*LIST(S) -> Boolean]

23 Cont. For every type environment TEnv and type expression S:
TEnv |- list:[Unit -> LIST] TEnv |- cons:[S*LIST -> LIST] TEnv |- car:[LIST -> S] TEnv |- cdr:[LIST -> LIST] TEnv |- null?:[LIST -> Boolean] TEnv |- list?:[S -> Boolean] TEnv |- equal?:[LIST*LIST -> Boolean]

24 Procedural abstraction
Publish: name, number and type of arguments (and conditions they must satisfy) type of procedure’s return value Guarantee: the behavior of the procedure Hide: local variables and procedures, way of implementation, internal details, etc. Interface Implementation Export only what is needed.

25 Data-object abstraction
Publish: constructors, selectors Guarantee: the behavior Hide: local variables and procedures, way of implementation, internal details, etc. Interface Implementation Export only what is needed.

26 An example: Rational numbers
We would like to represent rational numbers. A rational number is a quotient a/b of two integers. Constructor: (make-rat a b) Selectors: (numer r) (denom r) Guarantee: (numer (make-rat a b)) = a (denom (make-rat a b)) = b

27 An example: Rational numbers
We would like to represent rational numbers. A rational number is a quotient a/b of two integers. Constructor: (make-rat a b) Selectors: (numer r) (denom r) A better Guarantee: (numer (make-rat a b)) a = (denom (make-rat a b)) b A weaker condition, but still sufficient!

28 We can now use the constructors and selectors to implement operations on rational numbers:
(add-rat x y) (sub-rat x y) (mul-rat x y) (div-rat x y) (equal-rat? x y) (print-rat x) A form of wishful thinking: we don’t know how make-rat numer and denom are implemented, but we use them.

29 Implementing the operations
(define (add-rat x y) ;n1/d1 + n2/d2 = (n1.d2 + n2.d1) / (d1.d2) (make-rat (+ (* (numer x) (denom y)) (* (numer y) (denom x))) (* (denom x) (denom y)))) (define (sub-rat x y) … (define (mul-rat x y) (make-rat (* (numer x) (numer y)) (* (denom x) (denom y)))) (define (div-rat x y) (make-rat (* (numer x) (denom y)) (* (denom x) (numer y)))) (define (equal-rat? x y) (= (* (numer x) (denom y)) (* (numer y) (denom x))))

30 Using the rational package
(define (print-rat x) (newline) (display (numer x)) (display ”/”) (display (denom x))) (define one-half (make-rat 1 2)) (print-rat one-half)  1/2 (define one-third (make-rat 1 3)) (print-rat (add-rat one-half one-third))  5/6 (print-rat (add-rat one-third one-third))  6/9

31 Abstraction barriers Programs that use rational numbers
rational numbers in problem domain add-rat sub-rat mul-rat… rational numbers as numerators and denumerators make-rat numer denom

32 Gluing things together
We still have to implement numer, denom, and make-rat We need a way to glue things together… A pair: (define x (cons 1 2)) (car x)  1 (cdr x)  2

33 Implementing make-rat, numer, denom
(define (make-rat n d) (cons n d)) (define (numer x) (car x)) (define (denom x) (cdr x))

34 Abstraction barriers Programs that use rational numbers
rational numbers in problem domain add-rat sub-rat mul-rat... rational numbers as numerators and denumerators make-rat numer denom rational numbers as pairs cons car cdr

35 Alternative implementation for add-rat
Abstraction Violation (define (add-rat x y) (cons (+ (* (car x) (cdr y)) (* (car y) (cdr x))) (* (cdr x) (cdr y)))) If we bypass an abstraction barrier, changes to one level may affect many levels above it. Maintenance becomes more difficult.

36 Rationals - Alternative Implementation
In our current implementation we keep 10000/20000 as such and not as 1/2. This: Makes the computation more expensive. Prints out clumsy results. A solution: change the constructor (define (make-rat a b) (let ((g (gcd a b))) (cons (/ a g) (/ b g)))) No other changes are required!

37 Reducing to lowest terms, another way
(define (make-rat n d) (cons n d)) (define (numer x) (let ((g (gcd (car x) (cdr x)))) (/ (car x) g))) (define (denom x) (/ (cdr x) g)))

38 How can we implement pairs? (first solution – “lazy” implementation)
(define (cons x y) (lambda (f) (f x y))) (define (car z) (z (lambda (x y) x))) (define (cdr z) (z (lambda (x y) y)))

39 How can we implement pairs? (first solution, cont’)
Name Value (lambda(f) (f 1 2)) p > (define p (cons 1 2)) > (car p) ( (lambda(f) (f 1 2)) (lambda (x y) x)) ( (lambda(x y) x) 1 2 ) (define (cons x y) (lambda (f) (f x y))) > 1 (define (car z) (z (lambda (x y) x))) (define (cdr z) (z (lambda (x y) y)))

40 How can we implement pairs? (Second solution: “eager” implementation)
(define (cons x y) (lambda (m) (cond ((= m 0) x) ((= m 1) y) (else (error "Argument not 0 or CONS" m)))))) (define (car z) (z 0)) (define (cdr z) (z 1))

41 Implementing pairs (second solution, cont’)
Name Value > (define p (cons 3 4)) p (lambda(m) (cond ((= m 0) 3) ((= m 1) 4) (else ..))) > (car p) ((lambda(m) (cond ..)) 0) (cond ((= 0 0) 3) ((= 0 1) 4) (else ...))) (define (cons x y) (lambda (m) (cond ((= m 0) x) ((= m 1) y) (else ...))) > 3 (define (car z) (z 0)) (define (cdr z) (z 1))


Download ppt "Pairs and Lists. Data Abstraction. SICP: Sections – 2.2.1"

Similar presentations


Ads by Google