CSc 520 Principles of Programming Languages

Similar documents
CSc 520. Principles of Programming Languages 25: Types Introduction

Topic 9: Type Checking

Topic 9: Type Checking

CS558 Programming Languages

CS558 Programming Languages

CSc 553. Principles of Compilation. 16 : OO Languages Polymorphism. Department of Computer Science University of Arizona

Names, Scopes, and Bindings II. Hwansoo Han

CSE 431S Type Checking. Washington University Spring 2013

CSc 520. Principles of Programming Languages 46: OO Languages Polymorphism

CS558 Programming Languages

520 Principles of Programming Languages. Arithmetic. Variable Declarations. 19: Pascal

Argument Passing All primitive data types (int etc.) are passed by value and all reference types (arrays, strings, objects) are used through refs.

n n Try tutorial on front page to get started! n spring13/ n Stack Overflow!

Object-Oriented Languages. CSc 453. Compilers and Systems Software. 23 : OO Languages. Department of Computer Science University of Arizona

Outline. Java Models for variables Types and type checking, type safety Interpretation vs. compilation. Reasoning about code. CSCI 2600 Spring

Discussion. Type 08/12/2016. Language and Type. Type Checking Subtypes Type and Polymorphism Inheritance and Polymorphism

UNIT II Structuring the Data, Computations and Program. Kainjan Sanghavi

Generics/Templates. Steven R. Bagley

CSCI312 Principles of Programming Languages!

CSc 520. Principles of Programming Languages 45: OO Languages Introduction

Lecture Overview. [Scott, chapter 7] [Sebesta, chapter 6]

G Programming Languages Spring 2010 Lecture 6. Robert Grimm, New York University

Types and Type Inference

Fundamentals of Programming Languages

Lecture #23: Conversion and Type Inference

Conversion vs. Subtyping. Lecture #23: Conversion and Type Inference. Integer Conversions. Conversions: Implicit vs. Explicit. Object x = "Hello";

Types and Type Inference

CSc 520 Principles of Programming Languages

CSc 372. Comparative Programming Languages. 2 : Functional Programming. Department of Computer Science University of Arizona

Defining Functions. CSc 372. Comparative Programming Languages. 5 : Haskell Function Definitions. Department of Computer Science University of Arizona

CSc 453. OO Languages. Object-Oriented Languages... Object-Oriented Languages. Compiling OO Languages. Compilers and Systems Software

CSc 520 Principles of Programming Languages. 26 : Control Structures Introduction

CSc 372. Comparative Programming Languages. 36 : Scheme Conditional Expressions. Department of Computer Science University of Arizona

Binghamton University. CS-140 Fall Dynamic Types

CS 251 Intermediate Programming Methods and Classes

CS 251 Intermediate Programming Methods and More

Programming Languages Fall 2013

Advanced Programming - JAVA Lecture 4 OOP Concepts in JAVA PART II

Princeton University. Computer Science 217: Introduction to Programming Systems. Data Types in C

Introduction to Programming Using Java (98-388)

Preview from Notesale.co.uk Page 3 of 36

CSc 520 Principles of Programming Languages

CS412/CS413. Introduction to Compilers Tim Teitelbaum. Lecture 17: Types and Type-Checking 25 Feb 08

Types. Type checking. Why Do We Need Type Systems? Types and Operations. What is a type? Consensus

Inheritance & Polymorphism. Object-Oriented Programming Spring 2015

CS/ENGRD 2110 SPRING Lecture 7: Interfaces and Abstract Classes

CSC324 Principles of Programming Languages

Data Types. Every program uses data, either explicitly or implicitly to arrive at a result.

CS/ENGRD 2110 FALL Lecture 7: Interfaces and Abstract Classes

CS558 Programming Languages

Design Issues. Subroutines and Control Abstraction. Subroutines and Control Abstraction. CSC 4101: Programming Languages 1. Textbook, Chapter 8

COMP 250: Java Programming I. Carlos G. Oliver, Jérôme Waldispühl January 17-18, 2018 Slides adapted from M. Blanchette

CSc 520 Principles of Programming Languages

Structuring the Data. Structuring the Data

Inheritance. CSc 372. Comparative Programming Languages. 28 : Ruby Classes. Department of Computer Science University of Arizona.

CSc 372 Comparative Programming Languages

CSc 520 Principles of Programming Languages. ameter Passing Reference Parameter. Call-by-Value Parameters. 28 : Control Structures Parameters

Polymorphism. CMSC 330: Organization of Programming Languages. Two Kinds of Polymorphism. Polymorphism Overview. Polymorphism

Imperative Programming

CS260 Intro to Java & Android 03.Java Language Basics

Introduction. Inline Expansion. CSc 553. Principles of Compilation. 29 : Optimization IV. Department of Computer Science University of Arizona

Resource Management With a Unique Pointer. Resource Management. Implementing a Unique Pointer Class. Copying and Moving Unique Pointers

Compiler Construction Lent Term 2015 Lectures 10, 11 (of 16)

Java and C CSE 351 Spring

CS A331 Programming Language Concepts

Chapter 1 Getting Started

Object-Oriented Languages and Object-Oriented Design. Ghezzi&Jazayeri: OO Languages 1

Programming in Omega Part 1. Tim Sheard Portland State University

CS558 Programming Languages Winter 2018 Lecture 4a. Andrew Tolmach Portland State University

OCaml Data CMSC 330: Organization of Programming Languages. User Defined Types. Variation: Shapes in Java

Whidbey Enhancements to C# Jeff Vaughan MSBuild Team July 21, 2004

CSc 372 Comparative Programming Languages

INDEX. A SIMPLE JAVA PROGRAM Class Declaration The Main Line. The Line Contains Three Keywords The Output Line

CSc 372 Comparative Programming Languages

Type Hierarchy. Lecture 6: OOP, autumn 2003

CSE 374 Programming Concepts & Tools

Semantic Processing. Semantic Errors. Semantics - Part 1. Semantics - Part 1

COSC 2P95. Procedural Abstraction. Week 3. Brock University. Brock University (Week 3) Procedural Abstraction 1 / 26

CSc 372. Comparative Programming Languages. 1 : Introduction. Department of Computer Science University of Arizona

STUDY NOTES UNIT 1 - INTRODUCTION TO OBJECT ORIENTED PROGRAMMING

C++ Important Questions with Answers

Design Patterns: State, Bridge, Visitor

CSc 372 Comparative Programming Languages. 4 : Haskell Basics

Inclusion Polymorphism

Functional Programming in Haskell Part I : Basics

CSE 504. Expression evaluation. Expression Evaluation, Runtime Environments. One possible semantics: Problem:

CSc 372. Comparative Programming Languages. 4 : Haskell Basics. Department of Computer Science University of Arizona

CSc 372 Comparative Programming Languages

CSc 520. Principles of Programming Languages 11: Haskell Basics

Compilers CS S-05 Semantic Analysis

Programming Paradigms

Chapter 3:: Names, Scopes, and Bindings (cont.)

Chapter 3:: Names, Scopes, and Bindings (cont.)

Lecture Overview Code generation in milestone 2 o Code generation for array indexing o Some rational implementation Over Express Over o Creating

Review: Object Diagrams for Inheritance. Type Conformance. Inheritance Structures. Car. Vehicle. Truck. Vehicle. conforms to Object

CSC324 Principles of Programming Languages

Operators. The Arrow Operator. The sizeof Operator

Lecture 7: Type Systems and Symbol Tables. CS 540 George Mason University

Types, Type Inference and Unification

CS/ENGRD 2110 SPRING 2018

Transcription:

CSc 520 Principles of Programming Languages 16 : Types Polymorphism Christian Collberg collberg+520@gmail.com Department of Computer Science University of Arizona Copyright c 2008 Christian Collberg [1]

What is polymorphism? Polymorphic means having multiple forms. In programming languages it refers to code and data that can work with values of different types. A variable is polymorphic if it can refer to objects of different types. A function is polymorphic if you can pass arguments of different types to it. We want to define functions that are as reusable as possible. Polymorphic functions are reusable because they can be applied to arguments of different types. [2]

Polymorphic Variables A variable is polymorphic if it can refer to objects of different types. There s a trade-off between having as much static typing as possible (so that the compiler can tell you about errors in your code as early as possible) and allowing as much polymorphism as possible (to make your code flexible). [3]

Polymorphic Variables in Ruby In Ruby, a variable can refer to any type of data. No type checking is done until runtime. The last expression will fail at runtime since sub is expecting a regular expression as its first argument: x = 42; puts x x = "42"; puts x x = 42.42; puts x x = [42,42.0,"42"]; puts x x = /duck/ puts "duckduckduck".sub(x,"ruby") x = 42 puts "duckduckduck".sub(x,"ruby") [4]

Polymorphic Functions A function is polymorphic if you can pass arguments of different types to it. You want the list length function to be polymorphic so that you can pass a list-of-integers to it, a list-of-reals, a list-of-lists, etc. It shouldn t be necessary to write one list length function for each list type. Similarly, you want to write exactly one sort function that can sort an array-of-100-integers, an array-of-1000-reals, etc. [5]

Types of Polymorphism There are two major kinds of polymorphism, parametric polymorphism and inclusion polymorphism. Explicit parametric polymorphism is also known as genericity. Inclusion polymorphism is also known as subtype polymorphism. Ada has parametric polymorphism. Java and C++ have both parametric polymorphism (templates and generics) and inclusion polymorphism (inheritance, subtyping). [6]

Types of Polymorphism Parametric In a language with parametric polymorphism he code takes a type argument, such as: function sort[t](a : array of T) {... } which you then have to instantiate with a particular type: function intsort is new sort[integer]; function stringsort is new sort[string]; Parametric polymorphism can be explicit (you have to supply the type, as in the sort function above) or implicit (the compiler figures out the type: function sort(a : array of <some_type>) {...... var x : array [1..100] of real; sort(x); var y : array [1..100] of integer; sort(y); [7]

Types of Polymorphism Inclusion You get inclusion polymorphism in languages that support subtyping, i.e. any object oriented language with inheritance. You write your code to handle one particular type T. But, you can then create subtypes of T, and your code will work on objects of these subtypes also. We ll talk a lot about inclusion polymorphism and how it s implemented in the lectures on object-oriented languages. Java and C++ support both generics and inclusion polymorphism. [8]

Types of Polymorphism... Polymorphism Parametric Implicit Haskell Java Explicit C++ Inclusion Ada [9]

Levels of Freedom Depending on the language, we get different levels of freedom, and different levels of protection against type-errors. In some languages you can only have arrays of one element type: x = [1,2,3,4] but you can call a function with arrays of different types: sort([1,2,3,4]) sort(["hey","bar","ber","ri","ba"]) [10]

Levels of Freedom... In some languages you can mix the array element types: y = [1,2.3,"hello",[4,5]] In languages with inclusion polymorphism you can put similar objects in the same array Animals a = [monkey, puffer_fish, amoeba]; but the compiler (or runtime system) will complain if you try to put really different ones together: Animals b = [monkey, honda_civic]; [11]

Language Examples Let s have a look at a couple of languages and how they define polymorphism! I m going to take a roughly historical approach: 1. We ll start with C and Pascal (where you have to abuse the type system to make polymorphic functions), and then we ll look at 2. Modula-2 which has a (very) limited form of polymorphic arrays called conformant arrays, and on to 3. Ada which has fullblown generic functions and modules, and then 4. Java which supports inclusion polymorphism through its subtyping mechanism, and finally 5. Haskell s implicit parametric polymorphism. [12]

C s Generic Reference Types [13]

C C doesn t have any real support to build polymorphic functions. But, since it s so easy to bypass any static typing in C (we can cast pointers willy-nilly), we can still build functions that can take multiple types of argument. Of course, when we re doing this we give up any type of static type-checking it s up to the programmer to make sure that he does the right thing the compiler won t be able to help him at all! [14]

Polymorphic sort in C C s standard library has a function qsort(): void qsort(void *base, size_t n, size_t elsize, int (*compare)(void *, void *)); It takes four arguments: 1. base is a pointer to the array 2. n is a number of elements 3. elsize is the size of each element 4. compare is a function pointer which returns -1 for less than, 0 for equal, and 1 for greater than. [15]

Polymorphic sort in C Sorting ints int compare_ints(void *a, void *b) { int ia = *(int *)a; int ib = *(int *)b; return (ia<ib)?-1:1; } void main() { int data[] = {... }; qsort(data, num_elmts, sizeof(int), compare_ints); } Inside compare ints we have to cast the generic void pointers to the element type of the array, ints in our case. If we cast to the wrong type, disaster ensues... [16]

Pascal s Variant Records [17]

Pascal Pascal doesn t have any real support to build polymorphic functions. If you ve written a sorting routines for arrays of integers, that doesn t help you if you want to sort an array of reals! In the original Pascal definition, if you had a sorting routine that would sort an array of 100 integers you couldn t even use it to sort an array of 101 integers! The only way to bypass Pascal s rigid type system is to use the loop-hole known as untagged variant records (similar to C s unions). [18]

Tagged Variant Records type name = record field name : type; field name : type; case tag name : type of case : (field name:type;...); case : (field name:type;...); end; [19]

Tagged Variant Records... type rec = record a : integer; case tag : boolean of true : (x : integer); false : (y : char); end; var r: rec; begin r.tag := true; r.x := 55; r.tag := false; r.y := A ; r.tag := true; r.y := 55; (* Runtime error? end. [20]

Untagged Variant Records type rec = record a : integer; case boolean of true : (x : integer); false : (y : char); end; var r: rec; begin r.x := 55; r.y := A ; end. This construct is used to bypass Pascal s strong typing. [21]

Generic sort Here are two ways to build a generic sort routine in Pascal. In the first one we use tagged variant records to, essentially, allow run-time typing of data. In the second case we use untagged variant records but pass along a comparison function. We have to write one comparison function for every type of data we want to sort. [22]

Generic sort in Pascal 1 type R = record case tag : boolean of true : (x : integer); false : (y : real); end; A = array [1..100] of R; procedure sort(p:a); var greater : boolean; i,j : integer; begin i := 1;j := 2; if p[i].tag=true then greater := p[i].x > p[j else greater := p[i].y > p[j end; [23]

Generic sort in Pascal 1... var x:a; begin x[1].tag := true; x[1].x := 42; x[2].tag := true; x[2].x := 52; sort(x); x[1].tag := false; x[1].y := 42.5; x[2].tag := false; x[2].y := 52.3; sort(x); end. [24]

Generic sort in Pascal 2 program p; type R = record case boolean of true : (x : integer); false : (y : real); end; A = array [1..100] of R; function cmpints(p:a;i:integer;j:integer):boolea begin return p[i].x > p[j].x; end; function cmpreals(p:a;i:integer;j:integer):boole begin return p[i].y > p[j].y; end; [25]

Generic sort in Pascal 2... procedure sort(p:a; function cmp(x:a;i:integer;j:integer):boolea var greater : boolean; i,j : integer; begin i := 1; j := 2; greater := cmp(p,i,j); end; [26]

Generic sort in Pascal 2... var x:a; begin x[1].x := 42; x[2].x := 52; sort(x, greaterints); x[1].y := 42.5; x[2].y := 52.3; sort(x, greaterreals); x[1].x := 42; x[2].x := 52; sort(x, greaterreals); end. [27]

Modula-2 s conformant arrays [28]

Pascal array parameters Originally, a Pascal function that took an array-of-100-integers as argument wouldn t accept an array-of-101-integers. program p; type A = array [1..100] of integer; procedure sort(p:a); begin end; var x:a; begin sort(x); end. [29]

Modula-2 s arrays Modula-2 relaxed this by allowing conformant arrays, array parameters that could be of any length. You still couldn t pass an array-of-ints and an array-of-floats to the same function, though... PROCEDURE Sum(vector : ARRAY OF REAL) : REAL; VAR i:integer; tot:real; BEGIN tot := 0; FOR i := 0 TO HIGH(vector) DO tot := tot + Donkey[vector]; END; RETURN tot; END Sum; [30]

Ada s Generics [31]

Ada s generic modules An Ada module specification has two parts, a public part and a private part. The private part contains the definitions of all those items that we don t want a user to know about. In this example, the private part reveals that the stack is implemented as an array. [32]

Ada generic type ITEM is private; package GENERIC STACK is type STACK (SIZE : POSITIVE) is limited private; procedure PUSH (S : in out STACK; E : in ITEM); procedure POP ( S : in out STACK; E : out ITEM); pragma INLINE (PUSH, POP); private type VECTOR is array (POSITIVE range < >) of ITEM; type STACK (SIZE : POSITIVE) is record SPACE : VECTOR (1.. SIZE); INDEX : NATURAL := 0; end record; end GENERIC STACK; [33]

Ada... Before we can use a stack we have to instantiate it with the type of the element and the number of elements we want: package body GENERIC STACK is -- Implementations of... PUSH and POP... end GENERIC STACK; with GENERIC STACK; procedure MAIN is package STACK INT is new GENERIC STACK (INTEGER); S : STACK INT.STACK (100); begin STACK INT.PUSH (S, 314); end MAIN; [34]

Generics as Macros Instantiating a generic module is just like making a copy of the source code for the module, and replacing the type with the one we want. You could implement Ada style generics using C s macros! [35]

Avoiding code-bloat One of the reasons for having generics in the Ada language was to avoid code-bloat: we don t want to have one int sort routine, one float sort routine, etc. However, it was up to the compiler writer to decide whether to share code between instantiations! So, there was never any guarantee that you would save on memory. ALSO, these days code bloat is less of an issue, given the large memories of modern machines. [36]

Inclusion Polymorphism in Java [37]

Java Java is an object oriented language. This means we can create hierarchies of types: IS A Vehicle IS A Motorized Manual IS A TwoWheels FourWheels Bicycle Moped Motorcycle Car Each of these types is a class. An SUV is-a type of a Car which is-a type of a [38] FourWheels vehicle, which is-a kind of Motorized SUV

A Java class hierarchy This is what it looks like in Java source (indentation is just for clarity): class Vehicle {} class Motorized extends Vehicle {} class TwoWheels extends Motorized {} class Moped extends TwoWheels {} class Motorcycle extends TwoWheels {} class FourWheels extends Motorized {} class Car extends FourWheels {} class SUV extends Car {} class Manual extends Vehicle {} class Bicycle extends Manual {} [39]

Inclusion polymorphism Object-oriented languages support inclusion polymorphism, also known as subtype polymorphism. Unlike C s void pointers which you can assign and cast however you like, the Java type hierarchy restrics what you re allowed to assign. In general, you can assign a variable who s type is high up in the type hierarchy a variable that s lower down. The reason is that the lower down you get in the hierarchy, the more specific the type gets. For example, an SUV is-a kind of Car (it has all the characteristics of a car, plus some extra ones, such as being bad for the environment), so it s OK to assign an object of type SUV to a variable of type Car. [40]

A Java class hierarchy... class Main { public static void main(string args[]) { Car civic = new Car(); Vehicle v = civic; /* OK */ Bicycle b = civic; /* static error */ FourWheels f = civic; /* OK */ SUV s = (SUV)f; /* runtime error */ } } f s static type is Vehicle so it could contain an object of type SUV, we just don t know (until runtime) when a ClassCastException is thrown. [41]

Parametric Polymorphism in Haskell [42]

Haskell Polymorphic Functions Haskell is a statically typed functional language. Functions of polymorphic type are defined by using type variables in the signature: length :: [a] -> Int length s =... length is a function from lists of elements of some (unspecified) type a, to integer. I.e. it doesn t matter if we re taking the length of a list of integers or a list of reals or strings, the algorithm is the same. length [1,2,3] 3 (list of Int) length ["Hi ", "there", "!"] 3 (list of String length "Hi!" 3 (list of Char) [43]

Constrained Parametric Polymorphism Not every type can be used in every context. For example, to be able to sort an array the array elements must be comparable, i.e. they must support the <-operator. Haskell uses context predicates to restrict polymorphic types: member :: Eq [a] => [a] -> a -> bool Now, member may only be applied to list of elements where the element type has == and \= defined. Eq is called a type class. Ord is another useful type class. It is used to restrict the polymorphic type of a function to types for which the relational operators (<, <=, >, >=) have been defined. [44]

Context Predicates Consider the Haskell sort function which has the following type: sort :: (Ord a) => [a] -> [a] sort can be applied to any type of arrays for which we ve defined the relational operators (<, <=, >, >=) This is called constrained parametric polymorphism. Ada s generics support this also. [45]

Readings and References Readings in Scott: 1. Polymorphism and related concepts (pp. 145-149). 2. Polymorphism (pp. 309-311). 3. Overloading and coercion (pp. 330-331) 4. Generic reference types (pp. 331-332) 5. Conformant arrays (pp. 355-356) 6. Generic subroutines and modules (pp. 434-440) 7. Polymorphism in object oriented languages (505 508) [46]