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

Similar documents
Lecture #23: Conversion and Type Inference

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

Type Checking and Type Inference

Overloading, Type Classes, and Algebraic Datatypes

CS558 Programming Languages

CS558 Programming Languages

CS558 Programming Languages

CS-XXX: Graduate Programming Languages. Lecture 17 Recursive Types. Dan Grossman 2012

Lecture 19: Functions, Types and Data Structures in Haskell

CSE-505: Programming Languages. Lecture 20.5 Recursive Types. Zach Tatlock 2016

l e t print_name r = p r i n t _ e n d l i n e ( Name : ^ r. name)

Types-2. Polymorphism

CS 11 Haskell track: lecture 1

COSE212: Programming Languages. Lecture 3 Functional Programming in OCaml

Type Systems, Type Inference, and Polymorphism

Exercises on ML. Programming Languages. Chanseok Oh

Principles of Programming Languages 2017W, Functional Programming

Programming Languages and Compilers (CS 421)

COP4020 Programming Languages. Functional Programming Prof. Robert van Engelen

Lambda Calculus and Type Inference

Imperative languages

CMSC 330: Organization of Programming Languages

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

Program Syntax; Operational Semantics

News. Programming Languages. Complex types: Lists. Recap: ML s Holy Trinity. CSE 130: Spring 2012

Mini-ML. CS 502 Lecture 2 8/28/08

Programming Languages Lecture 14: Sum, Product, Recursive Types

Lambda Calculus and Type Inference

Flang typechecker Due: February 27, 2015

CS 314 Principles of Programming Languages

CSE 3302 Programming Languages Lecture 8: Functional Programming

Programming Paradigms

CSCI-GA Scripting Languages

ML 4 Unification Algorithm

Introduction to Lambda Calculus. Lecture 7 CS /08/09

CS 457/557: Functional Languages

Redefinition of an identifier is OK, but this is redefinition not assignment; Thus

CS 242. Fundamentals. Reading: See last slide

Hard deadline: 3/28/15 1:00pm. Using software development tools like source control. Understanding the environment model and type inference.

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

Part VI. Imperative Functional Programming

SCHEME The Scheme Interpreter. 2 Primitives COMPUTER SCIENCE 61A. October 29th, 2012

A First Look at ML. Chapter Five Modern Programming Languages, 2nd ed. 1

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

CMSC 330: Organization of Programming Languages

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

SML A F unctional Functional Language Language Lecture 19

Programming Languages

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

Currying fun f x y = expression;

Foundations. Yu Zhang. Acknowledgement: modified from Stanford CS242

To figure this out we need a more precise understanding of how ML works

CS 320: Concepts of Programming Languages

Exercise 1 ( = 18 points)

CS 4110 Programming Languages & Logics. Lecture 28 Recursive Types

CSC324- TUTORIAL 5. Shems Saleh* *Some slides inspired by/based on Afsaneh Fazly s slides

1 Terminology. 2 Environments and Static Scoping. P. N. Hilfinger. Fall Static Analysis: Scope and Types

Handout 2 August 25, 2008

Lecture #3: Environments

Questions? Static Semantics. Static Semantics. Static Semantics. Next week on Wednesday (5 th of October) no

Lecture 5: Lazy Evaluation and Infinite Data Structures

Simple Unification-based Type Inference for GADTs

CPS 506 Comparative Programming Languages. Programming Language Paradigm

Types and Programming Languages. Lecture 5. Extensions of simple types

Functional programming Primer I

A Third Look At ML. Chapter Nine Modern Programming Languages, 2nd ed. 1

How does ML deal with +?

Programming Languages

Functional Programming

F28PL1 Programming Languages. Lecture 12: Standard ML 2

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

Programming Language Concepts, CS2104 Lecture 7

Types and Type Inference

A Fourth Look At ML. Chapter Eleven Modern Programming Languages, 2nd ed. 1

SCHEME AND CALCULATOR 5b

Summer 2017 Discussion 10: July 25, Introduction. 2 Primitives and Define

Introduction to OCaml

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

According to Larry Wall (designer of PERL): a language by geniuses! for geniuses. Lecture 7: Haskell. Haskell 98. Haskell (cont) - Type-safe!

Functional Programming. Big Picture. Design of Programming Languages

Fundamentals and lambda calculus. Deian Stefan (adopted from my & Edward Yang s CSE242 slides)

CS 320: Concepts of Programming Languages

Programming Language Concepts: Lecture 19

Haskell 98 in short! CPSC 449 Principles of Programming Languages

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

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

SCHEME 8. 1 Introduction. 2 Primitives COMPUTER SCIENCE 61A. March 23, 2017

Programming Language Concepts: Lecture 14

Chapter 15. Functional Programming Languages

Introduction to Lambda Calculus. Lecture 5 CS 565 1/24/08

COMP 1130 Lambda Calculus. based on slides by Jeff Foster, U Maryland

Chapter 3 Linear Structures: Lists

CSE-321 Programming Languages 2011 Final

Semantic Processing (Part 2)

Note that pcall can be implemented using futures. That is, instead of. we can use

SCHEME 7. 1 Introduction. 2 Primitives COMPUTER SCIENCE 61A. October 29, 2015

Harvard School of Engineering and Applied Sciences Computer Science 152

Programming Languages

Fundamentals and lambda calculus

Functional Programming and Modeling

Transcription:

Lecture #13: Type Inference and Unification Typing In the Language ML Examples from the language ML: fun map f [] = [] map f (a :: y) = (f a) :: (map f y) fun reduce f init [] = init reduce f init (a :: y) = reduce f (f init a) y fun count [] = 0 count ( :: y) = 1 + count y fun addt [] = 0 addt ((a,,c) :: y) = (a+c) :: addt y Despite lack of explicit types here, this language is statically typed! Compiler will reject the calls map 3 [1, 2] and reduce (op +) [] [3, 4, 5]. Does this by deducing types from their uses. Last modified: Mon Apr 12 00:36:49 2010 CS164: Lecture #13 1 Last modified: Mon Apr 12 00:36:49 2010 CS164: Lecture #13 2 In simple case: Type Inference fun add [] = 0 add (a :: L) = a + add L Given a definition such as Doing Type Inference fun add [] = 0 add (a :: L) = a + add L compiler deduces that add has type int list int. Uses facts that (a) 0 is an int, (b) [] and a::l are lists (:: is cons), (c) + yields int. More interesting case: fun count [] = 0 count ( :: y) = 1 + count y ( means don t care or wildcard ). In this case, compiler deduces that count has type α list int. Here, α is a type parameter (we say that count is polymorphic). Last modified: Mon Apr 12 00:36:49 2010 CS164: Lecture #13 3 First give each named entity here an unbound type parameter as its type: add : α, a : β, L : γ. Now use the type rules of the language to give types to everything and to relate the types: 0: int, []: δ list. Since add is function and applies to int, must be that α = ι κ, and ι = δ list etc. Gives us a large set of type equations, which can be solved to give types. Solving involves pattern matching, known formally as type unification. Last modified: Mon Apr 12 00:36:49 2010 CS164: Lecture #13 4

Type Expressions For this lecture, a type expression can be A primitive type (int, bool); A type variable (today we ll use ML notation: a,, c 1, etc.); The type constructor T list, where T is a type expression; A function type D C, where D and C are type expressions. Will formulate our problems as systems of type equations between pairs of type expressions. Need to find the substitution Solving Simple Type Equations Simple example: solve a list = int list Easy: a = int. How about this: a list = list list; list = int list Also easy: a = int list; = int. On the other hand: a list = is unsolvable: lists are not functions. Also, if we require finite solutions, then a = list; = a list is unsolvable. However, our algorithm will allow infinite solutions. Last modified: Mon Apr 12 00:36:49 2010 CS164: Lecture #13 5 Last modified: Mon Apr 12 00:36:49 2010 CS164: Lecture #13 6 Rather trickier: a list= list list Most General Solutions Clearly, there are lots of solutions to this: e.g, a = int list; = int a = (int int) list; = int int etc. But prefer a most general solution that will be compatible with any possible solution. Any substitution for a must be some kind of list, and must be the type of element in a, but otherwise, no constraints Leads to solution a = list where remains a free type variable. Finding Most-General Solution by Unification To unify two type expressions is to find substitutions for all type variables that make the expressions identical. The set of substitutions is called a unifier. Represent substitutions by giving each type variable, τ, a binding to some type expression. The algorithm that follows treats type expressions as objects (so two type expressions may have identical content and still be different objects). All type variables with the same name are represented by the same object. It generalizes binding by allowing all type expressions(not just type variables) to be bound to other type expressions Initially, each type expression object is unbound. In general, our solutions look like a bunch of equations a i = T i, where the T i are type expressions and none of the a i appear in any of the T s. Last modified: Mon Apr 12 00:36:49 2010 CS164: Lecture #13 7 Last modified: Mon Apr 12 00:36:49 2010 CS164: Lecture #13 8

For any type expression, define binding(t) = Now proceed recursively: Unification Algorithm binding(t ), if T is bound to type expression T T, otherwise unify (TA,TB): TA = binding(ta); TB = binding(tb); if TA is TB: return True; # True if TA and TB are the same object if TA is a type variable: bind TA to TB; return True bind TB to TA; # Prevents infinite recursion if TB is a type variable: return True # Now check that binding TB to TA was really OK. if TA is C(TA 1,TA 2,...,TA n ) and TB is C(TB 1,...,TB n ): return unify(ta 1,TB 1 ) and unify(ta 2,TB 2 and... # where C is some type constructor else: return False Example of Unification I A = a int; B = list Dashed arrows are bindings Red items are current TA and TB So a = int list and = int. a int list Last modified: Mon Apr 12 00:36:49 2010 CS164: Lecture #13 9 Last modified: Mon Apr 12 00:36:49 2010 CS164: Lecture #13 10 Example of Unification II Example of Unification III: Simple Recursive Type A = a c list; B = a a list c So a = = c list and c is free. (to a) Introduce a new type constructor: ( h, t) pair, which is intended to model typed Lisp cons-cells (or nil). The car of such a pair has type h, and the cdr has type t. A = a; B = (, a) pair This one is very easy: a pair So a = (, a) pair; is free. Last modified: Mon Apr 12 00:36:49 2010 CS164: Lecture #13 11 Last modified: Mon Apr 12 00:36:49 2010 CS164: Lecture #13 12

Example of Unification IV: Another Recursive Type This time, consider solving A = B, C = D, A = C, where A = a; B = (, a) pair; C = c; D = ( d, ( d, c) pair) pair. We just did the first one, and the second is almost the same, so we ll just skip those steps. Try to solve Example of Unification V list= a list; a = c; c bool= (bool bool) bool We unify both sides of each equation (in any order), keeping the bindings from one unification to the next. a pair c pair d pair So a = c = ( d, a) pair; = d; d is free. a: bool : a bool c: a bool bool Unify list, a list: Unify, a Unify a, c Unify c bool, (bool bool) bool Unify c, bool bool: Unify a, bool bool: Unify a, bool Unify, bool: Unify bool, bool Unify bool, bool Last modified: Mon Apr 12 00:36:49 2010 CS164: Lecture #13 13 Last modified: Mon Apr 12 00:36:49 2010 CS164: Lecture #13 14 Some Type Rules (reprise) Construct Type Conditions Integer literal int [] a list hd (L) a L: a list tl (L) a list L: a list E 1 +E 2 int E 1 : int, E 2 : int E 1 ::E 2 a list E 1 : a, E 2 : a list E 1 = E 2 bool E 1 : a, E 2 : a E 1!=E 2 bool E 1 : a, E 2 : a if E 1 then E 2 else E 3 fi a E 1 : bool, E 2 : a, E 3 : a E 1 E 2 E 1 : a, E 2 : a def f x1...xn = E x1: a 1,..., xn: a n E: a 0, f: a 1... a n a 0. Using the Type Rules Apply these rules to a program to get a bunch of Conditions. Whenever two Conditions ascribe a type to the same expression, equate those types. Solve the resulting equations. Last modified: Mon Apr 12 00:36:49 2010 CS164: Lecture #13 15 Last modified: Mon Apr 12 00:36:49 2010 CS164: Lecture #13 16

Writing def sqr x = x*x; Aside: Currying means essentially that sqr is defined to have the value λ x. x*x. To get more than one argument, write def f x y = x + y; and f will have the value λ x. λ y. x+y It s type will be int int int (Note: is right associative). So, f 2 3 = (f 2) 3 = (λ y. 2 + y) (3) = 5 Zounds! It s the CS61A substitution model! This trick of turning multi-argument functions into one-argument functions is called currying (after Haskell Curry). Example def f x L = if L = [] then [] else if x!= hd(l) then f x (tl L) else x :: f x (tl L) fi fi Let s initially use f, x, L, etc. as the fresh type variables giving the types of identifiers. Using the rules then generates equations like this: f = a0 a1 a2 # def rule L = a3 list # = rule, [] rule L = a4 list # hd rule, x = a4 #!= rule x = a0 # call rule L = a5 list # tl rule a1 = a5 list # tl rule, call rule... Last modified: Mon Apr 12 00:36:49 2010 CS164: Lecture #13 17 Last modified: Mon Apr 12 00:36:49 2010 CS164: Lecture #13 18