PPL Pairs, lists and data abstraction. Data Abstraction? An interface: separate implementation from usage Think of the Map interface in Java: we know.

Slides:



Advertisements
Similar presentations
Chapter 7. Binary Search Trees
Advertisements

מבוא מורחב למדעי המחשב בשפת Scheme תרגול 5. 2 List Utilities Scheme built-in procedures –(list x y z...) –(list-ref lst index) –(length lst) –(append.
Lisp. Versions of LISP Lisp is an old language with many variants Lisp is alive and well today Most modern versions are based on Common Lisp LispWorks.
ML Datatypes.1 Standard ML Data types. ML Datatypes.2 Concrete Datatypes  The datatype declaration creates new types  These are concrete data types,
Lists in Lisp and Scheme a. Lists are Lisp’s fundamental data structures, but there are others – Arrays, characters, strings, etc. – Common Lisp has moved.
Getting started with ML ML is a functional programming language. ML is statically typed: The types of literals, values, expressions and functions in a.
Functional Programming. Pure Functional Programming Computation is largely performed by applying functions to values. The value of an expression depends.
Lambda Calculus and Lisp PZ03J. Lambda Calculus The lambda calculus is a model for functional programming like Turing machines are models for imperative.
מבוא מורחב 1 Lecture #7. מבוא מורחב 2 The rational number abstraction Wishful thinking: (make-rat ) Creates a rational number (numer ) Returns the numerator.
(define applicative-eval (lambda (exp) (cond ((atomic? exp) (eval-atomic exp)) ((special-form? exp) (eval-special-form exp)) ((list-form? exp) (eval-list.
Lisp. Versions of LISP Lisp is an old language with many variants –LISP is an acronym for List Processing language Lisp is alive and well today Most modern.
Functional programming: LISP Originally developed for symbolic computing Main motivation: include recursion (see McCarthy biographical excerpt on web site).
Data Abstraction… The truth comes out…. What we’re doing today… Abstraction ADT: Dotted Pair ADT: List Box and Pointer List Recursion Deep List Recursion.
CS 330 Programming Languages 11 / 20 / 2007 Instructor: Michael Eckmann.
6.001 SICP SICP Sections 5 & 6 – Oct 5, 2001 Quote & symbols Equality Quiz.
מבוא מורחב - שיעור 81 Lecture 8 Lists and list operations (continue).
Functional programming: LISP Originally developed for symbolic computing First interactive, interpreted language Dynamic typing: values have types, variables.
PPL Pairs, lists and data abstraction. Compound Data Until now: atomic, unrelated entities Now: organized into structures Why? – Better conceptual level.
Spring 2008Programming Development Techniques 1 Topic 6 Hierarchical Data and the Closure Property Section September 2008.
CSC3315 (Spring 2009)1 CSC 3315 Programming Paradigms Scheme Language Hamid Harroud School of Science and Engineering, Akhawayn University
1 Append: process  (append list1 list2) (cons 1 (append ‘(2) list2)) (cons 1 (cons 2 (append ‘() list2))) (cons 1 (cons 2 list2)) (define (append list1.
Practice session #6: 1. Sequence operations 2. Partial evaluation with currying 3. Lazy-lists.
1 Subt. model interpreter: Structure of the interpreter ASP Derived expressions Core Test Data structures Utils A racket lib Proc / Primitive-Proc. Global.
COP4020 Programming Languages Functional Programming Prof. Xin Yuan.
1 You’re Invited! Course VI Freshman Open House! Friday, April 7, :30-5:00 PM FREE Course VI T-Shirts (while supplies last) and Department.
18-October-2002cse Symbols © 2002 University of Washington1 Symbols CSE 413, Autumn 2002 Programming Languages
Ceg860 (Prasad)LADT1 Specification and Implementation of Abstract Data Types Algebraic Techniques.
CS535 Programming Languages Chapter - 10 Functional Programming With Lists.
1 Subt. model interpreter: Introduction Abstract Syntax Parser Abstract Syntax Parser Derived Expressions Core Test Data Structures Utils (a racket lib)
PPL Lazy Lists. Midterm 2012 (define sum-vals (λ (ts) (if (ts-simple? ts) (ts-val ts) (accumulate + 0 (map ts-val (ts-inner-slots ts))))))
1 Data Abstraction. Pairs and Lists. (SICP Sections – 2.2.1)
PPL CPS. Moed A 2007 Solution (define scale-tree (λ (tree factor) (map (λ (sub-tree) (if (list? sub-tree) (scale-tree sub-tree factor) (* sub-tree.
מבוא מורחב למדעי המחשב בשפת Scheme תרגול 8. Outline 1.The special form quote 2.Data abstraction: Trie 3.Alternative list: Triplets 4.Accumulate-n.
1 FP Foundations, Scheme In Text: Chapter Chapter 14: FP Foundations, Scheme Mathematical Functions Def: A mathematical function is a mapping of.
PPL CPS. Moed A 2007 Solution (define scale-tree (λ (tree factor) (map (λ (sub-tree) (if (list? sub-tree) (scale-tree sub-tree factor) (* sub-tree.
CS 152: Programming Language Paradigms February 12 Class Meeting Department of Computer Science San Jose State University Spring 2014 Instructor: Ron Mak.
Principles Of Programming Languages Lecture 2 Today Design-By-Contract Data Structures: Lists and Pairs Iteration vs. Recursion If we have time: live.
Abstraction A way of managing complexity for large programs A means of separating details of computation from use of computation Types of Abstraction Data.
Additional Scheme examples
Edited by Original material by Eric Grimson
Representing Sets (2.3.3) Huffman Encoding Trees (2.3.4)
Pairs and Lists. Data Abstraction. SICP: Sections – 2.2.1
PPL Lecture Notes: Chapter 3 High-Order Procedures Revisited.
PPL Lazy Lists.
Introduction to Scheme
Algebraic Specifications
Lists in Lisp and Scheme
COP4020 Programming Languages
Env. Model Implementation
The Metacircular Evaluator
PPL Sequence Interface.
The Metacircular Evaluator
Lecture #8 מבוא מורחב.
CS 36 – Chapter 11 Functional programming Features Practice
Chapter 4 Data and Behavior Abstraction
The Metacircular Evaluator (Continued)
Lecture #9 מבוא מורחב.
Binary Search Trees Chapter 9 2/22/2019 B.Ramamurthy.
Data Mutation Primitive and compound data mutators set! for names
topics mutable data structures
Binary Search Trees Chapter 9 2/24/2019 B.Ramamurthy.
6.001 SICP Data Mutation Primitive and Compound Data Mutators
6.001 SICP Data abstractions
Announcements Quiz 5 HW6 due October 23
Lecture #7 מבוא מורחב.
List and list operations (continue).
Functional Programming: Lisp
6.001 SICP Interpretation Parts of an interpreter
Lecture # , , , , מבוא מורחב.
Lisp.
Presentation transcript:

PPL Pairs, lists and data abstraction

Data Abstraction? An interface: separate implementation from usage Think of the Map interface in Java: we know how to use it, but we don’t know how it’s implemented. Motivation: better software design, modularity, less maintenance and more!

Data Abstractions in Scheme? Of course, but first we need to present 2 new data types in Scheme: – Pairs – Lists

Pairs Combines two data entities into a single unit Scheme provides built in primitives: – Value constructor: cons – Selectors: car, cdr – Identify predicate: pair? – Equality: equal?

Pairs > (define x (cons 1 2)) > (car x) 1 > (cdr x) 2 > x (1. 2) “toString” of pair

Pairs Each data entity can be anything! > (define y (cons x (quote a))) > (car y) (1. 2) > (cdr y) 'a > y ((1. 2). a) Recall that x is the pair (cons 1 2)

Pairs Do not confuse (cons 1 2) with (1. 2) !! 1 st is a Scheme expression (syntax) and 2 nd is the ‘toString’ of the value

Pairs Type constructor: PAIR [T 1 *T 2 -> PAIR(T 1,T 2 )] (λ (x y) (cons x y))

Recursive Pairs (define rec-pairs (λ (n) (if (= n 1) 1 (cons n (rec-pairs (- n 1)))))) > (rec-pairs 5) ( ) ;(cons 5 (cons 4 (cons 3 (cons 2 (cons 1)))))

Recursive Pairs We can also represent binary trees! (cons (cons 1 2) (cons (cons 3 4) (cons 5 6))) ((1. 2) (3. 4) 5. 6)

Recursive Pairs We have trees! How about searching a tree? (define member ? (lambda (el pair) (cond ((and (pair? (car pair)) (member? el (car pair))) #t) ((eq? el (car pair)) #t) ((and (pair? (cdr pair)) (member? el (cdr pair))) #t) ((eq? el (cdr pair)) #t) (else #f))))

Recursive Pairs How about counting number of leaves? (define count-leaves (λ (t) (if (not (pair? t)) 1 (+ (count-leaves (car t)) (count-leaves (cdr t))))))

Visual Representation

Lists Finite sequence  (v 1 … v n ) v 1 is head, (v 2 … v n ) is tail Value constructors: cons and list – Empty: (list) – Non-empty: (cons head tail) – tail must be a list! (list e 1 … e n )

Lists Both will create the same list: (list 1 2 3) (cons 1 (cons 2 (cons 3 (list))))

Lists Selectors: – car : head – cdr : tail Predicates: – list? – null? – equal?

Visual Representation

Lists and Types Homogenous – Examples: (1 2 3), ((1 2) (3)) – LIST(Number), LIST(T), … Heterogeneous – Examples: (1 #f 3), ((1 2) 3) – LIST

Useful List Operations car + cdr: > (define x (list )) > (car x) 5 > (cdr x) (6 8 2) > (car (cdr x)) 6 > (cadr x) 6 > (cddr x) (8 2)

Selector: list-ref n th element of a list: (define list-ref (λ (l n) (if (= n 0) (car l) (list-ref (cdr l) (- n 1))))) (define squares (list )) (list-ref squares 4)

Operator: length (define length (λ (l) (if (null? l) 0 (+ 1 (length (cdr l)))))) (define squares (list )) (length squares) 6

Iterative length (define length (λ (l) (letrec ((iter (λ (l c) (if (null? l) c (iter (cdr l) (+ c 1)))))) (iter l 0))))

Operator: append (define append (λ (l1 l2) (if (null? l1) l2 (cons (car l1) (append (cdr l1) l2))))) (append (list 1 2 3) (list 3 4))

Iterative append ;; Type: [LIST * LIST -> LIST] (define append (λ (l1 l2) (letrec ((iter (λ (l1 l2 c) (if (null? l1) (c l2) (iter (cdr l1) l2 (λ (app-cdr-l1) (c (cons (car l1) app-cdr-l1)))))))) (iter l1 l2 (lambda (x) x)))))

Constructor make-list Builds a list of given with given values (define make-list (λ (l v) (if (= l 0) (list) (cons v (make-list (- l 1) v)))))

Using Lists to Represent Trees Very much like pairs, but better: – Empty tree () – Leaf is just value – Non-empty tree – non-empty list Example: (1 (2 3)) is the tree:

Using Lists to Represent Trees How can we add data to non-leaf nodes? (i.e. labeled tree) : each node is also a list! ((1) ((2) (3))) Now we can create labled trees: (1 (0) (3 (2) (4)))

Leaves Count Unlabeled tree (define count-leaves (λ (t) (cond ((null? t) 0) ((not (list? t)) 1) (else (+ (count-leaves (car t)) (count-leaves (cdr t)))))))

Type Correctness with Pairs and Lists cons and list are primitives (not special forms!) So we need more axioms.

Pairs For every type environment _Tenv and type expressions _S,_S 1,_S 2 : Tenv |- cons:[S 1 *S 2 -> PAIR(S 1,S 2 )] Tenv |- car:[PAIR(S 1,S 2 ) -> S 1 ] Tenv |- cdr:[PAIR(S 1,S 2 ) -> S 2 ] Tenv |- pair?:[S -> Boolean] Tenv |- equal?:[PAIR(S 1,S 2 )*PAIR(S 3,S 4 ) -> Boolean]

Homogenous Lists For every type environment Tenv and type expression S: Tenv |- list:[Empty -> LIST(S)] Tenv |- list:[S*...*S -> LIST(S)] n >0 Tenv |- cons:[S*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]

Heterogeneous Lists For every type environment Tenv and type expression S: Tenv |- list:[Empty -> 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]

What About Data Abstraction? An interface: separation between usage (client) and implementation (supplier) Supplier gives getters, setters and other operators, and client uses them. Order of development: 1.Client level 2.Supplier level

ADT It’s a new type with a difference: type is semantic while ADT is syntactic Signature of constructor Signature of operators Invariants (see later)

So Why start with Pairs and Lists? Pairs and lists will be our implementation! The client will not know we used pairs and lists, she will just use the operations we give her! Example next slide

Binary Tree ADT: Constructors Signature: make-binary-tree(l,r) Purpose: Returns a binary tree whose left sub- tree is l and whose right sub-tree is r Type: [Binary-Tree*Binary-Tree -> Binary-Tree] Pre-condition: binary-tree?(l) and binary- tree?(r) Signature: make-leaf(d) Purpose: Returns a leaf binary-tree whose data element is d Type: [T -> Binary-Tree]

Binary Tree ADT: Selectors Signature: left-tree(r), right-tree(r) Purpose: (left-tree ): Returns the left sub- tree of the binary-tree. (right-tree ): Returns the right sub-tree of the binary-tree. Type: [Binary-Tree -> Binary-Tree] Pre-condition: composite-binary-tree?(t) Signature: leaf-data(r) Purpose: Returns the data element of the leaf binary-tree. Type: [Binary-Tree -> T] Pre-condition: leaf?(t)

Binary Tree ADT: Predicates Signature: leaf?(t) Type: [T -> Boolean] Post-condition: true if t is a leaf -- constructed by make-leaf Signature: composite-binary-tree?(t) Type: [T -> Boolean] Post-condition: true if t is a composite binary-tree -- constructed by make-binary-tree Signature: binary-tree?(t) Type: [T -> Boolean] Post-condition: result = (leaf?(t) or composite-binary-tree?(t) ) Signature: equal-binary-tree?(t1, t2) Type: [Binary-Tree*Binary-Tree -> Boolean]

Binary Tree ADT: Invariants leaf-data(make-leaf(d)) = d left-tree(make-binary-tree(l,r)) = l right-tree(make-binary-tree(l,r)) = r leaf?(make-leaf(d)) = true leaf?(make-binary-tree(l,r)) = false composite-binary-tree?(make-binary- tree(l,r)) = true composite-binary-tree?(make-leaf(d)) = false

Binary Tree ADT: Client Level ;Signature: count-leaves(tree) ;Purpose: Count the number of leaves of ’tree’ ;Type: [binary-Tree -> number] (define count-leaves (lambda (tree) (if (composite-binary-tree? tree) (+ (count-leaves (left-tree tree)) (count-leaves (right-tree tree))) 1)))

Binary Tree ADT: Implementation ;Signature: make-binary- tree(l,r) ;Type: [(LIST union T1)*(LIST union T2) ; -> LIST] ;Pre-condition: binary-tree?(l) ; and binary-tree?(r) (define make-binary-tree (lambda (l r) (list l r))) ;Signature: make-leaf(d) ;Type: [T -> T] (define make-leaf (lambda (d) d)) ;Signature: left-tree(t) ;Type: [LIST -> LIST union T] ;Pre-condition: composite- binary-tree?(t) (define left-tree (lambda (t) (car t))) ;Signature: right-tree(t) ;Type: [LIST -> LIST union T] ;Pre-condition: composite- binary-tree?(t) (define right-tree (lambda (t) (cadr t)))

Binary Tree ADT: Implementation ;Signarture: leaf-data(t) ;Type: [T -> T] ;Pre-condition: leaf?(t) (define leaf-data (lambda (t) t)) ;Signarture: leaf?(t) ;Type: [T -> Boolean] (define leaf? (lambda (t) #t)) ;Signarture: composite-binary-tree?(t) ;Type: [T -> Boolean] (define composite-binary-tree? (lambda (t) (and (list? t) (list? (cdr t)) (null? (cddr t)) (binary-tree? (left-tree t)) (binary-tree? (right-tree t)))

Binary Tree ADT: Invariants Seems ok, but look: > (leaf? (make-leaf (list 5 6))) #t > (has-leaf? (list 5 6) (make-leaf (list 5 6))) #f We have no way to distinct composite leaves from tree… We need a better implementation: tagged-data!

Tagged Data ADT Signature: attach-tag(x,tag) Purpose: Construct a tagged- data value Type: [T*Symbol -> Tagged- data(T)] Signature: get-tag(tagged) Purpose: Select the tag from a tagged-data value Type: [Tagged-data(T) -> Symbol] Signature: get-content(tagged) Purpose: Select the data from a tagged-data value Type: [Tagged-data(T) -> T] Signature: tagged-data?(datum) Purpose: Identify tagged-data values Type: [T -> Boolean] Signature: tagged-by? (tagged,tag) Purpose: Identify tagged-data values Type: [T*Symbol -> Boolean]

Binary Tree ADT: Implementation using Tagged-Data ;Signature: make-binary-tree(l,r) ;Type: [(LIST union T1)*(LIST union T2) ; -> Tagged-data(LIST)] ;Pre-condition: binary-tree?(l) ; and binary-tree?(r) (define make-binary-tree (lambda (l r) (attach-tag (list l r) ’composite-binary-tree))) ;Signature: make-leaf(d) ;Type: [T -> Tagged-data(T)] (define make-leaf (lambda (d) (attach-tag d ’leaf))) ;Signature: left-tree(t) ;Type: [Tagged-data(LIST) ; -> Tagged-data(LIST union T)] ;Pre-condition: composite-binary- tree?(t) (define left-tree (lambda (t) (car (get-content t)))) ;Signature: right-tree(t) ;Type: [Tagged-data(LIST) -> Tagged-data(LIST union T)] ;Pre-condition: composite-binary- tree?(t) (define right-tree (lambda (t) (cadr (get-content t))))

Tagged-Data Implementation Have you noticed that we didn’t implement the tagged-data ADT? That’s the whole idea! We are clients! We don’t have to know the implementation! But we’ll give it anyway…

Tagged-Data ADT Implementation ;Signature: attach-tag(x,tag) ;Type: [Symbol*T -> PAIR(Symbol, T)] (define attach-tag (λ (x tag) (cons tag x))) ;Signature: get-tag(tagged) ;Type: PAIR(Symbol,T) -> Symbol (define get-tag (λ (tagged) (car tagged))) ;Signature: get-content(tagged) ;Type: [PAIR(Symbol,T) -> T] (define get-content (λ (tagged) (cdr tagged))) ;Signature: tagged-data?(datum) ;Type: [T -> Boolean] (define tagged-data? (λ (datum) (and (pair? datum) (symbol? (car datum))))) ;Signature: tagged-by?(tagged,tag) ;Type: [T*Symbol -> Boolean] (define tagged-by? (λ (tagged tag) (and (tagged-data? tagged) (eq? (get-tag tagged) tag))))