Type Checking and Type Inference

Similar documents
Types-2. Polymorphism

Types, Type Inference and Unification

Lecture #23: Conversion and Type Inference

Types and Type Inference

Types and Type Inference

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

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

CS558 Programming Languages

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

Lecture #13: Type Inference and Unification. Typing In the Language ML. Type Inference. Doing Type Inference

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

Topics Covered Thus Far CMSC 330: Organization of Programming Languages

Overloading, Type Classes, and Algebraic Datatypes

Data Types The ML Type System

Programming Languages and Compilers (CS 421)

Generic polymorphism on steroids

Programming Languages Lecture 14: Sum, Product, Recursive Types

CMSC 330: Organization of Programming Languages

Programming Languages Lecture 15: Recursive Types & Subtyping

Static Checking and Type Systems

cs242 Kathleen Fisher Reading: Concepts in Programming Languages, Chapter 6 Thanks to John Mitchell for some of these slides.

Outline. Introduction Concepts and terminology The case for static typing. Implementing a static type system Basic typing relations Adding context

COSE212: Programming Languages. Lecture 3 Functional Programming in OCaml

CSCI-GA Scripting Languages

TYPE INFERENCE. François Pottier. The Programming Languages Mentoring ICFP August 30, 2015

Type Systems, Type Inference, and Polymorphism

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

CS558 Programming Languages

CS558 Programming Languages

CVO103: Programming Languages. Lecture 5 Design and Implementation of PLs (1) Expressions

Programming Languages Fall 2013

Topic 9: Type Checking

Topic 9: Type Checking

COS 320. Compiling Techniques

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

Agenda. CS301 Session 11. Common type constructors. Things we could add to Impcore. Discussion: midterm exam - take-home or inclass?

Mutable References. Chapter 1

Principles of Programming Languages

Functional Programming

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

CS 565: Programming Languages. Spring 2008 Tu, Th: 16:30-17:45 Room LWSN 1106

CSE 307: Principles of Programming Languages

Type Inference. Prof. Clarkson Fall Today s music: Cool, Calm, and Collected by The Rolling Stones

Harvard School of Engineering and Applied Sciences Computer Science 152

CMSC 330: Organization of Programming Languages. Formal Semantics of a Prog. Lang. Specifying Syntax, Semantics

Type Systems. Seman&cs. CMPT 379: Compilers Instructor: Anoop Sarkar. anoopsarkar.github.io/compilers-class

Overview. Elements of Programming Languages. Another example. Consider the humble identity function

CSE 505. Lecture #9. October 1, Lambda Calculus. Recursion and Fixed-points. Typed Lambda Calculi. Least Fixed Point

CSE 431S Type Checking. Washington University Spring 2013

Programming Languages, Summary CSC419; Odelia Schwartz

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

CS131 Typed Lambda Calculus Worksheet Due Thursday, April 19th

301AA - Advanced Programming [AP-2017]

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

CSCI.6962/4962 Software Verification Fundamental Proof Methods in Computer Science (Arkoudas and Musser) Chapter p. 1/27

Lambda Calculus and Type Inference

Semantic Processing (Part 2)

Part III. Chapter 15: Subtyping

COMP 181. Agenda. Midterm topics. Today: type checking. Purpose of types. Type errors. Type checking

Static Semantics. Winter /3/ Hal Perkins & UW CSE I-1

Recursive Types and Subtyping

Tail Calls. CMSC 330: Organization of Programming Languages. Tail Recursion. Tail Recursion (cont d) Names and Binding. Tail Recursion (cont d)

Symbolic Computation and Common Lisp

CS 430 Spring Mike Lam, Professor. Data Types and Type Checking

Tracing Ambiguity in GADT Type Inference

Polymorphism and Type Inference

Some Advanced ML Features

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

OCaml. ML Flow. Complex types: Lists. Complex types: Lists. The PL for the discerning hacker. All elements must have same type.

Homework 3 COSE212, Fall 2018

SML A F unctional Functional Language Language Lecture 19

FUNCTIONAL AND LOGIC PROGRAMS

Programming Languages

Handout 2 August 25, 2008

Simply-Typed Lambda Calculus

Haskell 98 in short! CPSC 449 Principles of Programming Languages

CS 320: Concepts of Programming Languages

Recap from last time. Programming Languages. CSE 130 : Fall Lecture 3: Data Types. Put it together: a filter function

Programming Languages

Lambda Calculus and Type Inference

9/7/17. Outline. Name, Scope and Binding. Names. Introduction. Names (continued) Names (continued) In Text: Chapter 5

The Substitution Model. Nate Foster Spring 2018

CMSC 330: Organization of Programming Languages. Functional Programming with Lists

CSCE 314 Programming Languages. Type System

CSC324 Principles of Programming Languages

Polymorphism and Type Inference

CMSC 330: Organization of Programming Languages. Functional Programming with Lists

Basic concepts. Chapter Toplevel loop

Programming Language Features. CMSC 330: Organization of Programming Languages. Turing Completeness. Turing Machine.

CMSC 330: Organization of Programming Languages

Part III Chapter 15: Subtyping

Processadors de Llenguatge II. Functional Paradigm. Pratt A.7 Robert Harper s SML tutorial (Sec II)

Formal Semantics. Prof. Clarkson Fall Today s music: Down to Earth by Peter Gabriel from the WALL-E soundtrack

CS558 Programming Languages

Type Systems COMP 311 Rice University Houston, Texas

Scope and Introduction to Functional Languages. Review and Finish Scoping. Announcements. Assignment 3 due Thu at 11:55pm. Website has SML resources

The Substitution Model

ML Type Inference and Unification. Arlen Cox

CS153: Compilers Lecture 14: Type Checking

22c:111 Programming Language Concepts. Fall Types I

Transcription:

Type Checking and Type Inference Principles of Programming Languages CSE 307 1 Types in Programming Languages 2 Static Type Checking 3 Polymorphic Type Inference Version: 1.8 17:20:56 2014/08/25 Compiled at 18:31 on 2014/12/01 Programming Languages Type Checking and Inference CSE 307 1 / 41

Use of datatype information The set of possible values denoted by a name or kept in a cell in store is denoted by a data type. Common data types include integers, floating point or real numbers, Booleans, and structured data. The type information is used for many purposes: Data representation: Type determines how data is represented (e.g. fixed precision integers; floating point for reals) Operation selection: Type information is used to select which among a set of overloaded operators is applied. (e.g. in x+y, a.f(b)). Compile-time error detection: Type information is used to check for operations on inappropriate data. Programming Languages Type Checking and Inference CSE 307 2 / 41

Languages and Datatypes (1) Dynamically-typed languages: The datatype information is known and tracked only at run-time. So, data representation, operation selection, and error detection can all be performed only at run-time. Languages such as Scheme, Prolog, Python, and Javascript are all dynamically typed. Statically-typed languages: The datatype information is tracked and checked at compile-time, before a program s execution. Data representation is determined at compile time. Much of operation selection and error detection can be performed at compile-time as well. Languages such as SML, C, and Pascal are statically typed. Java is considered statically-typed as well even though operation selection and some of error detection is performed at run-time. Programming Languages Type Checking and Inference CSE 307 3 / 41

Languages and Datatypes (2) Strongly-typed languages: The datatype information is used to ensure error-free operations. Languages such as SML, Java, Scheme, Prolog, Python, and Ruby are all strongly typed. Languages such as C, C++, and Perl are not strongly typed (aka weakly typed). Common confusion: static typing vs. strong typing. Statically typed Dynamically typed Strongly typed SML, Java Scheme, Prolog, Python Weakly typed C, C++ Perl Static/dynamic only refers to when type information is known and tracked. Strong/weak refers to whether type information is always tracked and whether it is used for operation selection/error detection. Programming Languages Type Checking and Inference CSE 307 4 / 41

Why is C weakly typed? Use of type casts on pointers (e.g. a pointer to void can be cast to be a pointer to int). Use of unions: overlapping memory areas used for different types of values. Lack of memory safety (array bounds, dangling references to automatic variables). Programming Languages Type Checking and Inference CSE 307 5 / 41

Static Type Checking A procedure that, without running the program, determines the types of expressions and checks for improper operations. We generally use this terminology for checking datatypes without considering the control flow of the program (aka flow-insensitive). Type-checking techniques are used for more complex types, e.g. non-null references, which may use control flow information (e.g. type of a variable at a specific statement in the program). Static type checking can be (and is often) specified using inference rules. Programming Languages Type Checking and Inference CSE 307 6 / 41

Type Checking Given an expression e and a type t, is the expression well-typed w.r.t. t? e.g. is x+y:int well typed?... depends on the types of x and y Type environment Γ: a function that associates a type with each name in the program. e.g. {x int, y int}. Type judgement Γ e : t Under type environment Γ the expression e has type t. Type inference: given an expression e, is there a type t such that e is well-typed w.r.t. t? Programming Languages Type Checking and Inference CSE 307 7 / 41

Type Expressions We can construct expressions over types analogous to how we construct arithmetic and boolean expressions over numeric and boolean constants and variables. Type expressions can be: Type names (e.g. int, bool, float) t 1 t 2 where t 1, t 2 are type exprs. t 1 t 2 where t 1, t 2 are type exprs. list of t where t is a type expr. ref t where t is a type expr.... Type variables (e.g. α, α, β,...) Programming Languages Type Checking and Inference CSE 307 8 / 41

Example Expression Language We will use a small language of expressions for formally defining a type system and the corresponding type checking and inference procedures. As usual, we will start with a trivial language and add language constructs as we proceed. Ultimately, this language will look (i.e. be syntactically) and behave (i.e. be semantically) similar to OCAML. Programming Languages Type Checking and Inference CSE 307 9 / 41

Constants Boolean Constants: true, false, represented in abstract syntax as True and False, resp. Integer Constants: usual, represented in abstract syntax as Int(i) Floating Point Constants: usual, represented in abstract syntax as Float(x) Unit Constant: written in concrete syntax as () and represented in abstract syntax as Unit. Programming Languages Type Checking and Inference CSE 307 10 / 41

Type Rules Constants Int Float Bool t Bool f Unit Γ Int(i) : int Γ Float(x) : float Γ True : bool Γ False : bool Γ Unit : unit Each type judgement of the form Γ e : t associates a type t with expression e in type environment Γ. The inference of types for constants, as specified above, is trivial. Unsurprising fact: the type environment is not used to infer types of constants. Programming Languages Type Checking and Inference CSE 307 11 / 41

Boolean Operators And(e 1, e 2 ), Or(e 1, e 2 ), Not(e 1 ) where e 1 and e 2 are expressions. Note that concrete syntax may use an infix notation for these operators. If(e 1, e 2, e 3 ), where e 1, e 2 and e 3 are expressions. In concrete syntax, these expressions may be written as: if e 1 then e 2 else e 3 Programming Languages Type Checking and Inference CSE 307 12 / 41

Type Rules Boolean Operators And Or Not If Γ e 1 : bool Γ e 2 : bool Γ And(e 1, e 2 ) : bool Γ e 1 : bool Γ e 2 : bool Γ Or(e 1, e 2 ) : bool Γ e 1 : bool Γ Not(e 1 ) : bool Γ e 1 : bool Γ e 2 : t Γ e 3 : t Γ If(e 1, e 2, e 3 ) : t Note the use of t in the If rule: The condition in if must be a bool The then- and else- expressions must be of same (but arbitrary) type t. The whole expression will then have type t. Programming Languages Type Checking and Inference CSE 307 13 / 41

Arithmetic Operators Add(e 1, e 2 ), Sub(e 1, e 2 ),... where e 1 and e 2 are expressions. Comparison operations such as Equal(e 1, e 2 ), Less(e 1, e 2 ),... where e 1 and e 2 are expressions. Note that concrete syntax may use an infix notation for these operators. Programming Languages Type Checking and Inference CSE 307 14 / 41

Type Rules Arithmetic Operators Add 1 Add 2 Add 3 Add 4 Γ e 1 : int Γ e 2 : int Γ Add(e 1, e 2 ) : int Γ e 1 : int Γ e 2 : float Γ Add(e 1, e 2 ) : float Γ e 1 : float Γ e 2 : int Γ Add(e 1, e 2 ) : float Γ e 1 : float Γ e 2 : float Γ Add(e 1, e 2 ) : float The type rules explicitly list the cases when the built-in operators are overloaded. Type rules for other arithmetic operators are similar. Programming Languages Type Checking and Inference CSE 307 15 / 41

Let Expressions We now add the ability to give names to expressions and use them elsewhere, as in: let x = 2 in x+3 Concrete syntax: let v = e 1 in e 2 Abstract syntax: let(v, e 1, e 2 ), where v is an identifier, and e 1 and e 2 are expressions. Programming Languages Type Checking and Inference CSE 307 16 / 41

Type Rules Let Expressions Var Let (x t) Γ Γ Id(x) : t Γ e 1 : t 1 (x t 1 ) Γ e 2 : t Γ Let(x, e 1, e 2 ) : t The Var rule uses the type environment to determine the type of an identifier. In the Let rule, the type of the entire expression is the same as the type of the inner expression e 2 since e 2 may have x free, its type environment needs to specify the type of x and that type is same as the type of e 1. Programming Languages Type Checking and Inference CSE 307 17 / 41

Functions Following the lambda calculus: Abstraction for defining new functions. Concrete syntax: fun x -> e Abstract syntax: fun(x, e), where x is an identifier and e is an expression. Application for calling functions. Concrete syntax: (e 1 e 2 ) Abstract syntax: apply(e 1, e 2 ), where e 1 and e 2 are expressions. Programming Languages Type Checking and Inference CSE 307 18 / 41

Type Rules Functions Fun App (x t 1 ) Γ e : t 2 Γ Fun(x, e) : t 1 t 2 Γ e 1 : t 2 t Γ e 2 : t 2 Γ Apply(e 1, e 2 ) : t The Fun rule augments the environment with the formal parameter s type; and uses this environment to determine the type of e. According to the App rule, the first expression must be a function (of type t 1 t 2 ) and the second expression s type must match that of the function s parameter. Programming Languages Type Checking and Inference CSE 307 19 / 41

Type Rules Functions(2) Fun App (x t 1 ) Γ e : t 2 Γ Fun(x, e) : t 1 t 2 Γ e 1 : t 2 t Γ e 2 : t 2 Γ Apply(e 1, e 2 ) : t In Fun(x, e), the type of x is not specified, so t 1 can be any type Programming Languages Type Checking and Inference CSE 307 20 / 41

Type Rules Functions(2) Fun App (x t 1 ) Γ e : t 2 Γ Fun(x, e) : t 1 t 2 Γ e 1 : t 2 t Γ e 2 : t 2 Γ Apply(e 1, e 2 ) : t In Fun(x, e), the type of x is not specified, so t 1 can be any type... as long as, for that t 1, e has a valid type. Programming Languages Type Checking and Inference CSE 307 20 / 41

Type Rules Functions(2) Fun App (x t 1 ) Γ e : t 2 Γ Fun(x, e) : t 1 t 2 Γ e 1 : t 2 t Γ e 2 : t 2 Γ Apply(e 1, e 2 ) : t In Fun(x, e), the type of x is not specified, so t 1 can be any type... as long as, for that t 1, e has a valid type. As a consequence, Fun(x, e) may not have a unique type! Programming Languages Type Checking and Inference CSE 307 20 / 41

Type Rules Functions(2) Fun App (x t 1 ) Γ e : t 2 Γ Fun(x, e) : t 1 t 2 Γ e 1 : t 2 t Γ e 2 : t 2 Γ Apply(e 1, e 2 ) : t In Fun(x, e), the type of x is not specified, so t 1 can be any type... as long as, for that t 1, e has a valid type. As a consequence, Fun(x, e) may not have a unique type! E.g., Fun(x, Id(x)) has type int int, float float, bool bool, int int int int,... Programming Languages Type Checking and Inference CSE 307 20 / 41

Type Rules Functions(2) Fun App (x t 1 ) Γ e : t 2 Γ Fun(x, e) : t 1 t 2 Γ e 1 : t 2 t Γ e 2 : t 2 Γ Apply(e 1, e 2 ) : t In Fun(x, e), the type of x is not specified, so t 1 can be any type... as long as, for that t 1, e has a valid type. As a consequence, Fun(x, e) may not have a unique type! E.g., Fun(x, Id(x)) has type int int, float float, bool bool, int int int int,... In ML, we have variables ranging over types (aka type variables). This lets us define the most general type of an expression, called its principal type. Programming Languages Type Checking and Inference CSE 307 20 / 41

Pairs As in C, pair datatypes are added with: Pair constructor (concrete: (e 1, e 2 ); abstract: Pair(e 1, e 2 )). Fst and Snd access operators (concrete: e.1, and e.2, respectively; abstract: Fst(e) and Snd(e)). Programming Languages Type Checking and Inference CSE 307 21 / 41

Type Rules Datatypes: Pairs Pair Fst Snd Γ e 1 : t 1 Γ e 2 : t 2 Γ Pair(e 1, e 2 ) : t 1 t 2 Γ e : t 1 t 2 Γ Fst(e) : t 1 Γ e : t 1 t 2 Γ Snd(e) : t 2 The Pair rule judges the type of the constructed pair using the types of its components. The Fst and Snd rules apply only when the operand is of a pair type; the rules then specify which component of the pair type to extract. Programming Languages Type Checking and Inference CSE 307 22 / 41

Lists Similar to pairs, lists can be added with: Cons and Nil constructors (concrete: e 1 ::e 2, and [], respectively; abstract: Cons(e 1, e 2 ), and Nil). Hd and Tl access operators (concrete: hd(e), and tl(e), respectively; abstract: Hd(e) and Tl(e)). isnil operator to test whether a list is nil or not. Programming Languages Type Checking and Inference CSE 307 23 / 41

Type Rules Lists Cons Nil Hd Tl IsNil Γ e 1 : t Γ e 2 : list of t Γ Cons(e 1, e 2 ) : list of t Γ Nil : list of t Γ e : list of t Γ Hd(e) : t Γ e : list of t Γ Tl(e) : list of t Γ e : list of t Γ IsNil(e) : bool Programming Languages Type Checking and Inference CSE 307 24 / 41

References Finally, we add OCAML-style references for writing programs with side effects. Ref(e) to create new references (initialized to the value of e) Deref(e) to dereference an existing reference (concrete syntax:!e) Assign(e 1, e 2 ) to assign the value of one expression (e 2 ) to the location supplied by another expression (e 1 ). Concrete syntax: e 1 := e 2 Programming Languages Type Checking and Inference CSE 307 25 / 41

Type Rules References Ref Deref Assign Γ e 1 : t 1 Γ Ref(e 1 ) : ref t 1 Γ e 1 : ref t 1 Γ Deref(e 1 ) : t 1 Γ e 1 : ref t 1 Γ e 2 : t 1 Γ Assign(e 1, e 2 ) : unit The Ref rule judges the type of the constructed cell using the type of the stored value. The Deref rule does the converse: determines the type of a value in a cell based on the type of its reference. The Assign requires the l.h.s. to be a reference type, and r.h.s. to be a value of the same type. Programming Languages Type Checking and Inference CSE 307 26 / 41

Type Inference Infer the type of an expression given the types of the subexpressions. Consider the expression fst(1,2): Int(1) Int(2) Pair Fst Programming Languages Type Checking and Inference CSE 307 27 / 41

Type Inference Infer the type of an expression given the types of the subexpressions. Consider the expression fst(1,2): Int(1) :int Int(2) :int Pair Fst Type of Int(1) and Int(2) are int (from rules for constants) Programming Languages Type Checking and Inference CSE 307 27 / 41

Type Inference Infer the type of an expression given the types of the subexpressions. Consider the expression fst(1,2): Int(1) :int Int(2) :int Pair :int * int Fst Type of Int(1) and Int(2) are int (from rules for constants) Type of Pair(e 1, e 2 ) is t 1 t 2 where t i is the type of e i (from Pair rule) Programming Languages Type Checking and Inference CSE 307 27 / 41

Type Inference Infer the type of an expression given the types of the subexpressions. Consider the expression fst(1,2): Int(1) :int Int(2) :int Pair :int * int Fst :int Type of Int(1) and Int(2) are int (from rules for constants) Type of Pair(e 1, e 2 ) is t 1 t 2 where t i is the type of e i (from Pair rule) Type of Fst(e) is t 1 if e is of type t 1 t 2 (from Fst rule) Programming Languages Type Checking and Inference CSE 307 27 / 41

Type Reconstruction Introduction Can we infer the types of the subexpressions (or at least, some constraints on their types) assuming the full expression is well-typed? Consider the expression fst(x,y): Id(x) Id(y) Pair Fst Programming Languages Type Checking and Inference CSE 307 28 / 41

Type Reconstruction Introduction Can we infer the types of the subexpressions (or at least, some constraints on their types) assuming the full expression is well-typed? Consider the expression fst(x,y): Id(x) : α Id(y) : β Pair Fst Types of x and y are assumed to be α and β. (i.e., some unknown type, but not necessarily the same). Programming Languages Type Checking and Inference CSE 307 28 / 41

Type Reconstruction Introduction Can we infer the types of the subexpressions (or at least, some constraints on their types) assuming the full expression is well-typed? Consider the expression fst(x,y): Id(x) : α Id(y) : β Pair : α β Fst Types of x and y are assumed to be α and β. (i.e., some unknown type, but not necessarily the same). Type of Pair(e 1, e 2 ) is t 1 t 2 where t i is the type of e i (from Pair rule) Programming Languages Type Checking and Inference CSE 307 28 / 41

Type Reconstruction Introduction Can we infer the types of the subexpressions (or at least, some constraints on their types) assuming the full expression is well-typed? Consider the expression fst(x,y): Id(x) : α Id(y) : β Pair : α β Fst : α Types of x and y are assumed to be α and β. (i.e., some unknown type, but not necessarily the same). Type of Pair(e 1, e 2 ) is t 1 t 2 where t i is the type of e i (from Pair rule) Type of Fst(e) is t 1 if e is of type t 1 t 2 (from Fst rule) Programming Languages Type Checking and Inference CSE 307 28 / 41

Type Reconstruction Example 2 Can we infer the types of the subexpressions (or at least, some constraints on their types) assuming the full expression is well-typed? Consider fun x -> fun y -> x: Id(x) y Fun x Fun Programming Languages Type Checking and Inference CSE 307 29 / 41

Type Reconstruction Example 2 Can we infer the types of the subexpressions (or at least, some constraints on their types) assuming the full expression is well-typed? Consider fun x -> fun y -> x: Id(x) y Fun x : α Fun Types of x and y are assumed to be α and β. (i.e., some unknown type, but not necessarily the same). Programming Languages Type Checking and Inference CSE 307 29 / 41

Type Reconstruction Example 2 Can we infer the types of the subexpressions (or at least, some constraints on their types) assuming the full expression is well-typed? Consider fun x -> fun y -> x: Id(x) y : β Fun x : α Fun Types of x and y are assumed to be α and β. (i.e., some unknown type, but not necessarily the same). Programming Languages Type Checking and Inference CSE 307 29 / 41

Type Reconstruction Example 2 Can we infer the types of the subexpressions (or at least, some constraints on their types) assuming the full expression is well-typed? Consider fun x -> fun y -> x: Id(x) : α y : β Fun x : α Fun Types of x and y are assumed to be α and β. (i.e., some unknown type, but not necessarily the same). Type of innermost x is same as its assumption (Id rule). Programming Languages Type Checking and Inference CSE 307 29 / 41

Type Reconstruction Example 2 Can we infer the types of the subexpressions (or at least, some constraints on their types) assuming the full expression is well-typed? Consider fun x -> fun y -> x: Id(x) : α y : β Fun : β α x : α Fun Types of x and y are assumed to be α and β. (i.e., some unknown type, but not necessarily the same). Type of innermost x is same as its assumption (Id rule). Type of (fun y ->e) is t 1 t 2 if y is of type t 2 (from Fun rule) Programming Languages Type Checking and Inference CSE 307 29 / 41

Type Reconstruction Example 2 Can we infer the types of the subexpressions (or at least, some constraints on their types) assuming the full expression is well-typed? Consider fun x -> fun y -> x: Id(x) : α y : β Fun : β α x : α Fun : α β α Types of x and y are assumed to be α and β. (i.e., some unknown type, but not necessarily the same). Type of innermost x is same as its assumption (Id rule). Type of (fun y ->e) is t 1 t 2 if y is of type t 2 (from Fun rule) Type of (fun x ->e) is t 1 t 2 if x is of type t 2 (from Fun rule) Programming Languages Type Checking and Inference CSE 307 29 / 41

Type Reconstruction Example 3 Consider fun x -> if fst(x) then 1 else snd(x) Since the entire expression is of the form fun x -> e, its type is α β, where x : α and e : β. Let s determine the type of e under the environment {x α}. Since e is an if expression, we have the following: 1 fst(x) : bool 2 1: β 3 snd(x): β From 1: β, we get β = int. From x:α and fst(x):bool, and from the rule Fst, we get α = bool γ. From x:α and snd(x):int, and from the rule Snd, we get, α = δ int. From the last two steps, we get α = bool int and hence the original expressions type is: bool int int Programming Languages Type Checking and Inference CSE 307 30 / 41

Type Unification Motivation In the previous example, we initially assigned types denoted by type variables to certain identifiers. As type inference proceeded, we discovered constraints on those type variables, e.g. α = bool γ. The constraints are all equality constraints, hence if α 1 = α 2 and α 2 = α 3 then α 1 = α 3. From bool γ = δ int, we get γ = int and δ = bool. More formally, the constraints are solved using unification, defined next. Programming Languages Type Checking and Inference CSE 307 31 / 41

Type Unification Two type expressions t 1, t 2 are said to unify iff there is some substitution θ to the type variables in t 1 and t 2 such that t 1 θ = t 2 θ. Examples: A type variable α unifies with any type expression t that does not contain α. α and list of β unify, setting α = list of β. list of α and list of β unify, setting α = β. int and list of β do not unify. α 1 α 2 and list of β do not unify. α and list of α do not unify. Type unification is the core of Hindley-Milner type inference. Programming Languages Type Checking and Inference CSE 307 32 / 41

Polymorphic Types The type rules can be used to find out the constraints on Γ and t such that Γ e : t is derivable from the empty type judgement. We will illustrate the use of these rules informally: Find the type of fun x -> x Programming Languages Type Checking and Inference CSE 307 33 / 41

Polymorphic Types The type rules can be used to find out the constraints on Γ and t such that Γ e : t is derivable from the empty type judgement. We will illustrate the use of these rules informally: Find the type of fun x -> x Since it is a function definition, we represent the type of its formal parameter to be some type variable, say α. Programming Languages Type Checking and Inference CSE 307 33 / 41

Polymorphic Types The type rules can be used to find out the constraints on Γ and t such that Γ e : t is derivable from the empty type judgement. We will illustrate the use of these rules informally: Find the type of fun x -> x Since it is a function definition, we represent the type of its formal parameter to be some type variable, say α. We evaluate the type of the function s body assuming x is of type α. Programming Languages Type Checking and Inference CSE 307 33 / 41

Polymorphic Types The type rules can be used to find out the constraints on Γ and t such that Γ e : t is derivable from the empty type judgement. We will illustrate the use of these rules informally: Find the type of fun x -> x Since it is a function definition, we represent the type of its formal parameter to be some type variable, say α. We evaluate the type of the function s body assuming x is of type α. The type of its body is then determined to be α as well. Programming Languages Type Checking and Inference CSE 307 33 / 41

Polymorphic Types The type rules can be used to find out the constraints on Γ and t such that Γ e : t is derivable from the empty type judgement. We will illustrate the use of these rules informally: Find the type of fun x -> x Since it is a function definition, we represent the type of its formal parameter to be some type variable, say α. We evaluate the type of the function s body assuming x is of type α. The type of its body is then determined to be α as well. Som the function s type is α α. Programming Languages Type Checking and Inference CSE 307 33 / 41

Polymorphic Types (contd.) A function is said to be polymorphic if it has more than one type. Since fun x -> x is of type α α for any type α, the function is polymorphic. This form of polymorphism is called parametric polymorphism: f is polymorphic w.r.t. type parameter α. The type parameter for fun x -> x is implicit, and so this is also called implicit parametric polymorphism. Consider the following OCAML definition of a tree data structure: type a tree = Empty Node of a * a tree * a tree;; This defines trees for different node types, and hence is polymorphic. Since the node types is given as a parameter to the datatype definition, this is called implicit parametric polymorphism. Programming Languages Type Checking and Inference CSE 307 34 / 41

Unification and parametric polymorphism Consider fun x -> if (fst(x)) then 1 else (x,1) If the type of the expression is α β, we get: 1 1 : β, which means β = int, and 2 (x,1) : β, which means β = α int. int and α int do not unify! Hence there is no type for the expression. The expression is not well-typed. Programming Languages Type Checking and Inference CSE 307 35 / 41

Omega Consider fun x -> (x x) This is the first part of the ω-combinator introduced in the lambda calculus. If the type of the expression is α β, we get 1 x : α, and 2 (x x) : β Rule App says that if (e 1 e 2 ) : β then e 1 : γ β and e 2 : γ. Hence we also have the following constraints: 1 x : γ β 2 x : γ γ and γ β do not unify! Hence ω is not well-typed. By a similar argument, we can show that the Y-combinator is also not well-typed. Programming Languages Type Checking and Inference CSE 307 36 / 41

ML s Type Inference ML s type inference proceeds very similar to our definition of types, with two main changes. 1 ML s let is polymorphic: every use of a let-defined identifier may have a different, incompatible type. Our rules have (implicitly) demanded that all uses of an identifier have the same consistent set of types. 2 ML has user-defined types and uses pattern matching in function definitions. Type checking for these can also be formalized as inference rules, but following them strictly becomes tedious, so we ll explain these only with examples. Programming Languages Type Checking and Inference CSE 307 37 / 41

ML s Type Inference Example 1 Find the type of g defined as let g y = match y with (x::xs) -> x 1 We know g is a function so has type α β. Programming Languages Type Checking and Inference CSE 307 38 / 41

ML s Type Inference Example 1 Find the type of g defined as let g y = match y with (x::xs) -> x 1 We know g is a function so has type α β. 2 Hence y is of type α. Programming Languages Type Checking and Inference CSE 307 38 / 41

ML s Type Inference Example 1 Find the type of g defined as let g y = match y with (x::xs) -> x 1 We know g is a function so has type α β. 2 Hence y is of type α. 3 For match, the pattern (x::xs) must have type α, same as y. Programming Languages Type Checking and Inference CSE 307 38 / 41

ML s Type Inference Example 1 Find the type of g defined as let g y = match y with (x::xs) -> x 1 We know g is a function so has type α β. 2 Hence y is of type α. 3 For match, the pattern (x::xs) must have type α, same as y. 4 From the definition of :: we now infer that α = γ list, x is of type γ and xs is of type γ list. Programming Languages Type Checking and Inference CSE 307 38 / 41

ML s Type Inference Example 1 Find the type of g defined as let g y = match y with (x::xs) -> x 1 We know g is a function so has type α β. 2 Hence y is of type α. 3 For match, the pattern (x::xs) must have type α, same as y. 4 From the definition of :: we now infer that α = γ list, x is of type γ and xs is of type γ list. 5 The return type of g must be same as the type of x; hence from (1) and (3), we know β = γ. Programming Languages Type Checking and Inference CSE 307 38 / 41

ML s Type Inference Example 1 Find the type of g defined as let g y = match y with (x::xs) -> x 1 We know g is a function so has type α β. 2 Hence y is of type α. 3 For match, the pattern (x::xs) must have type α, same as y. 4 From the definition of :: we now infer that α = γ list, x is of type γ and xs is of type γ list. 5 The return type of g must be same as the type of x; hence from (1) and (3), we know β = γ. 6 Hence g has type γ list γ. Programming Languages Type Checking and Inference CSE 307 38 / 41

ML s Type Inference Example 2 Find the type of len defined by let rec len y = match y with [ ] > 0 (x::xs) > 1 + (len xs) 1 We know len is a function so has type α β. Programming Languages Type Checking and Inference CSE 307 39 / 41

ML s Type Inference Example 2 Find the type of len defined by let rec len y = match y with [ ] > 0 (x::xs) > 1 + (len xs) 1 We know len is a function so has type α β. 2 The expression [] (l.h.s. pattern of first match case) must have type α; from the definition of [] we now infer that α = γ list. Programming Languages Type Checking and Inference CSE 307 39 / 41

ML s Type Inference Example 2 Find the type of len defined by let rec len y = match y with [ ] > 0 (x::xs) > 1 + (len xs) 1 We know len is a function so has type α β. 2 The expression [] (l.h.s. pattern of first match case) must have type α; from the definition of [] we now infer that α = γ list. 3 The return type of len must be same as the type of 0; hence from (1), we know β = int. Programming Languages Type Checking and Inference CSE 307 39 / 41

ML s Type Inference Example 2 Find the type of len defined by let rec len y = match y with [ ] > 0 (x::xs) > 1 + (len xs) 1 We know len is a function so has type α β. 2 The expression [] (l.h.s. pattern of first match case) must have type α; from the definition of [] we now infer that α = γ list. 3 The return type of len must be same as the type of 0; hence from (1), we know β = int. 4 From the second match case, if α = γ list then x must be of type γ and xs must be of type γ list. Programming Languages Type Checking and Inference CSE 307 39 / 41

ML s Type Inference Example 2 Find the type of len defined by let rec len y = match y with [ ] > 0 (x::xs) > 1 + (len xs) 1 We know len is a function so has type α β. 2 The expression [] (l.h.s. pattern of first match case) must have type α; from the definition of [] we now infer that α = γ list. 3 The return type of len must be same as the type of 0; hence from (1), we know β = int. 4 From the second match case, if α = γ list then x must be of type γ and xs must be of type γ list. 5 From (3), we know the rhs of second eqn must be of type int. Programming Languages Type Checking and Inference CSE 307 39 / 41

ML s Type Inference Example 2 Find the type of len defined by let rec len y = match y with [ ] > 0 (x::xs) > 1 + (len xs) 1 We know len is a function so has type α β. 2 The expression [] (l.h.s. pattern of first match case) must have type α; from the definition of [] we now infer that α = γ list. 3 The return type of len must be same as the type of 0; hence from (1), we know β = int. 4 From the second match case, if α = γ list then x must be of type γ and xs must be of type γ list. 5 From (3), we know the rhs of second eqn must be of type int. 6 len is of type γ list int. Since xs is of type γ list, len xs is int. Since 1 is of type int, 1 + len xs is of type int as required by (5). Hence len is well typed and has type γ list int. Programming Languages Type Checking and Inference CSE 307 39 / 41

ML s Type Inference (Example 2-a) Find the type of len2a defined by let rec len2a y = match y with [ ] > 0 (x::xs) > 1.0 + (len2a xs) 1 5. The first 5 steps are the same as in the previous example. 6. We know that len2a is of type γ list int. Since xs is of type γ list, len2a xs is of type int. Since 1.0 is of type float, 1 + len2a xs is not well typed. Hence len2a is not well typed. Programming Languages Type Checking and Inference CSE 307 40 / 41

ML s Type Inference (Example 2-b) Find the type of len2a defined by let rec len2b y = match y with [ ] > 0 (x::xs) > 1 + (len2b x) 1 5. The first 5 steps are the same as in the previous example. 6. We know that len2b is of type γ list int. Since x is of type γ for len2b x to be well typed, γ = γ list. Since there is no type γ such that γ = γ list (see Type Unification), len2b x is not well typed. Hence len2b is not well typed. Programming Languages Type Checking and Inference CSE 307 41 / 41