Printing TDDC74 Programming: Abstraction and Modelling Printing is usually the process of presenting data using a medium (the screen, a file, ...) SICP 2 – Lecture 4-6 Annika Silvervarg 2 Some Printing Procedures Content display – print the value of the argument print – print the arguemtn newline – print a new line printf – print a formatted string Introduction to data abstraction Data types in Scheme – – – – Warning: Do not use these procedure to return values. Scheme has its own way of showing returned values. – – – Numbers Symbols Character String Pair List Tree Abstract Data Types ADT – – 3 4 Abstraction example ADT – Brick Properties – – – X-position Y-position Shape Abstraction barrier Constructors, Selectors, Recognizers Data-directed programming Primitive Data: Numbers, Symbols, Strings, ... Program Procedures – – Numbers: 2, 3.14 Symbols: x, y, square, pi Strings: ”whatever”, ”123”, ”\”” Characters: #\2, #\c, #\C, #\$ Collide?(brick1, brick2) … Procedures – – – – – 6 Make-brick Get-X-pos Get-Y-pos Get-Shape Rotate-brick 7 1 Recognizing Primitive Data Comparing Primitive Data Numbers: number? Symbols: symbol? String: string? Characters: char? 8 Numbers: = Symbols: eq? String: string=?, string<?, string<=?,... Characters: char=?, char<?, ... 9 Symbols and QUOTE Symbols and QUOTE Symbols as data should be distinguished from names QUOTE is used to mark that an expression is data and should not be evaluated (quote x) is evaluated to the symbol x, where as x is evaluated to the value x has (quote x) has a short form ’x if you prefer that (define a 3) >a 3 > (quote a) a > ’a a 10 11 Structured Data and Data Abstraction Pairs Pairs are represented as two ”glued” elements called CAR and CDR Pairs are constructued by the procedure CONS which has two arguments Two procedures CAR and CDR are used to select the part we want PAIR? Is used to test whether something is a pair Pairs are printed as (car . cdr) If something is not a pair we call it an atom Constructing Structured Data Constructor Procedures Selecting Parts of Structured Data Selector Procedures Recognizing Structured Data Recognizer and Comparison Procedures Changing Parts of Structured Data Mutator Procedures Presenting Structured Data Printing Procedures 12 13 2 Pairs example 14 Graphical Notation for Pairs Construction > (define my-pair (cons 1 2)) > my-pair (1 . 2) Selecting > (car my-pair) 1 > (cdr my-pair) 2 Recognizing > (pair? my-pair) #t > (pair 1) #f A pair is physically represented using a so called CONS-cell which is graphically denoted as: 15 Graphical Notation for Pairs Graphical Notation for Pairs (cons 10 20) (cons 10 20) 10 20 10 20 16 17 Combining pairs Graphical Notation for Pairs Pairs can have new pairs as parts Thus, pairs can be used to form more complex compound data (cons 10 (cons 20 30)) 10 18 20 30 19 3 Graphical Notation for Pairs Graphical Notation for Pairs (cons 10 (cons 20 30)) (define x (cons 10 (cons 20 30))) x 10 20 30 20 10 20 30 21 Graphical Notation for Pairs Printing Pairs (define x (cons (cons 10 40) (cons 20 30))) Pairs (or CONS-cells) are printed by the system as follows: (cons 1 2) as (1 . 2) (cons (cons 1 2) (cons 3 4)) as ((1 . 2) 3 . 4) which is equvalent to ((1 . 2) . (3 . 4)) (cons (cons 1 (cons 2 ()))) as (1 2) which is equivalent to (1 . ( 2 . ())) x 10 40 20 30 Each call to CONS creates a box 22 23 CONS-cell can be shared CONS-cell can be shared (define pair (cons 1 2)) (define pairpair (cons pair pair)) (define pair (cons 1 2)) (define pairpair (cons pair pair)) (define metoo pair) pairpair pairpair pair 1 2 pair metoo 24 1 2 25 4 CONS-cell can be shared Sequences (Lists) - The Definition (define pair (cons 1 2)) (define pairpair (cons pair pair)) (define metoo pair) (define andme (cons pairpair metoo)) (1 . 2) ((1 . 2) 1 . 2) (1 . 2) (((1 . 2) 1 . 2) 1 . 2) A sequence is either empty or it contains a number of elements that appear in a certain order Examples: 1, 2, 3, ... 0, 1, 1, 2, 3, ... 6, 28, ... pairpair andme pair 1 metoo 26 2 27 Representing Lists Graphical Notation for Lists The empty list: () Non-empty lists: as a finite sequence of pairs The ith pair contains the ith element as its first part and the rest of the list as its second part The second part of the final pair would then be the empty list Empty list: () List with 1 element: (list 10) 10 () List with 2 elements: (list 10 20) 10 28 29 Graphical Definition for Lists Constructing Lists A non-empty list is represented by a finite sequence of CONS-cells where the CAR-part of each cell contains an element of the list and the CDR-part of it contains the remaining list. The CDR-part of the final cell is (): e1 30 20 () e2 ... (cons 1 (cons 2 (cons 3 ()))) Constructs the list (1 2 3) en () 31 5 Constructing Lists Constructing Lists (list 1 2 3) Does the same thing as (cons 1 (cons 2 (cons 3 ()))) 32 (list ’this ’that) Constructs the list (this that) Instead of (list ’this ’that) we could write ’(this that) if we wish 33 LIST functions 34 cons – returns a list where an element has been added first in a list list – returns a new list created of 1 to n elements append – returns a list combined from two lists car – returns the first element from a list cdr – returns a list without the first element (removes the first element from a list) car and cdr can be combined – caddr returns the third element of a list (listref L n) – returns the n+1 element of list L (listref ‘(a b c) 0) -> a (listerf ‘(a b c) 2) -> c LIST functions Result cons element x list list list element x element x … x element list append list x list list car list element cdr list list Recognizing Lists Null? Checks whether we have an empty list List? Tests whether we have a list 36 Arguments 35 Recognizing Lists (null? ()) (list? ()) (null? (list 1 2)) (list? ’(1 2)) Function (null? (list())) is #f (list ()) is the same as (cons () ()) () () is #t is #t is #f is #t 37 6 List of Lists List of Lists The definition of list says nothing about the nature of the elements of the list The elements of a list can be anything, for example, they can be lists themselves ((1 2) (a (b) c)) () ((1 2) (a (b) c)) 1 38 () a () Lists are printed by the system as follows: (1 2 3) (0 1 1 2 3) (6 28) Main List () 2 () Printing Lists ((1 2) (a (b) c)) 1 c b 39 List of Lists 40 2 () Sublists a Sublist of Sublist c b () () 41 List Procedures - Examples Length of a list Computing the length of a list Appending two lists Reversing a list Comparing two lists (define (length L) (cond ((null? L) 0) (else (+ 1 (length (cdr L)))))) We use the same old algorithmic techniques: Break Down the Problem into Cases! 42 43 7 Appending two lists Reversing a list (define (append L1 L2) (cond ((null? L1) L2) (else (cons (car L1) (append (cdr L1) L2))))) 44 (define (reverse L) (if (null? l) () (append (reverse (cdr l)) (list (car l)))))) 45 Comparing Similarity of Lists Comparing Similarity of Lists (define (equal? L1 L2) (cond ((and (null? L1) (null? L2)) #t) ((null? L1) #f) ((null? L2) #f) ((eq? (car L1) (car L2)) (equal (cdr L1) (cdr L2)) (else #f))) 46 (define (equal? L1 L2) (cond ((null? L1) (null? L2)) ((eq? (car L1) (car L2)) (equal (cdr L1) (cdr L2)) (else #f))) 47 Program Patterns: #1 Lists as Sequences Program Patterns: #1 Recursive Processes Two Cases: Empty sequence: () Finite number of elements: (a b c) (DEFINE (FN SEQ) (IF (NULL? SEQ) <null-result> (<operation> (FN (CDR SEQ))))) (define (length seq) (if (null? seq) 0 (length (+ 1 (cdr seq))))) 48 49 8 Program Patterns: #2 Lists as Sequences Program Patterns: #1 Iterative Processes (DEFINE (FN SEQ) (DEFINE (ITER SEQ RESULT) (IF (NULL? SEQ) RESULT (ITER (CDR SEQ) (accum RESULT)))) (ITER SEQ <null-result>)) 50 (define (length seq) (define (iter seq result) (if (null? seq) result (iter (cdr seq) (+ result 1)))) (iter seq 0)) Three Cases: Empty sequence: () The first element has a certain property: (2 a b c) Finite number of elements: (a b c) In fact case pattern #2 is a version of #1 where we separate the treatment of the first element of the list. 51 Program Patterns: #3 Lists of Lists Program Patterns: #2 Recursive Processes (DEFINE (FN SEQ) (COND ((NULL? SEQ) <null-result>) (<condition> <result>) (ELSE (<operation> (FN (CDR SEQ)))))) Three Cases: Empty: () Starts with a list: ((a b) (b c) (d)) General case: (a (b c) (d)) (define (ran seq) ; remove all numbers (ran) from seq (cond ((null? seq)' ()) ((number? (car seq)) (ran (cdr seq))) (else (cons (car seq) (ran (cdr seq)))))) 52 53 Program Patterns: #4 Lists of Lists Program Patterns: #3 Recursive Processes (DEFINE (FN SEQ) (COND ((NULL? SEQ) <null-result>) ((LIST? (CAR SEQ)) (<operation1> (FN (CAR SEQ)) (FN (CDR SEQ)))) (ELSE (<operation2> (FN (CDR SEQ)))))) 54 (define (length seq) (cond ((null? seq) 0) ((list? (car seq)) (+ (length (car seq)) (length (cdr seq)))) (length (+ 1 (cdr seq))))) Four Cases: Empty sequence: () Starts with a list: ((a b) (b c) (d)) The first element has a certain property: (2 a b c) General case: (a (b c) (d)) 55 9 Program Patterns: #4 Recursive Processes Program Patterns: #4 Recursive Processes (DEFINE (FN SEQ) (COND ((NULL? SEQ) <null-result>) ((LIST? (CAR SEQ)) (<operation1> (FN (CAR SEQ)) (FN (CDR SEQ)))) (<condition> <result>) (ELSE (<operation2> (FN (CDR SEQ)))))) (define (ran seq) ; remove all numbers (ran) from seq (cond ((null? seq)' ()) ((list? (car seq)) (cons (ran (car seq)) (ran (cdr seq)))) ((number? (car seq)) (ran (cdr seq))) (else (cons (car seq) (ran (cdr seq)))))) 56 57 Lists as Trees Program Patterns: #4 Lists as Trees ((1 2) (a (b) c)) Three Cases: Empty tree: () Atomic Tree: a General case: ((a b) (b c) (d)) () 1 2 () a c b 58 () () 59 Lists as Trees Program Patterns: #5 Lists as Trees car – returns the left branch of a tree cdr – returns the right branch(es) of a tree atom? – test if the tree is a leaf null? – test if the tree is emprt (DEFINE (FN TREE) (COND ((NULL? TREE) <null-result>) ((ATOM? TREE) <atom-result>) (ELSE (<operation> (FN (CAR TREE)) (FN (CDR TREE)))))) (define (count-leaves tree) (cond ((null? tree) 0) ((atom? tree) 1) (else (+ (count-leaves (car tree)) (count-leaves (cdr tree)))))) 60 61 10 Higher Order Functions for Lists Filter Filter Map Enumerate Accumulate 62 (filter proc L) Applies proc to each element in L (from left to right) and returns a new list that is the same as L, but omitting all the elements for which proc returned #f. 63 Filter Map (define (filter proc L) (cond ((null? L) ‘()) ((list? (car L)) (cons (filter proc (car L)) (filter proc (cdr L)))) ((proc (car L)) (cons (car L) (filter proc (cdr L)))) (else (filter proc (cdr L))))) 64 (map proc L) Map applies proc element-wise to the elements of the list L and returns a list of the results. Scheme’s map can work with many lists 65 Map Enumerate (define (map proc L) (cond ((null? L) ‘()) ((list? (car L)) (cons (map proc (car L)) (map proc (cdr L)))) (else (cons (proc (car L)) (map proc (cdr L)))))) 66 (define (enumerate low high) (cond ((> low high) ‘()) (else (cons low (enumerate (+ low 1) high))))) 67 11 Accumulate (Fold-right) Accumulate (accumulate proc null-value list) -> value Applies proc recursively to the elements in list starting with null-value and the last element (define (accumulate proc null-value L) (cond ((null? L) null-value) ((list? (car L)) (proc (accumulate proc null-value (car L)) (accumulate proc null-value (cdr L)))) (else (proc (car L) (accumulate proc null-value (cdr L)))))) Scheme’s fold-right can work with many lists 68 69 Programs as flow of sequence operations SICP on Data Abstraction Räkna upp de 10 först talen i Fibonacci talserien! (accumulate cons ‘() (map fib (enumerate 0 9))) (0 1 1 2 3 5 8 13 21 34) The basic idea of data abstraction is to structure the programs that are to use compound data objects so that they operate on “abstract data.” That is, our programs should use data in such a way as to make no assumptions about the data that are not strictly necessary for performing the task at hand. At the same time, a “concrete” data representation is defined independent of the programs that use the data. The interface between these two parts of our system will be a set of procedures, called selectors and constructors, that implement the abstract data in terms of the concrete representation. Vad tjänar den högst betalda programmeraren? (accumulate max 0 (map salary (filter programmer? salary-db))) 70 71 Data Abstraction:The Philosophy An Example Base your programs on abstract descriptions of the data, not a specific physical realisation of it Making your programs independent of the physical representation has the advantage of not needing to change your program when the physical representation of the data changes Data abstraction makes our programs easier to read Data abstraction makes top-down design of your programs possible 72 The example will be about families This is what we will do: We’ll write a program without knowing how data about a family is actually stored Then we test the program with two different representations. We’ll see that without changing the program we can get it working with both representation 73 12 Data Abstraction: How? Family Data Example Data abstraction is done by defining the procedures that create data, select from data, (recognize data, change data, and also print data) Abstract Data Types: – Person Name DOB Father Mother Sex – Database Collection of Person 74 75 Family Data Example – Person Family Data Example – Person Primitive procedure – Primitive procedure Constructors – Make-person Name x DOB x Father x Mother x Sex -> Person – 76 Female? Person -> Bool Male? Person -> Bool Selectors Get-name Person -> name Get-dob Person -> DOB Get-father Person -> father Get-mother Person -> mother Get-sex Person -> sex – 77 Family Data Example – Program Primitive procedure (define (sister? n1 n2 db) (let ((p1 (get-person n1 db)) (p2 (get-person n2 db))) (and (female? p1) (have-common-parent? p1 p2)))) Constructors Make-empty-database -> DB Add-person-to-database Person x DB -> DB – Selectors (define (have-common-parent? p1 p2) (or (same-name? (get-father p1) (get-father p2)) (same-name? (get-mother p1) (get-mother p2)))) Get-person DB x name -> Person 78 Comparison Same-name? Person x Person -> Bool Family Data Example – Database – Recognizers 79 13 Family Data Example – Program Family Data Example – data represent 1 (define (grand-father? n1 n2 db) (let* ((kid (get-person n2 db)) (mom (get-person (get-mother kid) db)) (dad (get-person (get-father kid) db))) (or (same-name? n1 (get-father mom)) (same-name? n1 (get-father dad))))) 80 Constructor (define make-person list) ;example (define p (make-person ' carl 57 ' gunnar ' anna ' m)) 81 Family Data Example – data represent 1 Family Data Example – data represent 1 Recognizers (define (female? p) (eq? (get-sex p) ' w)) (define (male? p) (eq? (get-sex p) ' m)) (define (same-name? n1 n2) (eq? n1 n2)) 82 83 Family Data Example – data represent 1 (define DB (list (make-person ' carl 57 ' gunnar ' anna ' m) (make-person ' asa 61 ' lars ' ann-britt ' w) (make-person ' linus 89 ' carl ' asa ' m) (make-person ' linnea 84 ' carl ' asa ' w) (make-person ' eva 59 ' gunnar ' anna ' w) (make-person ' ulrika 65 ' gunnar ' anna ' w) (make-person ' anna 36 ' tage ' gunnel ' w) (make-person ' tage 12 () () ' m) (make-person ' gunnel 19 () () ' w) (make-person ' valborg 15 () () ' w) (make-person ' zachari 9 () () ' m))) Family Data Example – data represent 2 (define (get-person n db) (define (iter db) (cond ((null? db) ()) ((same-name? (get-name (car db)) n) (car db)) (else (iter (cdr db))))) (iter db)) 84 Selectors (define (get-name p) (car p)) (define (get-dob p) (cadr p)) (define (get-father p) (caddr p)) (define (get-mother p) (cadddr p)) (define (get-sex p) (cadddr (cdr p))) Constructor (define (make-person name dob father mother sex) (list (cons ‘name name) (cons ‘dob dob) (cons ‘father father) (cons ‘mother mother) (cons ‘sex sex))) 85 ((name . (carl larsson)) (dob . 570801) (mother . (anna larsson)) (father . (gunnar larsson)) (sex . male)) 14 Association lists Family Data Example – data represent 2 Lists of pairs ((key1 . value1) (key2 . value2) … (keyn . valuen)) (assq ‘key1) returns value1 (assq ‘key0) returns #f 86 Selectors (define (get-name p) (cdr (assq ' name p))) (define (get-dob p) (cdr (assq ‘dob p))) (define (get-father p) (cdr (assq ‘father p))) (define (get-mother p) (cdr (assq ‘mother p))) (define (get-sex p) (cdr (assq ‘sex p))) 87 Family Data Example – data represent 2 Family Data Example – data represent 2 Recognizers (define (female? p) (eq? (get-sex p) ‘female)) (define (male? p) (eq? (get-sex p) ‘male)) (define (same-name? n1 n2) (equal? n1 n2)) 88 (define DB ' (((name . (carl larsson)) (mother . (anna larsson)) (dob . 570801) (sex . male) (father . (gunnar larsson))) ((name . (asa larsson)) (dob . 610112) (sex . female) (mother . (ann-britt jonsson)) (father . (lars jonsson))) …)) 89 Family Data Example – data represent 2 Procedures With Unlimited Number Of Arguments (define (get-person n db) (define (iter db) (cond ((null? db) ()) ((same-name? (get-name (car db)) n) (car db)) (else (iter (cdr db))))) (iter db)) (define (fn . L) …) or (lambda L ...) zero or more arguments (define (fn x . L) …) or (lambda (x . L) ...) at least one argument (define (fn x y . L) …) or (lambda (x y . L) ...) at least two arguments ... The arguments are grouped in a (possible empty) list L 90 91 15 New Syntax: BEGIN Procedures With Unlimited Number Of Arguments (define (my+ . argL) (define (help+ L) (if (null? L) 0 (+ (car L) (help+ (cdr L))))) (help+ argL)) (begin <exp1> <exp2> … <expn>) Evaluates the expression in order and returns the value of the last (define (number-of-args . argL) (define (iter L n) (cond ((null? L) n) (else (iter (cdr L) (+ n 1))))) (iter argL 0)) 92 (begin (display ”(”) (display x) (display ”)”) 93 New Syntax: Implicit BEGIN New Syntax: Implicit BEGIN (if (= a 0) (begin (display ”(”) (display x) (display ”)”) ) (begin (display ”(”) (display y) (display ”)”) )) (define f (lambda () (display ”(”) (display x) (display ”)”))) (cond ((= a 0) (display ”(”) (display x) (display ”)”)) (else (display ”(”) (display y) (display ”)”))) 94 95 Test of Equality Data-Driven Programs A modular way of organizing programs The idea will be illustrated by examples The idea is to tag data and use these tags for dispatching to the right procedure Later on in the course we’ll compare various ways of organizing programs Different sorts of data need different sorts of functions for comparison. In particular: test of equality What do we mean with equality? Do we mean being similar or do we mean being physically the same? = eq? equal? test for same value 96 97 16 Data-Driven Programs Tagging media-dbs-examples.scm Adds information about the type to data ((respect) (aretha franklin) 1967 soul) -> (music (respect) (aretha franklin) 1967 soul) attach-tag get-type get-content Problem 2-4 98 99 Dispatching on type Tagging and Dispatching on types Generalised procedures that works for different types of data Problems Adding new data-types means modifying alla selector procedures Approach not scalable Problem 5 100 101 Packages table-helper.scm Simple procedures for each data-type grouped in packages Store packages independently of each other -> easy to add or remove packages Create generic operations that retrieves appropriate procedures from storage 102 put row x column x item-to-store -> get row x column -> item-to-store display-table -> prints table 103 17 Install-package Generic procedures Define procedure install-type – – Get the type from the tag in the record Get the procedure for the type from the table Apply the procedure to the record Define the procedures Store them in table (put) Evaluate procedure install-type Problem 9-10 Problem 8 104 105 18