Presentation is loading. Please wait.

Presentation is loading. Please wait.

Polymorphism Discrete Mathematics and Its Applications Baojian Hua

Similar presentations


Presentation on theme: "Polymorphism Discrete Mathematics and Its Applications Baojian Hua"— Presentation transcript:

1 Polymorphism Discrete Mathematics and Its Applications Baojian Hua bjhua@ustc.edu.cn

2 Variables and Types Languages such as C or Java have a relative strict semantics to variables use Each variable has a static (declared) type Variables declared before use

3 Examples // Examples from C: int i; i = 99; double f; f = 3.14; // compiler complains i = f; // Examples from Java: class A{} class B{} A a; a = new A (); // compiler complains a = new B();

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

5 What We Want? // Suppose a variable x is polymorphic, we want // to write: x = 99; x = 3.14; x = “hello”; // But how to declare such a variable in // statically typed language as C? // What the “type” of x should be? type x;

6 Difficulties In C or Java, compiler automatically allocates space for every declared variable And the size of that space is calculated statically (at compile-time).

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

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

9 The Magic // Hummm, thus x must be a pointer (x holds some // data d, but the data d is not in x---an // indirection). // Try #1: int *x; x = malloc (sizeof(int)); *x = 88; // but x could only points to data of size 4 // How to make x point to other sized data? x 88

10 The Magic // Try #2: make x point to float data: int *x; x = malloc (8); *x = 3.14; // Try this demo … // What happened here? *x = 3.14; x

11 The Magic // Try #3: let’s cheat the compiler: int *x; x = malloc (8); *((double *)x) = 3.14; // Try this demo … x

12 The Magic // Try #4: a structure: struct s { int i; double f; }; int *x; x = malloc (sizeof (struct s)); ((struct s *)x)->i = 3; ((struct s *)x)->f = 3.14; // Try this demo … x

13 Moral So, every pointer is essentially a polymorphic value could point to any type (size) of value the trick is ugly type conversion Every time we want a polymorphic variable, we declare an arbitrary pointer type But the “ int * ” is a little misleading C ’ s early convention (char *) now it offers “ void * ” compiler emits more meaningful error message

14 Void * // The use of “void *” struct s { int i; double f; }; void *x; x = malloc (sizeof (struct s)); ((struct s *)x)->i = 3; ((struct s *)x)->f = 3.14; // Try this demo … x

15 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

16 Linear List (Linked-based) // a list of integers: typedef struct linkedList *linkedList; struct linkedList { int data; linkedList next; }; void insertHead (linkedList l, int data); int lookup (linkedList l, int data);

17 Linear List (Linked-based) // implementation of “insertHead” void insertHead (linkedList l, int data) { linkedList temp = malloc (sizeof (*temp)); temp->data = data; temp->next = l->next; l->next = temp; return; }

18 Linear List (Linked-based) // implementation of “lookup” int lookup (linkedList l, int data) { linkedList temp = l->next; while (temp) { if (temp->data == data) // note equality! return 1; temp = temp->next; } return 0; }

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

20 Linear List (Linked-based) // another linked list of doubles: typedef struct linkedList *linkedList; struct linkedList { double data; linkedList next; }; void insertHead (linkedList l, double data); int lookup (linkedList l, double data);

21 Linear List (Linked-based) // implementation of “insertHead” void insertHead (linkedList l, double data) { linkedList temp = malloc (sizeof (*temp)); temp->data = data; temp->next = l->next; l->next = temp; return; } // See? Code duplicated!

22 Linear List (Linked-based) // implementation of “lookup” int lookup (linkedList l, double data) { linkedList temp = l->next; while (temp) { if (temp->data == data) // note equality! return 1; temp = temp->next; } return 0; } // See? Code duplicated!

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

24 Linear List (Linked-based) // a polymorphic linked list: typedef struct linkedList *linkedList; struct linkedList { void *data; linkedList next; }; void insertHead (linkedList l, void *data); int lookup (linkedList l, void *data);

25 Linear List (Linked-based) // implementation of “insertHead” void insertHead (linkedList l, void *data) { linkedList temp = malloc (sizeof (*temp)); temp->data = data; temp->next = l->next; l->next = temp; return; }

26 Linear List (Linked-based) // implementation of “lookup” int lookup (linkedList l, void *data) { linkedList temp = l->next; while (temp) { if (temp->data == data) // Right??? return 1; temp = temp->next; } return 0; }

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

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

29 Client Code // a list of “doubles” #include “linkedList.h” … linkedList list = newLinkedList (); void *p; for (int i=0; i<10; i++) { p = malloc (8); *((double *)p) = 3.14; insertHead (list, p); } // The burden is lifted to user of linkedList!

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

31 Problem #1: Inconsistency (Safety Issues) #include “linkedList.h” … linkedList list = newLinkedList (); void *p; for (int i=0; i<10; i++){ p = malloc (4); *((int *)p) = i; insertHead (list, p); } double *f = listGetHead (list); // ever worse: int (*p)() = listGetHead (list); (*p) ();

32 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 In C. It ’ s programmers ’ duty to guarantee this! Important: always keep your data structure invariants in mind!

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

34 Problem #2: Complexity // Recall the definition of polymorphic variables: void *p, *q; // We want to write a function “equals ()” int equals (void *x, void *y); // How to implement this? xy

35 Problem #2: Complexity // Try #1: int equals (void *x, void *y) { return (x==y); // right? } xy

36 Problem #2: Complexity // Try #2: int equals (void *x, void *y) { return (*x==*y); // right? } xy

37 Cure to Problem #2: Extra Comparing Function // Try #2: typedef int (*tyEq) (void *, void *); int equals (void *x, void *y, tyEq eq) { return (eq (x, y)); } xy

38 Client Code int comp (void *p, void *q){ return (*p==*q); } //////////////////////////////////////// void *x = malloc (4); *x = 9; void *y = malloc (4); *y = 9; equals (x, y, comp);

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

40 Cure to Problem #2: Function Pointers in Data int equals (void *x, void *y) { return (x->eq (x, y)); } xy eq Essential features of OO programming!

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

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

43 A Glimpse on Other Forms of Polymorphism // In C void *p; p = malloc (4); *((int *)p) = 99; … printf (“%d\n”, *((int *)p)); equals (p, q, eq); // In Java Object p; p = new Integer (99); … System.out.println (((Integer)p).intValue ()); p.equals (q);

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

45 Client Code import util.LinkedList; LinkedList list = new LinkedList (); for (int i=0; i<10; i++) list.insert (new Integer (i)); // Or: for (int i=0; i<10; i++) list.insert (new String (“hello”));

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

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

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

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

50 Cure to Problem #1: Use of Generic import util.LinkedList; 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 ();

51 Problem #2: Complexity // Turn back to “equals ()” function int equals (Object y); // How to implement this? xy

52 Cure to Problem #2: Dynamic Method Dispatch Every class has an “ equals ” method, the call to “ equals ” is automatically dispatched to the correct ones in the current called objects. xy eq

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

54 Problem #3: Efficiency Nearly all data in Java are boxed typically heap-allocated in all compilers space automatically allocated by the compilers transparent to the programmers Rely on garbage collection to recycle dead objects


Download ppt "Polymorphism Discrete Mathematics and Its Applications Baojian Hua"

Similar presentations


Ads by Google