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

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

Types and Type Inference

Types and Type Inference

CS558 Programming Languages

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

CS558 Programming Languages

CMSC 330: Organization of Programming Languages

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

CS1150 Principles of Computer Science Methods

Type Systems, Type Inference, and Polymorphism

CS 231 Data Structures and Algorithms, Fall 2016

INF 212/CS 253 Type Systems. Instructors: Harry Xu Crista Lopes

Chapter 9. Subprograms

INF 212 ANALYSIS OF PROG. LANGS Type Systems. Instructors: Crista Lopes Copyright Instructors.

Inheritance and Substitution (Budd chapter 8, 10)

What are the characteristics of Object Oriented programming language?

Topics Covered Thus Far CMSC 330: Organization of Programming Languages

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

Chapter 9. Subprograms

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

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

Some instance messages and methods

Subprograms. Copyright 2015 Pearson. All rights reserved. 1-1

Topics Covered Thus Far. CMSC 330: Organization of Programming Languages. Language Features Covered Thus Far. Programming Languages Revisited

Names, Scopes, and Bindings II. Hwansoo Han

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

Chapter 13 Object Oriented Programming. Copyright 2006 The McGraw-Hill Companies, Inc.

Types, Type Inference and Unification

Lecture 12 ADTs and Stacks

Functions and Recursion. Dr. Philip Cannata 1

Type Bindings. Static Type Binding

Type Checking and Type Inference

Semantic Analysis. Outline. The role of semantic analysis in a compiler. Scope. Types. Where we are. The Compiler Front-End

A declaration may appear wherever a statement or expression is allowed. Limited scopes enhance readability.

The role of semantic analysis in a compiler

Lecture 5: Methods CS2301

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

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

Overloading, Type Classes, and Algebraic Datatypes

Pierce Ch. 3, 8, 11, 15. Type Systems

M301: Software Systems & their Development. Unit 4: Inheritance, Composition and Polymorphism

Introduction to Software Testing Chapter 2.4 Graph Coverage for Design Elements Paul Ammann & Jeff Offutt

Polymorphic lambda calculus Princ. of Progr. Languages (and Extended ) The University of Birmingham. c Uday Reddy

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

C++ Programming: Introduction to C++ and OOP (Object Oriented Programming)

Topic 9: Type Checking

Topic 9: Type Checking

CS110D: PROGRAMMING LANGUAGE I

STRUCTURING OF PROGRAM

SEMANTIC ANALYSIS TYPES AND DECLARATIONS

Concepts of Programming Languages

Introduction to Programming Using Java (98-388)

Programmiersprachen (Programming Languages)

Fundamentals of Programming Languages

CMSC 4023 Chapter 9. Fundamentals of Subprograms Introduction

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

MIDTERM EXAMINATION - CS130 - Spring 2005

Inheritance. Inheritance allows the following two changes in derived class: 1. add new members; 2. override existing (in base class) methods.

Example: Haskell algebraic data types (1)

Chapter 11. Abstract Data Types and Encapsulation Concepts ISBN

CSC 533: Organization of Programming Languages. Spring 2005

TYPES, VALUES AND DECLARATIONS

Day 4. COMP1006/1406 Summer M. Jason Hinek Carleton University

Programming Paradigms, Fall 06

The Compiler So Far. CSC 4181 Compiler Construction. Semantic Analysis. Beyond Syntax. Goals of a Semantic Analyzer.

Types. What is a type?

Properties of an identifier (and the object it represents) may be set at

CS1622. Semantic Analysis. The Compiler So Far. Lecture 15 Semantic Analysis. How to build symbol tables How to use them to find

CA Compiler Construction

CSc 520 Principles of Programming Languages

CSCE 314 Programming Languages. Type System

Object Oriented Programming is a programming method that combines: Advantage of Object Oriented Programming

STUDY NOTES UNIT 1 - INTRODUCTION TO OBJECT ORIENTED PROGRAMMING

Informatica 3 Syntax and Semantics

Overview of OOP. Dr. Zhang COSC 1436 Summer, /18/2017

Semantic Analysis. How to Ensure Type-Safety. What Are Types? Static vs. Dynamic Typing. Type Checking. Last time: CS412/CS413

CS1150 Principles of Computer Science Methods

Chapter 5 Object-Oriented Programming

Abstract data types &

Abstract Data Types & Object-Oriented Programming

CS263: Runtime Systems Lecture: High-level language virtual machines

Chapter 5 Names, Binding, Type Checking and Scopes

CS201 - Introduction to Programming Glossary By

Imperative Programming

(Not Quite) Minijava

Operating Systems CMPSCI 377, Lec 2 Intro to C/C++ Prashant Shenoy University of Massachusetts Amherst

1 Epic Test Review 2 Epic Test Review 3 Epic Test Review 4. Epic Test Review 5 Epic Test Review 6 Epic Test Review 7 Epic Test Review 8

Intermediate Code Generation

Programming Languages: Lecture 11

Programming Languages

Data Structures (list, dictionary, tuples, sets, strings)

Functions and Recursion

Semantic Analysis. Outline. The role of semantic analysis in a compiler. Scope. Types. Where we are. The Compiler so far

CSCI 3155: Principles of Programming Languages Exercise sheet #14 28 June 2007

3.Constructors and Destructors. Develop cpp program to implement constructor and destructor.

301AA - Advanced Programming [AP-2017]

Computer Science II (20073) Week 1: Review and Inheritance

What is an algorithm?

Anatomy of a Compiler. Overview of Semantic Analysis. The Compiler So Far. Why a Separate Semantic Analysis?

CMSC 331 Final Exam Section 0201 December 18, 2000

Transcription:

Type Joseph Spring Discussion Languages and Type Type Checking Subtypes Type and Inheritance and 7COM1023 Programming Paradigms 1 2 Type Type denotes the kind of values that programs can manipulate: Simple types» Integers, decimal numbers, characters, Boolean values Structured types» Character strings, lists, trees, hash tables More complex types» Functions, classes 3 Very few languages do not partition the collection of data values (bit patterns) into distinct types Assembler language doesn t BCPL (Basic Combined Programming Language) didn t. developed by Martin Richards Uni of Cambridge, 1966 aka the Before C Programming Language The first brace programming language BCPL, followed by B (stripped down, syntactically modified version of BCPL became the basis for C Some languages check type safety: during the compilation stage (static) others while the program is executing. (dynamic) 4 Languages like Modula 2, Ada, Pascal, C++, C# and C are statically typed languages The languages require that a single type is bound to a variable when the variable is declared, remaining bound throughout run time Hence the type of the value of an expression is determined at compile time A language is said to be: statically typed if the types of all variables are fixed when they are declared at compile time Languages like Perl, Python and Scheme are dynamically typed languages The languages allow the type of a variable to be redefined each time a new value is assigned to it at run time To facilitate this a type indicator is stored at run time with each value A language is said to be: Dynamically typed if the type of a variable can vary at run time depending on the value assigned 5 6 1

A programming language is said to be strongly typed if its type system allows all type errors in a program to be detected either at compile time or run time Examples include Ada and Java C and C++ are not considered strongly typed Dynamically typed languages such as Perl and Scheme are strongly typed languages Strongly typed programming generally produces more reliable programs Is seen as a virtue in programming language design Static Type Checking Type checking means that operations or functions can only be applied to arguments of an appropriate type static means consistency is checked before the program is run. To do this all expressions, arguments to functions and, for procedural languages, variables must be given a type. 7 8 Static Type Checking Example For Example: int sum(int a[]) { int sum = 0; for(int i=0; i<a.length; i++) sum=sum+a[i]; return sum; int j, k; k = sum(j); is a compile time type error. 9 Type Inference Some languages like Haskell and SML use type inference which means the user does not need to explicitly give types for all names: parameters and functions the compiler works it out. Consider: sumlist s = if null s then 0 else (head s) + sumlist (tail s) which has type: sumlist :: Num a => [a] > a which means if a is any number type then the function sumlist takes a list of a s and returns a number. Writing code that misuses it will give a type error: (Standard ML (SML) is a general purpose, modular, functional programming language with compile time type checking and type inference) 10 Type Inference Main> sumlist 57 ERROR Cannot infer instance *** Instance : Num [a] *** Expression : sumlist 57 AND all this is done BEFORE the code is executed, ie. by the compiler 11 Dynamic Type Checking Ruby, Python, Lisp, Prolog and others do not have typed variables. Such languages have dynamic type checking. They still prevent incorrect operations on data types but check at runtime. So: (defun sumlist (l) (cond ((null l) 0) (t (+ (car l) (sumlist (cdr l)))) )) 12 2

Dynamic Type Checking Examples of running it: [2]> (sumlist (1 2 3 5 7 11)) 29 [3]> (sumlist 45) *** CAR: 45 is not a list it tried to execute and failed in the middle of the function attempting to take the head (car) of 45 13 Dynamic Type Checking Advantages It provides flexibility and speed of development Disadvantages it is possible to write programs that could sometimes produce type errors but with different data might not do so: (cond ((equal x 10) (sumlist 77)) (t (sumlist (1 2 3)))) this code might execute, it might fail dynamic checking languages must have extra hidden runtime code to check values in variables before EVERY operation on them 14 Subtypes Checking with Subtypes Many languages permit some form of subtype relationship If type t 2 is a subtype of t 1 then values of type t 2 can be used where values of type t 1 are expected. Type t 1 is the parent (base or host) type of t 2 The subtype t 2 has all the characteristics of its parent type and then adds some, for example its range of values in some way restricted 15 Subtypes But all the operations of the parent type are applicable to the child type. Type checking now does not check that the types of arguments or variables are the same but rather that they are compatible ie. are subtypes of the same base type. 16 Subtyping and Inheritance Subtyping is often associated with inheritance in object oriented languages Most treat a subclass as a subtype: class Parent { public void g() { class Child extends Parent { void fun(parent o) { o.g() Child v = new Child(); fun(v); h d i l f Child 17 Subtyping and Inheritance the parameter passed is a value of Child type which is a subtype of the formal argument so it is compatible. Any operation invoked inside g on the value named by o will be defined on the value v. NB it would be illegal to allow Parent values to be used where Child values are expected because the Child class might have additional attributes that would not be present in the Parent value. 18 3

Subranges Another use of subtyping is subrange values used in Ada and some other languages: procedure compat is subtype sta is integer range 0..100; subtype stb is integer range 100..100; i: integer := 3; j : integer; s : sta := 20; t : stb := 10; begin j := s * t; end compat; 19 Subranges Which is OK, s*t is applied between compatible types, both subtypes of integer and the assignment to j is of some subtype value. However Ada also allows the use of a parent type value whenever a child value is expected, this is very odd! In the above example it is legal to assign an integer value to a subrange: s := j; if the value assigned is out of range of left hand side it produces a runtime error 20 is the simplification and generality of having one name to operate safely on values of more than one type For example +, *, apply to ints, doubles in many languages. A function to find the length of a list in Haskell can be applied to any list In 1967 Christopher Strachey identified two principal forms of polymorphism in programming languages: ad hoc polymorphism parametric polymorphism Both these forms of polymorphism are important. They are applicable in different situations 21 ad hoc polymorphism under one name different operations can be applied to different types. This is more commonly called overloading parametric polymorphism one operation can be applied to different types of value. The generic is an example of a form of parametric polymorphism Both these forms of polymorphism are important. They are applicable in different situations 22 is important: Similar operations on different types would need distinct names which would make libraries harder to use Need ad hoc polymorphism (overloading) A monomorphic type system is one where procedures or functions can be applied to only one type. This would mean code must be repeated, a collection would have to be rewritten for different value types Need parametric polymorphism (generics) is important: However dynamic type checked languages offer reuse of code on ANY type of value: (defun length (l) (cond ((null l) 0) (t (+ 1 (length (cdr l)))) )) can be applied to any type of list BUT this is at the cost of no safe compiler checks So this is what a parametric polymorphic type discipline should give: flexibility AND safety. 23 24 4

Flexible Class in Python class Stack: def init (self): self.items = [] def push(self,item): self.items.append(item) def pop(self): return self.items.pop() def isempty(self): return (self.items == []) def top(self): return len(self.items) def str (self): return str(self.items) stck = Stack() stck.push(5) stck.push(10) stck.push(15) sum = 0 while not stck.isempty(): sum = sum + stck.pop() print "sum of stack: ", sum 25 Monomorphic Class in Python class Stack { private int stk[]; private int topp; public Stack(){stk=new int[100]; topp= 1; public void push(int s) { stk[++topp]=s; public void pop() { if(topp>=0) topp=topp 1; public boolean empty() { return topp<0; public int top() throws Exception { if(empty()) throw new Exception("stack empty"); else return stk[topp]; 26 Monomorphic Class in Python Parametric : Generics in Java 1 public class IntStackTest { public static void main(string args[]) throws Exception { Stack lifo = new Stack(); lifo.push(20); lifo.push(30); lifo.push(40); int sum = 0; while(! lifo.empty()) { sum = sum + lifo.top() ; lifo.pop(); System.out.println("sum of stack items " + sum); 27 Consider the Stack class example: class Stack<E> { private E[] mem = (E[]) new Object[4096]; private inttopp; public Stack() { topp = 1; public boolean empty() { return topp<0; E top() { assert(! empty()); return mem[topp]; void pop() { assert(! empty()); topp ; void push(e c) { assert(! full()); topp = topp+1; mem[topp] = c; After this definition stacks can be declared 28 Parametric : Generics in Java 2 After this definition stacks can be declared, but the declarations must provide an actual type for the type parameter: Stack<Integer> istk = new Stack<Integer>(); Stack<String> sstk = new Stack<String>(); and values can be pushed: istk.push(4); istk.push(16); istk.push(24); sstk.push("yellow"); sstk.push("blue"); sstk.push("red"); Given: Parametric : Generics in Java 3 Stack<Integer> istk = new Stack<Integer>(); Stack<String> sstk = new Stack<String>(); the following is NOT allowed: istk.push("pink"); it should give a compilation error. 29 30 5

Parametric in Haskell Consider the simple Haskell function: last s = if null s then error "no last element" else if null (tail s) then (head s) else last (tail s) the function does not depend on the type of the elements of the list the type is: last :: [a] > a where a is a type parameter, the type signature defines all the specific types that can be obtained by substituting any type for the letter a, eg.: [ Int ] > Int [ Float ] > Float [ [Int] ] > [Int] etc. And it is statically type safe, consider: 31 Parametric in Haskell And it is statically type safe, consider: 3 + (last (f x)).. the result of (last (f x)) should be Int because it is an argument to the operator +, the type of last is [a] >a so substituting Int for a (because that s the result) gives the argument to last as [Int] and that can be checked to make sure that s the result of (f x). 32 Parametric : Templates in C++ Parametric : Templates in C++ template <class E> class Stack { private: E mem[256]; int topp; public: Stack(void) { topp= 1; bool empty(void) { return topp<0; bool full(void) { return topp==255; E top(void) { assert(! empty()); return mem[topp]; void pop(void) { assert(! empty()); topp ; void push(e c) { assert(! full()); topp = topp+1; mem[topp] = c; ; 33 Like Java after the definition stacks can be declared, but the declarations must provide an actual type for the type parameter: Stack<int> istk; Stack<string> sstk; and values can be pushed: istk.push(4); istk.push(16); istk.push(24); sstk.push("yellow"); sstk.push("blue"); sstk.push("red"); but NOT: istk.push("pink"); that would, like Java, give a compilation error. But there is a big difference, the instantiation generates a new modified copy of the template. 34 Java before Generics Until version 1.5 Java didn t have a generic (or template) mechanism. Instead it was suggested that containers could hold values of type Object, and since every type is by definition a sub type of Object then by the rules of sub typing the container can hold values of any type. class Stack { protected Object mem[]; protected int topind; public Stack() { mem = new Object[100]; topind= 1; public boolean empty() { return topind<0; public boolean full() { return 99==topind; public Object top() { if(empty()) return null; else return mem[topind]; public void pop() { if(! empty()) topind=topind 1; public void push(object s) { if(! full()) { topind=topind+1; mem[topind]=s; 35 Java before Generics public class BadStackUse { public static void main(string args[]) { Stack filo = new Stack(); int sum = 0; filo.push(new Integer(22)); filo.push(new Integer(33)); filo.push("should be a number"); filo.push(new Integer(55)); System.out.println("Pop contents and add them up"); while(! filo.empty() ) { sum = sum + ((Integer)filo.top()).intValue(); filo.pop(); System.out.println("sum = " + sum); 36 6

Java before Generics Here the Stack objects can contain any type descended from Object, that includes all objects. BUT: when the values are popped off the stack they are only Objects so must be cast to the required type, allowing possible runtime errors! i.e When values are popped off the stack they are Objects (which don t all have an integer value) so they must be cast to Integer and then the int can be retrieved: sum = sum + ((Integer)filo.top()).intValue(); but other stuff, like the String above, can be accidentally pushed on the stack with no static compile time type error. this can cause a runtime type error: rabbit(340)$ java BadStackUse Pop contents and add them up java.lang.classcastexception: at BadStackUse.main(BadStackUse.java:27) 37 Overloading or ad hoc polymorphism Ad hoc polymorphism is different operations on different types but with the same name: the arithmetic operators +, *,, etc. are applicable to more than one type in explicitly programmer typed languages like Java it is simple: the compiler easily determines which instruction to use by the declared or inferred types of its operands user functions (or methods) can be overloaded : int sumsq(int a,int b) { return a*a + b*b; double sumsq(double a, double b) { return a*a + b*b; the compiler can infer which piece of code to use by the context: double x; sumsq(x,3.0) + 2.1.. obviously use the double sumsq function 38 Inheritance and class Base { String name; public Base(String n) { name=n; public String fullname() { return "Base: "+name; class Derived extends Base { public Derived(String n) { super(n); public String fullname() { return "Derived: "+name; public class SubTypeEg01 { public static void main(string args[]) { Base b = new Base("Mummy"); Derived d = new Derived("Baby"); Random rand = new Random(System.nanoTime()); Base bb = rand.nextint(2)==1? d : b; System.out.println( bb.fullname() ); 39 Inheritance and The program defines 2 classes with a subtype relationship, the method fullname() is different in each. Because derived class objects can be used anywhere a parent class object is needed, the variable bb can refer to either type, the compiler cannot know which class of object is referred to by bb when fullname() is called: System.out.println( bb.fullname() ); the runtime system must dynamically select the appropriate version of the method, this is called dynamic binding 40 7