Polymorphism Discrete Mathematics and Its Applications Baojian Hua

Slides:



Advertisements
Similar presentations
C and Data Structures Baojian Hua
Advertisements

The C ++ Language BY Shery khan. The C++ Language Bjarne Stroupstrup, the language’s creator C++ was designed to provide Simula’s facilities for program.
Data Structure & Abstract Data Type
C Module System C and Data Structures Baojian Hua
Data Structure & Abstract Data Type C and Data Structures Baojian Hua
Extensible Array C and Data Structures Baojian Hua
CSCI 171 Presentation 11 Pointers. Pointer Basics.
CS113 Introduction to C Instructor: Ioannis A. Vetsikas Lecture 7 : September 8.
Kernighan/Ritchie: Kelley/Pohl:
Memory allocation CSE 2451 Matt Boggus. sizeof The sizeof unary operator will return the number of bytes reserved for a variable or data type. Determine:
1 CS 162 Introduction to Computer Science Chapter 8 Pointers Herbert G. Mayer, PSU Status 11/20/2014.
C12, Polymorphism “many forms” (greek: poly = many, morphos = form)
6/10/2015C++ for Java Programmers1 Pointers and References Timothy Budd.
Structures C and Data Structures Baojian Hua
C For Java Programmers Tom Roeder CS sp. Why C? The language of low-level systems programming  Commonly used (legacy code)  Trades off safety.
Map, Set & Bit-Vector Discrete Mathematics and Its Applications Baojian Hua
Abstract Data Type C and Data Structures Baojian Hua
Memory Arrangement Memory is arrange in a sequence of addressable units (usually bytes) –sizeof( ) return the number of units it takes to store a type.
Dynamically Extensible Data Structures Discrete Mathematics and Its Applications Baojian Hua
C and Data Structures Baojian Hua
Pointers and Arrays C and Data Structures Baojian Hua
Stack C and Data Structures Baojian Hua
C and Data Structures Baojian Hua
C and Data Structures Baojian Hua
Hash Discrete Mathematics and Its Applications Baojian Hua
Extensible Array C and Data Structures Baojian Hua
Extensible Array C and Data Structures Baojian Hua
Linked List C and Data Structures Baojian Hua
Set, Map & Bit-Vector Discrete Mathematics and Its Applications Baojian Hua
Functional List C and Data Structures Baojian Hua
String C and Data Structures Baojian Hua
String C and Data Structures Baojian Hua
C Slides and captured lecture (video and sound) are available at:
Object-oriented Languages Compiler Baojian Hua
Set & Bit-Vector Discrete Mathematics and Its Applications Baojian Hua
Memory Layout C and Data Structures Baojian Hua
Polymorphism C and Data Structures Baojian Hua
Polymorphism Discrete Mathematics and Its Applications Baojian Hua
C++ fundamentals.
Pointers| SCP1103 Programming Technique C | Jumail, FSKSM, UTM, 2005 | Last Updated: September 2006 Slide 1 Pointers by Jumail Bin Taliba Faculty of Computer.
Overview Working directly with memory locations is beneficial. In C, pointers allow you to: change values passed as arguments to functions work directly.
OOP Languages: Java vs C++
Engr 691 Special Topics in Engineering Science Software Architecture Spring Semester 2004 Lecture Notes.
Programming Languages and Paradigms Object-Oriented Programming.
CS 11 C track: lecture 5 Last week: pointers This week: Pointer arithmetic Arrays and pointers Dynamic memory allocation The stack and the heap.
17. ADVANCED USES OF POINTERS. Dynamic Storage Allocation Many programs require dynamic storage allocation: the ability to allocate storage as needed.
Programming Languages and Paradigms Object-Oriented Programming (Part II)
Variables and Objects, pointers and addresses: Chapter 3, Slide 1 variables and data objects are data containers with names the value of the variable is.
Dynamic Memory Allocation Conventional array and other data declarations An incorrect attempt to size memory dynamically Requirement for dynamic allocation.
CSSE501 Object-Oriented Development. Chapter 12: Implications of Substitution  In this chapter we will investigate some of the implications of the principle.
Chapter 0.2 – Pointers and Memory. Type Specifiers  const  may be initialised but not used in any subsequent assignment  common and useful  volatile.
Copyright © Curt Hill Generic Classes Template Classes or Container Classes.
C Programming in Linux Jacob Chan. C/C++ and Java  Portable  Code written in one system and works in another  But in C, there are some libraries that.
Dynamic Memory Allocation. Domain A subset of the total domain name space. A domain represents a level of the hierarchy in the Domain Name Space, and.
Types in programming languages1 What are types, and why do we need them?
Pointers in C Computer Organization I 1 August 2009 © McQuain, Feng & Ribbens Memory and Addresses Memory is just a sequence of byte-sized.
Generic lists Vassilis Athitsos. Problems With Textbook Interface? Suppose that we fix the first problem, and we can have multiple stacks. Can we have.
 Objects versus Class  Three main concepts of OOP ◦ Encapsulation ◦ Inheritance ◦ Polymorphism  Method ◦ Parameterized ◦ Value-Returning.
Computer Organization and Design Pointers, Arrays and Strings in C Montek Singh Sep 18, 2015 Lab 5 supplement.
Polymorphism Discrete Mathematics and Its Applications Baojian Hua
1 Lecture07: Memory Model 5/2/2012 Slides modified from Yin Lou, Cornell CS2022: Introduction to C.
CSE 374 Programming Concepts & Tools Hal Perkins Fall 2015 Lecture 12 – C: structs, linked lists, and casts.
Extensible Tree Discrete Mathematics and Its Applications Baojian Hua
MORE POINTERS Plus: Memory Allocation Heap versus Stack.
DYNAMIC MEMORY ALLOCATION. Disadvantages of ARRAYS MEMORY ALLOCATION OF ARRAY IS STATIC: Less resource utilization. For example: If the maximum elements.
Overview Working directly with memory locations is beneficial. In C, pointers allow you to: change values passed as arguments to functions work directly.
Generic Programming in C
CSE 374 Programming Concepts & Tools
C Basics.
Programming Languages and Paradigms
Presentation transcript:

Polymorphism Discrete Mathematics and Its Applications Baojian Hua

Variables and Types Languages such as C, C++ or Java are called statically-typed As opposed to Basic, Lisp, etc. A relatively strict semantics on variables declaration and use Each variable must be declared with a static type Variables declared before use Uses should conform to types

Examples // Examples from C: int i; i = 99; struct s { int x; int y; }; struct s pt; // compiler complains: i = pt; // Examples from Java: int i; i = 99; class S { int x; int y; } S pt = new S (); // compiler complains: i = pt;

What ’ s Polymorphism? A variable of polymorphic type could hold any type of values poly: various morphism: shapes How to declare and use such kind of variables?

What We Want? // Suppose we have a variable x which is // polymorphic, we may write: x = 99; x = 3.14; x = “hello”; // But how to declare such a variable in // statically typed language such as C? // More specific, what x’s “type” should be? type x;

Difficulties In C C++ or Java, the compiler automatically allocates space for every declared variable the size of that space is calculated statically at compile-time the detailed data layout is determined

Difficulties // Examples: int i; // 4 bytes double f; // 8 bytes struct s { int x; int y; }; struct s pt; // 8 bytes // So it seems that we can never declare such // a polymorphic variable in C …

The Magic The magic is that: if we want to make a variable x hold any type (size) of data d, then the only way is not to put this data d in the variable x.

Try #1 // Hummm, thus x must be a pointer (x holds some // data d, but the data d is not in x itselft--- // via an indirection). // Try #1: int *p; p = (int *)malloc (sizeof(*p)); *p = 88; // but x it seems that p could only point to // integer data (of size 4). // How to make p point to data of other size? p 88

Try #2 // Try #2: make p point to struct data: int *p; // we want to point to a Point2d p = (int *)malloc (sizeof(struct s)); p->x = 3; p->y = 4; // Try this demo … // What happened here? p 3 4

Try #2 // Try #3: let’s cheat the compiler: int *p; p = (int *)malloc (8); ((Point2d *)p)->x = 3; ((Point2d *)p)->y = 4; // Try this demo … p

Moral So, every pointer is essentially a polymorphic value could point to value of any type (and size) the trick is the ugly type conversion (cast) of course, should be consistent But the type “ int * ” is a little misleading But recall C ’ s early convention (char *) now C offers “ void * ” compiler emits more meaningful error message

Void * // The use of “void *” struct s { int x; int y; }; void *p; p = malloc (sizeof (struct s)); ((struct s *)p)->x = 3; ((struct s *)p)->y = 4; // Try this demo … p

Polymorphic Data Structures Structure: relationships linear, tree, graph, hash, … Data structures: relationships between data not the data themselves Polymorphic data structures data are polymorphic Next, I ’ ll take linear list as a running example

Linked List #1 (Integer List) typedef struct linkedListStruct *linkedList; struct linkedListStruct { int data; linkedList next; }; void insertHead (linkedList l, int data); int exists (linkedList l, int data);

Functions void insertHead (linkedList l, int data) { linkedList t = (linkedList)malloc (sizeof (*t)); t->data = data; t->next = l->next; l->next = t; return; } data next data next data next l …

Functions int exists (linkedList l, int data) { linkedList temp = l->next; while (temp) { if (temp->data == data) // equality test! return 1; temp = temp->next; } return 0; } data next data next data next l …

Client Code #include “linkedList.h” … linkedList list = newLinkedList (); for (int i=0; i<10; i++) { insertHead (list, i); } exists (list, 5); exists (list, 50);

Linked List #2 (Double List) typedef struct linkedListStruct *linkedList; struct linkedListStruct { double data; linkedList next; }; void insertHead (linkedList l, double data); int exists (linkedList l, double data);

Functions void insertHead (linkedList l, double data) { linkedList t = (linkedList)malloc (sizeof (*t)); t->data = data; t->next = l->next; l->next = t; return; }

Functions int exists (linkedList l, double data) { linkedList temp = l->next; while (temp) { if (temp->data == data) // equality? return 1; temp = temp->next; } return 0; }

Client Code #include “linkedList.h” … linkedList list = newLinkedList (); for (int i=0; i<10; i++) { insertHead (list, (double)i); } exists (list, 5.0); exists (list, 50.0);

Linked List #3 (Point List) typedef struct linkedListStruct *linkedList; struct linkedListStruct { struct s data; linkedList next; }; void insertHead (linkedList l, struct s data); int exists (linkedList l, struct s data);

Functions void insertHead (linkedList l, struct s data) { linkedList t = (linkedList)malloc (sizeof (*t)); t->data = data; t->next = l->next; l->next = t; return; }

Functions int exists (linkedList l, struct s data) { linkedList temp = l->next; while (temp) { if (temp->data == data) // equality? return 1; temp = temp->next; } return 0; }

Client Code #include “linkedList.h” … linkedList list = newLinkedList (); for (int i=0; i<10; i++) { insertHead (list, cookPoint(i, i*i)); } struct s pt1 = cookPoint (5, 5*5); struct s pt2 = cookPoint (50, 50*50); exists (list, pt1); exists (list, pt2);

Linked List #4: polymorphic list typedef void *poly; typedef struct linkedListStruct *linkedList; struct linkedListStruct { poly data; linkedList next; }; void insertHead (linkedList l, poly data); int exists (linkedList l, poly data);

Functions void insertHead (linkedList l, poly data) { linkedList t = (linkedList)malloc (sizeof (*t)); t->data = data; t->next = l->next; l->next = t; return; }

Functions int exists (linkedList l, poly data) { linkedList temp = l->next; while (temp) { if (temp->data == data) // Correct??? return 1; temp = temp->next; } return 0; }

Client Code #1 #include “linkedList.h” … linkedList list = newLinkedList (); for (int i=0; i<10; i++) { insertHead (list, ???); } We should turn data into a pointer, and link the pointer here!

Client Code #1 // “integers” list #include “linkedList.h” … linkedList list = newLinkedList (); int *p; for (int i=0; i<10; i++) { p = (int *)malloc (sizeof (*p)); *p = i; insertHead (list, p); }

Client Code #1 // “integers” list #include “linkedList.h” … linkedList list = newLinkedList (); int *p; for (int i=0; i<10; i++) { p = (int *)malloc (sizeof (*p)); *p = i; insertHead (list, p); } p = (int *)malloc (sizeof (int)); *p = 5; exists (list, p);

Client Code #2 // “doubles” list #include “linkedList.h” … linkedList list = newLinkedList (); double *p; for (int i=0; i<10; i++) { p = (double *)malloc (sizeof (*p)); *p = (double)i; insertHead (list, p); }

Client Code #3 // “point” list #include “linkedList.h” … linkedList list = newLinkedList (); struct s *p; for (int i=0; i<10; i++) { p = (struct s *)malloc (sizeof (*p)); *p = cookPoint (i, i*i); insertHead (list, p); } // The burden is shifted to the client code!

Pros. and Cons. of Polymorphism Pros: code reuse: write once, use in arbitrary contexts ADT: data structures won ’ t change client data (won ’ t know) Cons: Inconsistency (safety issues) Complexity Efficiency We ’ d discuss cons. issues next

Problem #1: Inconsistency (Safety Issues) #include “linkedList.h” … linkedList list = newLinkedList (); int *p; for (int i=0; i<10; i++) { p = (int *)malloc (sizeof (int)); *p = i; insertHead (list, p); } // Can we do this? double *f = (double *)listGetHeadData (list); // ever worse: void (*fp)() = (void (*)())listGetHeadData (list); fp ();

Cure to Problem #1: Inconsistency (Safety Issues) C has no built-in static or dynamic checking against such inconsistency Runtime error segment fault, core dumped, Or even worse C programmers ’ duty to prevent these! Important: always keep invariants of our data structures in mind! Ask yourself: what ’ s the type?

Problem #2: Complexity int exists (linkedList l, void *data) { linkedList temp = l->next; while (temp) { if (temp->data == data) // Right??? return 1; temp = temp->next; } return 0; }

Equality Testing // Recall the definition of polymorphic variables: void *p, *q; // We want to write a function int equals (void *p, void *q); // to compare Contents! Not address! // How to implement this? pq

Try #1 int equals (void *p, void *q) { return (p==q); // right? } pq

Try #2 int equals (void *p, void *q) { return (*p==*q); // right? } pq

Try #3: Comparing Function Pointer as Argument typedef int (*eqTy) (void *, void *); int equals (void *p, void *q, tyEq eq) { return (eq (p, q)); } pq

Client Code int compareInt (void *p, void *q) { return *((int *)p)==*((int *)q); } //////////////////////////////////////// int *p = (int *)malloc (sizeof (*p)); *p = 9; int *q = (int *)malloc (sizeof (*q)); *q = 9; equals (p, q, compareInt);

Client Code int comparePoint2d (void *p, void *q) { return (p->x==q->x && p->y==q->y); } //////////////////////////////////////// struct s *x = (struct s *)malloc (sizeof (*x)); *x = …; struct s *y = (struct s *)malloc (sizeof (*y)); *y = …; equals (x, y, comparePoint2d); // A mimic of so-called “callback”.

Try #4: Function Pointers in Data int equals (void *p, void *q) { return (p->eq (p, q)); } pq eq

Point2d Revisited struct Point2d { int (*eq) (void *, void *); int x; int y; }; eq x y

Point2d Revisited struct Point2d *newPoint2d (int x, int y) { struct Point2d *p; p = (struct Point2d *)malloc (sizeof (*p)); p->x = x; p->y = y; p->eq = point2dEquals; return p; } eq x y p

Point2d Revisited int point2dEquals (void * pt1, void *pt2) { struct Point2d *p = (struct Point2d *)pt1; struct Point2d *q = (struct Point2d *)pt2; return ((p->x == q->x) && (p->y == q->y)); }

Try #4: Function Pointers in Data int equals (void *p, void *q) { return (p->eq (p, q)); } pq eq Commonly known as Object-oriented programming (OOP)

Problem #3: Efficiency // integer list #include “linkedList.h” … linkedList list = newLinkedList (); for (int i=0; i<10; i++) { insertHead (list, i); } // “integer” list #include “linkedList.h” … linkedList list = newLinkedList (); int *p; for (int i=0; i<10; i++) { p = (int *)malloc (4); *p = i; insertHead (list, p); }

Boxed Data Polymorphism does not come free data mostly heap-allocated, to cope with the “ void * ” pointer convention makes memory management expensive It ’ s programmers ’ duty to recycle garbage Such kind of data are called “ boxed ” and “ void * ” is essentially a mask difficulty of reallocation popularized the technology of garbage collection

Extension to other Languages Two flavors of polymorphism so far: ad-hoc void * They are important in that they motivate ideas for “ advanced ” features in other language Next, we ’ d discuss how C++ and Java reflect this observation and I ’ ll also use linked list as running example After that, you should be able to give some comment

Case Study Essentially, in C++ or Java, we could also use some form of “ void * ” C++ even supports that directly But we concentrate on: C++ Template Java Generic

Linked List Template #ifndef LINKED_LIST_H #define LINKED_LIST_H template class LinkedList { public: X data; LinkedList *next; void insertHead (X data); int exists (X data); }; // function on next slides… #endif

… and Functions // Note: these code is in same.h file as above! template void LinkedList ::insertHead (X data) { LinkedList *temp = new LinkedList (); temp->data = data; temp->next = this->next; this->next = temp; return; }

… and Functions // Note: these code is in same.h file as above! template int LinkedList ::exists (X data) { LinkedList *temp = this->next; while (temp) { if (temp->data == data) return 1; temp = temp->next; } return 0; }

Client Code #include “linkedList.h” int main () { LinkedList *p = …; LinkedList *q = …; for (int i=0; i<10; i++) p->insertHead (i); p->exists (5); q->exists (3.14); }

What ’ s a Template? template class LinkedList { public: X data; LinkedList *next; }; // which results in (roughly): class LinkedList_int { public: int data; LinkedList_int *next; }; class LinkedList_double { public: double data; LinkedList_double *next; };

Static Monomorphization Program code are duplicated Exponential in theory (code blowing) Seldom observed in practice Separate compilation is lost The template ’ s interface can not be compiled alone and the implementation is exposed

Template Rethink the ad-hoc poly in C Any difference? Rethink the problem of poly in C, does template also incur these problems? Why or why not? Security (inconsistency) Complexity Efficiency

Case Study C++ Template Java Generic

void * ≈ Object // In C void *p; p = (int *)malloc (sizeof(int)); *p = 99; … printf (“%d\n”, *p); equals (p, q, intEq); // In Java Object p; p = new Integer (99); … System.out.println (((Integer)p).intValue ()); p.equals (q);

Linked List in Java class LinkedList { Object data; LinkedList next; void insert (Object data) {…} Object getFirst () {…} }

Client Code LinkedList list = new LinkedList (); for (int i=0; i<10; i++) list.insert (new Integer (i)); // Also Ok for a list of strings: for (int i=0; i<10; i++) list.insert (new String (“hello”));

Problem #1: Inconsistency (Safety Issues) LinkedList list = new LinkedList (); for (int i=0; i<10; i++) list.insert (new Integer (i)); // compile-time error String s = list.getFirst ();

Problem #1: Inconsistency (Safety Issues) LinkedList list = new LinkedList (); for (int i=0; i<10; i++) list.insert (new Integer (i)); // shut up the compiler, but raise run-time // exception: String s = (String)list.getFirst ();

Cure to Problem #1: Generic class LinkedList { X data; LinkedList next; void insert (X data) {…} X getFirst () {…} }

Use of Generic LinkedList list = new LinkedList (); for (int i=0; i<10; i++) list.insert (new Integer (i)); // compile-time error list.insert (new String (“hello”));

Cure to Problem #1: Use of Generic LinkedList list = new LinkedList (); for (int i=0; i<10; i++) list.insert (new Integer (i)); // compile-time error list.insert (new String (“hello”)); // compile-time error String s = list.getFirst ();

Problem #2: Complexity // Turn back to “equals ()” function int equals (Object p, Object q); // How to implement this? pq

Cure to Problem #2: Dynamic Method Dispatch Every class has an “ equals ” method, the call to “ equals ” is automatically dispatched to the correct one in the current called object. (virtual functions) pq eq

Problem #3: Efficiency Nearly all data in Java are boxed objects typically heap-allocated Rely on garbage collection to recycle dead objects user have little control on this used in embedded system?