1 / 45

Understanding Polymorphism: A Powerful Language Feature

This article explains polymorphism in programming languages, including its various applications and examples. It also discusses scope and how it affects the recognition of identifiers.

copej
Download Presentation

Understanding Polymorphism: A Powerful Language Feature

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. What is it? What does it do? Polymorphism (Ch 8) • A functions that is not fixed is polymorphic • Applies to a wide variety of language features • Most languages have at least a little Scope (Ch 10) Where is it? Where to find it? • A scope of an identifier (e.g., a variable) is the space where it can be recognized. IT 327

  2. Every thing is fixed: PolymorphismExample: C: int f(char a, char b) { return a==b; } ML: • fun f(a, b) = (a = b); val f = fn : ''a * ''a -> bool IT 327

  3. Common Examples of Polymorphism • Overloading • Parameter coercion • Parametric polymorphism • Subtype polymorphism • (OOP) (Dynamic binding) IT 327

  4. Overloading • An overloaded function or operator is one that has at least two definitions. (some restriction, what is it?) • Most languages have overloaded operators • Some also allow the programmer to redefine overloaded operators IT 327

  5. Predefined Overloaded Operators ML: val x = 1 + 2; val y = 1.0 + 2.0; Pascal: a := 1 + 2; b := 1.0 + 2.0; c := "hello " + "there"; d := ['a'..'d'] + ['f'] IT 327

  6. Defining Overloaded Functions C++ allows a function to be overloaded int square(int x) { return x*x;}double square(double x) { return x*x;} IT 327

  7. Adding new definitions to Overloaded Operators C++ allows operators to be overloaded. class complex { double rp, ip; // real part, imaginary partpublic: complex(double r, double i) {rp=r; ip=i;}friend complex operator +(complex, complex);friend complex operator *(complex, complex);}; void f(complex a, complex b, complex c) { complex d = a + b * c; …} IT 327

  8. Implementing Overloading • Compilers usually implement overloading straightforwardly: • Give a different name to each definition IT 327

  9. Coercion • A coercion is an automatic and implicit type conversion Explicit type conversion in Java: double x;x = (double) 2;double x;x = 2; Coercion in Java: IT 327

  10. Parameter Coercion void f(double x) { … } f((byte) 1); f((short) 2);f('a'); f(3); This f can be called with any typeof parameter, as long as Java is willing to coerce to type double IT 327

  11. Defining Type Coercions Must be defined precisely in details about which coercions are performed • Some old languages like Algol 68 and PL/I, have very extensive powers of coercion • Some, like ML, have none • Most, like Java, are somewhere in the middle They wanted to make the languages smart We wanted make the languages precise IT 327

  12. Where is my penny? There is a criminal charge in 1970’s double payment, price, change; inti; cout << "Input payment and price in dollars: "; cin >> payment >> price; cout << "Payment = " << payment << ", Price = " << price << endl; change = payment-price; cout << "Change = " << change << endl; cout << “Pennies = " << change*100 << "\n"; i = (payment-price)*100; cout << "(Payment-Price)*100 = " << i << endl; Input payment and price in dollars: 100.0 3.99 Payment = 100, Price = 3.99 Change = 96.01 Pennies = 9601 (Payment-Price)*100 = 9601 Input payment and price in dollars: 10.0 3.99 Payment = 10, Price = 3.99 Change = 6.01 Pennies = 601 (Payment-Price)*100 = 601 Input payment and price in dollars: 20.0 3.99 Payment = 20, Price = 3.99 Change = 16.01 Pennies = 1601 (Payment-Price)*100 = 1600 (x-y)*100 (x*100)-(y*100) IT 327

  13. Difference between Coercion and Overloading: int square(int x) { return x*x;} double square(double x) { return x*x;} Overloading : type  definition (types determine which definitions) Coercion: definition  type (definitions determine which types) square(0.3) void f(int x, int y) { …} f('a', 'b') IT 327

  14. Parametric Polymorphism C++ Function Templates template<classX> X max(X a, X b) { return a > b ? a : b; } JAVA Generic Classes publicinterface Queue<T> { boolean offer(T item); T remove(); T poll(); ..... } IT 327

  15. Example: ML Functions - fun identity x = x; val identity = fn : 'a -> 'a - fun reverse x = = if null x then nil = else (reverse (tl x)) @ [(hd x)]; val reverse = fn : 'a list -> 'a list IT 327

  16. Subtype Polymorphism Java Any SUV is a Vehicle • Especially object-oriented languages. Vehicle SUV Honda Pilot Base type Object Number Integer Derived type Double IT 327

  17. Static  Dynamic When to be determined: Compiling  Running Contemporary emphasis Polymorphism IT 327

  18. Scope: the space for a name to be identified • Scope is trivial if you have a unique name for everything: • The same names are used over and over, we in most cases have no problems with that. • How does this work? There are 300M people in the USA IT 327

  19. Named definitions • When there are different variables using the same name, there are different possible bindings (definitions) for those names type names, constant names, function names, etc. • Each occurrence must be bound using one of the definitions. Which one? • There are many different ways to solve this scoping problem (i.e., how to bind) IT 327

  20. The origin of the scoping problem came from logic xy(xzP(x,y,z) x(Q(x,y)zt(R(y,z,z)xS(t,x)))T(x)) -conversion xy(azP(a,y,z) b(Q(b,y)ct(R(y,c,c)dS(t,d))) T(x)) IT 327

  21. Scoping with blocks Different ML Blocks let val .. in .... end • The let is just a block: no other purpose • A fun definition includes a block: • Multiple alternatives have multiple blocks: • Each rule in a match is a block: fun cube x = x*x*x; fun f (a::b::_) = a+b| f [a] = a| f [] = 0; case x of (a,0) => a | (_,a) => a IT 327

  22. Java Blocks • In Java and other C-like languages: a compound statement using { and } • A compound statement also serves as a block: int c = 4; // can we? for (int i=0;i<0; i++) { int c = i*i*i; p += c; q += c; i -= step;} while (i < 0) { int c = i*i*i; p += c; q += c; i -= step;} IT 327

  23. Nesting Example Scope of this definition let end val n = 1in end let val n = 2in n Scope of this definition IT 327

  24. Labeled Namespaces • ML’s structure… structure Fred = struct val a = 1; fun f x = x + a;end; Fred.forFred.a IT 327

  25. C++ Labeled Namespaces namespace IT { int a=2; int f(...) {...} } using IT::f; ..... ..... ..... IT::f(...) ..... ..... ..... ..... { using namespace IT; ... a ... ........ .... f(...).. } ..... IT 327

  26. Java or C++ Example public class Month { public static int min = 1; public static int max = 12; …} • Month.min and Month.max IT 327

  27. Namespace Refinement • Some information and implementation can (may) be hidden in a namespace. Need for OOP. Origin of OOP: abstract data types reveals an interface hides implementation details… IT 327

  28. Example: An Abstract Data Type namespace dictionary containsa constant definition for initialSizea type definition for hashTablea function definition for hasha function definition for reallocatea function definition for createa function definition for inserta function definition for searcha function definition for deleteend namespace Implementation definitionsshould be hidden Interface definitions should be visible IT 327

  29. Two Approaches • C++ makes every component in a namespace visible • ML uses a separate construct to define the interface (a signature in ML) • Java combines the two approaches IT 327

  30. Legitimate but not a good idea - val int = 3;val int = 3 : int - fun f int = int*int;val f = fn : int -> int- f 3;val it = 9 : int int is not reserved in ML IT 327

  31. Primitive Namespaces • ML’s syntax can keep types and expressions separated • There is a separate namespace for types fun f(int:int*double:int) = (int:int)*(double:int); These are types in the namespace for types These are variable s in the ordinary namespace IT 327

  32. Primitive Namespaces • Not explicitly created by the programmers (like primitive types) • They are part of the language definition • Some languages have several separate primitive namespaces IT 327

  33. When Is Scoping Resolved? • All scoping tools we have seen so far are static, i.e., they are determined at compile time • Some languages postpone the decision until runtime: dynamic scoping IT 327

  34. Dynamical Scoping • Each function has an environment of definitions • If a name that occurs in a function is not found in its environment, its caller’s environment is searched • And if not found there, the search continues back through the chain of callers • This generates a rather odd scope. Well, not that odd. IT 327

  35. Classic Dynamic Scope Rule The scope of a definition: • From the point of definition to the end of the function in which the definition is defined, plus • the scope of any functions that is called by the function after the definition, (even indirectly)— minus the scopes of any re-definitions of the same name in those called functions IT 327

  36. Static vs. Dynamic • The static rule considers only the regions of program text (context of the program), so it can be applied at compile time • The dynamic considers the runtime events: “functions when they are called…” (timing) IT 327

  37. 5 Block Scope (Static) fun g x = let val inc = 1; fun f y = y+inc; fun h z = let val inc = 2; in f z end; in h x end; With block scope, the reference to inc is bound to the previous definition in the same block. The definition in f’s caller’s (h’s) evironment is inaccessible. 5 5 1 5 What is the value ofg 5 using ML’s classicalblock scope rule? 5 g 5 = 6 5 IT 327

  38. 5 Dynamic Scope fun g x = let val inc = 1; fun f y = y+inc; fun h z = let val inc = 2; in f z end; in h x end; With dynamic scope,the reference to inc isbound to the definition in the caller’s (h’s) environment. g 5 = 7 if ML useddynamic scope 5 5 2 5 caller 5 5 IT 327

  39. Dynamic Scope • Only in a few languages: some dialects of Lisp and APL • Available as an option in Common Lisp • Drawbacks: • Difficult to implement efficiently • Creates large and complicated scopes, since scopes extend into called functions • Choice of variable name in caller can affect behavior of called function IT 327

  40. Separate Compilation • Scope issues extend to the linker: it needs to connect references to definitions across separate compilations • Special support for this is needed IT 327

  41. C Approach, Compiler Side • Two different kinds of definitions: • Full definition • Name and type only: a declaration (prototype) • If several separate compilations want to use the same integer variable x: • Only one will have the full definition, int x = 3; • All others have the declaration extern int x; IT 327

  42. C Approach, Linker Side • When the linker runs, it treats a declaration as a reference to a name defined in some other file • It expects to see exactly one full definition of that name • Note that the declaration does not say where to find the definition—it just requires the linker to find it somewhere IT 327

  43. Older Fortran Approach, Compiler Side • Older Fortran dialects used COMMON blocks • All separate compilations give the same COMMON declaration: COMMON A,B,C COMMON X,A,B COMMON A,B,C B = X - A; A = B+C/2; IT 327

  44. Older Fortran Approach, Linker Side • The linker allocates just one block of memory for the COMMON variables: • The linker does not use the local names A X B A COMMON A,B,C COMMON X,A,B C B A = B+C/2; B = X - A; IT 327

  45. Modern Fortran Approach • A MODULE can define data in one separate compilation • A USE statement can import those definitions into another compilation • USE says what module to use, but does not say what the definitions are • Unlike the C approach, the Fortran compiler must at least look at the result of that separate compilation IT 327

More Related