SLIDE 1 Why Types Matter
Zheng Gao CREST, UCL
SLIDE 2 Russell’s Paradox
Let R be the set of all sets that are not members of themselves. Is R a member of itself?
- If so, this contradicts with R’s definition
- If not, by definition, R should contain
itself
Formalism in naïve set theory:
Let R = {x | x ∉ x}, then R ∈ R ⟺ R ∉ R
SLIDE 3
SLIDE 4
The Barber Paradox
There is a town with a male barber who shaves all and only those men who do not shave themselves. Who shaves the barber?
SLIDE 5 The Barber Paradox
There is a town with a male barber who shaves all and only those men who do not shave themselves. Who shaves the barber?
- If the barber does not shave himself, according to the
rule he must shave himself.
SLIDE 6 The Barber Paradox
There is a town with a male barber who shaves all and only those men who do not shave themselves. Who shaves the barber?
- If the barber does not shave himself, according to the
rule he must shave himself.
- If he does shave himself, according to the rule he will
not shave himself.
SLIDE 7 The Barber Paradox
There is a town with a male barber who shaves all and only those men who do not shave themselves. Who shaves the barber?
- If the barber does not shave himself, according to the
rule he must shave himself.
- If he does shave himself, according to the rule he will
not shave himself.
Naïve set theory contains contradiction
SLIDE 8 Types to the Rescue
Constructs a hierarchy of types. Any object is built only from those of higher types, which prevents circular referencing.
1) a barber as a citizen of the town, who shaves himself and 2) a barber as a professional, who shaves others are of different types.
SLIDE 9 Type Theory
An alternative to set theory as a foundation for mathematics, in which each term has a type Simply typed λ-calculus is one of the many forms of type theory, which consists of
- Base types
- Only one type constructor, ⟶, used to model the type
- f functions
SLIDE 10
The Evolution of Types
t
SLIDE 11
The Evolution of Types
t
SLIDE 12
The Evolution of Types
t
SLIDE 13
The Evolution of Types
t
SLIDE 14
The Evolution of Types
t
SLIDE 15
The Evolution of Types
t
SLIDE 16
Type System
A tractable method that assigns types to syntactic phrases that compose a program, and automatically checks whether the usage of these phrases comply with their types An over-approximation of the run-time behaviour of program terms
SLIDE 17 Static & Dynamic Type Checking
Source Code Executable Compilation Execution
SLIDE 18 Static & Dynamic Type Checking
Source Code Executable Compilation Execution Static type checking
SLIDE 19 Static & Dynamic Type Checking
Source Code Executable Compilation Execution Static type checking Early error detection
SLIDE 20 Static & Dynamic Type Checking
Source Code Executable Compilation Execution Static type checking Early error detection Increased run-time efficiency
SLIDE 21 Static & Dynamic Type Checking
Source Code Executable Compilation Execution Static type checking Early error detection Increased run-time efficiency Better documentation
SLIDE 22 Static & Dynamic Type Checking
Source Code Executable Compilation Execution Static type checking Dynamic type checking Early error detection Increased run-time efficiency Better documentation
SLIDE 23 Static & Dynamic Type Checking
Source Code Executable Compilation Execution Static type checking Dynamic type checking Early error detection Reduced implementation
Increased run-time efficiency Better documentation
SLIDE 24 Static & Dynamic Type Checking
Source Code Executable Compilation Execution Static type checking Dynamic type checking Early error detection Reduced implementation
Increased run-time efficiency Better documentation Better expressibility
SLIDE 25
Why We Care
Generally, almost all real-world programming languages have type systems which offers multiple benefits. Specifically for GI/GP, type systems have the promise to guide the search and avoid the construction of invalid individuals.
SLIDE 26 Java’s Static Type Checking
Suppose we have:
SLIDE 27
Java’s Static Type Checking
SLIDE 28 Java’s Static Type Checking
- Illegal. Compiler thinks new B().me()
returns an object of class A, but at run- time, this returns an objects of class B.
SLIDE 29 Java’s Static Type Checking
- Illegal. Compiler thinks new B().me()
returns an object of class A, but at run- time, this returns an objects of class B. Legal.
SLIDE 30 Java’s Static Type Checking
- Illegal. Compiler thinks new B().me()
returns an object of class A, but at run- time, this returns an objects of class B. Legal. Legal.
SLIDE 31 Java’s Static Type Checking
- Illegal. Compiler thinks new B().me()
returns an object of class A, but at run- time, this returns an objects of class B. Legal. Legal.
exception at run-time.
SLIDE 32 Hindley Milner’s Type System
One of the most famous type systems for the typed λ- calculus with parametric polymorphism:
- A fast (nearly linear time) algorithm that
automatically infer types of the constructs from their usage
- A set of typing rules, e.g.
SLIDE 33 HM Example
Let us assume that we have a function myFunc of type:
myFunc : ADT ⟶ int
And we want to infer the type of a function someFunc
someFunc (x) + myFunc (x)
SLIDE 34 Step One
someFunc (x) + myFunc (x)
SLIDE 35 Step One
someFunc (x) + myFunc (x)
x : α
SLIDE 36 Step Two
someFunc (x) + myFunc (x)
ADT ⟶ int x : α
SLIDE 37 Step Two
someFunc (x) + myFunc (x)
ADT ⟶ int α = ADT x : α
SLIDE 38 Step Two
someFunc (x) + myFunc (x)
ADT ⟶ int α = ADT x : α x : ADT
SLIDE 39 Step Three
someFunc (x) + myFunc (x)
ADT ⟶ int x : ADT
SLIDE 40 Step Three
someFunc (x) + myFunc (x)
ADT ⟶ int x : ADT +: int ⟶ int ⟶ int
SLIDE 41 Step Three
someFunc (x) + myFunc (x)
ADT ⟶ int x : ADT someFunc : ADT ⟶ int +: int ⟶ int ⟶ int
SLIDE 42
Polymorphism
The provision of a single interface to entities of different types
SLIDE 43
Polymorphism Parametric Ad Hoc Inclusion
SLIDE 44
Parametric Polymorphism
Rank-N polymorphic function is a function whose parameters are Rank-(N-1) polymorphic Generic programming in programming languages
SLIDE 45
Ad Hoc Polymorphism
Function overloading in programming languages
SLIDE 46
Inclusion Polymorphism
Inheritance creates inclusion polymorphism (subtyping)
SLIDE 47
Inclusion Polymorphism
Inheritance creates inclusion polymorphism (subtyping) Cat < Animal Dog < Animal
SLIDE 48 HM Limitations
- Limited to rank 1 parametric polymorphism
- Does not support ad hoc polymorphism
- No notion of subtyping
SLIDE 49 Limitation Example One
Suppose we have subtyping B < A, any function that takes arguments of type A is expected to takes arguments of type B as well.
someFunc (x) + myFunc (x)
ADT ⟶ int α = ADT ??? x : α x : ADT ???
SLIDE 50 Limitation Example One
Suppose we have subtyping B < A, any function that takes arguments of type A is expected to takes arguments of type B as well.
someFunc (x) + myFunc (x)
ADT ⟶ int α = ADT ??? x : α x : ADT ???
SLIDE 51 Limitation Example Two
In HM, an assumption set may contain at most one typing assumption for an construct The operator < , for example, has types:
char ⟶ char ⟶ bool int ⟶ int ⟶ bool
But it does not have the type:
∀α.α ⟶ α ⟶ bool
So any single typing is either too narrow or too wide
SLIDE 52 Intersection Types
Allow a term to have multiple types by introducing a type constructor ⋀, a universal type ω used for untypable constructs, and the following typing rules: In practice, intersection types enable function
SLIDE 53
Union Types
The dual notion of intersection types, which introduces a type constructor ⋁ and similar typing rules. In C / C++, union types are the construct union
SLIDE 54 Example
Consider the following code snippet in C++: The type of function foo would be: ((int ⋁ ADT) ⟶ int ⟶ void) ⋀ ((int ⋁ ADT) ⟶ float ⟶ void)
SLIDE 55 Example
Consider the following code snippet in C++: The type of function foo would be: ((int ⋁ ADT) ⟶ int ⟶ void) ⋀ ((int ⋁ ADT) ⟶ float ⟶ void)
SLIDE 56 Example
Consider the following code snippet in C++: The type of function foo would be: ((int ⋁ ADT) ⟶ int ⟶ void) ⋀ ((int ⋁ ADT) ⟶ float ⟶ void)
SLIDE 57 Example
Consider the following code snippet in C++: The type of function foo would be: ((int ⋁ ADT) ⟶ int ⟶ void) ⋀ ((int ⋁ ADT) ⟶ float ⟶ void)
SLIDE 58 Example
Consider the following code snippet in C++: The type of function foo would be: ((int ⋁ ADT) ⟶ int ⟶ void) ⋀ ((int ⋁ ADT) ⟶ float ⟶ void)
SLIDE 59
Retype
A general tool that automatically replaces certain types, together with the corresponding operations if necessary, of a program with new ones.
SLIDE 60
Potential Applications
Reducing energy consumption Precision tracking and improvement for FP programs New mutation operators in GI/GP Taint analysis Symbolic execution Auto-transplantation
SLIDE 61 Intersection Types in Retype
We use intersection types to cleanly model function
- verloading, because Retype may generate new overloads
- f an existing operator.
Consider the following code snippet: Assumption: an external function ext_func of type int ⟶ int Objective: retype int to ADT
SLIDE 62 Intersection Types in Retype
We use intersection types to cleanly model function
- verloading, because Retype may generate new overloads
- f an existing operator.
Consider the following code snippet: Assumption: an external function ext_func of type int ⟶ int Objective: retype int to ADT
Before retyping
SLIDE 63 Intersection Types in Retype
We use intersection types to cleanly model function
- verloading, because Retype may generate new overloads
- f an existing operator.
Consider the following code snippet: Assumption: an external function ext_func of type int ⟶ int Objective: retype int to ADT
+: int ⟶ int ⟶ int
Before retyping
SLIDE 64 Intersection Types in Retype
We use intersection types to cleanly model function
- verloading, because Retype may generate new overloads
- f an existing operator.
Consider the following code snippet: Assumption: an external function ext_func of type int ⟶ int Objective: retype int to ADT
+: int ⟶ int ⟶ int +: int ⟶ int ⟶ int
Before retyping
SLIDE 65 Intersection Types in Retype
We use intersection types to cleanly model function
- verloading, because Retype may generate new overloads
- f an existing operator.
Consider the following code snippet: Assumption: an external function ext_func of type int ⟶ int Objective: retype int to ADT
+: ADT ⟶ ADT ⟶ ADT +: ADT ⟶ int ⟶ ADT
After retyping