CSE341: Programming Languages Lecture 11 Type Inference. Dan Grossman Spring 2016

Similar documents
CSE341: Programming Languages Lecture 9 Function-Closure Idioms. Dan Grossman Winter 2013

CSE341: Programming Languages Lecture 7 First-Class Functions. Dan Grossman Winter 2013

CSE341 Autumn 2017, Final Examination December 12, 2017

CS558 Programming Languages

CSE341 Section 3. Standard-Library Docs, First-Class Functions, & More

CSE341: Programming Languages Lecture 26 Course Victory Lap. Dan Grossman Spring 2016

CSE341: Programming Languages Lecture 9 Function-Closure Idioms. Dan Grossman Fall 2011

CSE 341 Section 5. Winter 2018

Topics Covered Thus Far CMSC 330: Organization of Programming Languages

CSE 341: Programming Languages

CSE 413 Languages & Implementation. Hal Perkins Winter 2019 Structs, Implementing Languages (credits: Dan Grossman, CSE 341)

CSE341 Spring 2016, Midterm Examination April 29, 2016

CS558 Programming Languages

CS558 Programming Languages

CS-XXX: Graduate Programming Languages. Lecture 9 Simply Typed Lambda Calculus. Dan Grossman 2012

CSE341: Programming Languages Lecture 6 Nested Patterns Exceptions Tail Recursion. Zach Tatlock Winter 2018

CMSC 330: Organization of Programming Languages

CSCI-GA Scripting Languages

Recap: Functions as first-class values

CSE341 Spring 2017, Final Examination June 8, 2017

CSE341 Spring 2016, Midterm Examination April 29, 2016

Variables and Bindings

CSE341, Spring 2013, Final Examination June 13, 2013

CSE 341: Programming Languages

CSE341: Programming Languages Lecture 4 Records, Datatypes, Case Expressions. Dan Grossman Spring 2013

CSE341: Programming Languages Lecture 2 Functions, Pairs, Lists. Dan Grossman Fall 2011

CS152: Programming Languages. Lecture 24 Bounded Polymorphism; Classless OOP. Dan Grossman Spring 2011

CSE341 Spring 2017, Final Examination June 8, 2017

CS 11 Haskell track: lecture 1

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

CSE341: Programming Languages Lecture 2 Functions, Pairs, Lists. Zach Tatlock Winter 2018

Function definitions. CSE341: Programming Languages Lecture 2 Functions, Pairs, Lists. Example, extended. Some gotchas. Zach Tatlock Winter 2018

Typed Racket: Racket with Static Types

News. CSE 130: Programming Languages. Environments & Closures. Functions are first-class values. Recap: Functions as first-class values

CSE341, Fall 2011, Lecture 26 Summary

CSE341 Autumn 2017, Midterm Examination October 30, 2017

CSE 341: Programming Languages

CSE 341, Spring 2011, Final Examination 9 June Please do not turn the page until everyone is ready.

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

Introduction to OCaml

Handout 2 August 25, 2008

CS153: Compilers Lecture 14: Type Checking

Part I: Written Problems

CS152: Programming Languages. Lecture 11 STLC Extensions and Related Topics. Dan Grossman Spring 2011

Begin at the beginning

CSE413: Programming Languages and Implementation Racket structs Implementing languages with interpreters Implementing closures

COSE212: Programming Languages. Lecture 3 Functional Programming in OCaml

CSE341: Programming Languages Lecture 25 Subtyping for OOP; Comparing/Combining Generics and Subtyping. Dan Grossman Winter 2013

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

Last major topic: Subtyping. CSE341: Programming Languages Lecture 24 Subtyping. A tiny language. Records (half like ML, half like Java)

News. Programming Languages. Recap. Recap: Environments. Functions. of functions: Closures. CSE 130 : Fall Lecture 5: Functions and Datatypes

Programming Languages

Goal. CS152: Programming Languages. Lecture 15 Parametric Polymorphism. What the Library Likes. What The Client Likes. Start simpler.

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

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

Lists. Michael P. Fourman. February 2, 2010

The Typed Racket Guide

CSE 331 Software Design and Implementation. Lecture 14 Generics 2

Programming Languages

CSE341, Fall 2011, Midterm Examination October 31, 2011

Programming Languages

CSE341 Spring 2016, Final Examination June 6, 2016

Introduction to Typed Racket. The plan: Racket Crash Course Typed Racket and PL Racket Differences with the text Some PL Racket Examples

CMSC 430 Introduction to Compilers. Fall Everything (else) you always wanted to know about OCaml (but were afraid to ask)

Tail Recursion: Factorial. Begin at the beginning. How does it execute? Tail recursion. Tail recursive factorial. Tail recursive factorial

Side note: Tail Recursion. Begin at the beginning. Side note: Tail Recursion. Base Types. Base Type: int. Base Type: int

CSE 341 : Programming Languages

CSE341: Programming Languages Lecture 17 Implementing Languages Including Closures. Dan Grossman Autumn 2018

CSE 130, Fall 2005: Final Examination

Some Advanced ML Features

Preparing for Class: Watch le Videos! What is an ML program?

CMSC 330: Organization of Programming Languages. OCaml Expressions and Functions

CSE 331 Software Design and Implementation. Lecture 14 Generics 2

Programming Languages

Programming Languages

CSCI-GA Final Exam

Harvard School of Engineering and Applied Sciences CS 152: Programming Languages

CSE341 Spring 2017, Midterm Examination April 28, 2017

Review. CS152: Programming Languages. Lecture 11 STLC Extensions and Related Topics. Let bindings (CBV) Adding Stuff. Booleans and Conditionals

The Typed Racket Guide

CSE 130, Fall 2006: Final Examination

CSE341, Fall 2011, Midterm Examination October 31, 2011

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

CSE 505, Fall 2008, Final Examination 11 December Please do not turn the page until everyone is ready.

Closures. Mooly Sagiv. Michael Clarkson, Cornell CS 3110 Data Structures and Functional Programming

Chapter 9. Subprograms

Overloading, Type Classes, and Algebraic Datatypes

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

CSci 4223 Principles of Programming Languages

Programming Languages

Lecture 13: Subtyping

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

INF 212 ANALYSIS OF PROG. LANGS FUNCTION COMPOSITION. Instructors: Crista Lopes Copyright Instructors.

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

SNU Programming Language Theory

CSE-321 Programming Languages 2010 Final

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

Announcements. CSCI 334: Principles of Programming Languages. Lecture 5: Fundamentals III & ML

The story so far. Elements of Programming Languages. Pairs in various languages. Pairs

Recap. Recap. If-then-else expressions. If-then-else expressions. If-then-else expressions. If-then-else expressions

Transcription:

CSE341: Programming Languages Lecture 11 Type Inference Dan Grossman Spring 2016

Type-checking (Static) type-checking can reject a program before it runs to prevent the possibility of some errors A feature of statically typed languages Dynamically typed languages do little (none?) such checking So might try to treat a number as a function at run-time Will study relative advantages after some Racket Racket, Ruby (and Python, Javascript, ) dynamically typed ML (and Java, C#, Scala, C, C++) is statically typed Every binding has one type, determined at compile-time 2

Implicitly typed ML is statically typed ML is implicitly typed: rarely need to write down types fun f x = (* infer val f : int -> int *) if x > 3 then 42 else x * 2 fun g x = (* report type error *) if x > 3 then true else x * 2 Statically typed: Much more like Java than Javascript! 3

Type inference Type inference problem: Give every binding/expression a type such that type-checking succeeds Fail if and only if no solution exists In principle, could be a pass before the type-checker But often implemented together Type inference can be easy, difficult, or impossible Easy: Accept all programs Easy: Reject all programs Subtle, elegant, and not magic: ML 4

Overview Will describe ML type inference via several examples General algorithm is a slightly more advanced topic Supporting nested functions also a bit more advanced Enough to help you do type inference in your head And appreciate it is not magic 5

Key steps Determine types of bindings in order (Except for mutual recursion) So you cannot use later bindings: will not type-check For each val or fun binding: Analyze definition for all necessary facts (constraints) Example: If see x > 0, then x must have type int Type error if no way for all facts to hold (over-constrained) Afterward, use type variables (e.g., 'a) for any unconstrained types Example: An unused argument can have any type (Finally, enforce the value restriction, discussed later) 6

Very simple example After this example, will go much more step-by-step Like the automated algorithm does val x = 42 (* val x : int *) fun f (y, z, w) = if y (* y must be bool *) then z + x (* z must be int *) else 0 (* both branches have same type *) (* f must return an int f must take a bool * int * ANYTHING so val f : bool * int * 'a -> int *) 7

Relation to Polymorphism Central feature of ML type inference: it can infer types with type variables Great for code reuse and understanding functions But remember there are two orthogonal concepts Languages can have type inference without type variables Languages can have type variables without type inference 8

Key Idea Collect all the facts needed for type-checking These facts constrain the type of the function See code and/or reading notes for: Two examples without type variables And one example that does not type-check Then examples for polymorphic functions Nothing changes, just under-constrained: some types can be anything but may still need to be the same as other types 9

Material after here is optional, but is an important part of the full story 10

Two more topics ML type-inference story so far is too lenient Value restriction limits where polymorphic types can occur See why and then what ML is in a sweet spot Type inference more difficult without polymorphism Type inference more difficult with subtyping Important to finish the story but these topics are: A bit more advanced A bit less elegant Will not be on the exam 11

The Problem As presented so far, the ML type system is unsound! Allows putting a value of type t1 (e.g., int) where we expect a value of type t2 (e.g., string) A combination of polymorphism and mutation is to blame: val r = ref NONE (* val r : 'a option ref *) val _ = r := SOME "hi" val i = 1 + valof (!r) Assignment type-checks because (infix) := has type 'a ref * 'a -> unit, so instantiate with string Dereference type-checks because! has type 'a ref -> 'a, so instantiate with int 12

What to do To restore soundness, need a stricter type system that rejects at least one of these three lines val r = ref NONE (* val r : 'a option ref *) val _ = r := SOME "hi" val i = 1 + valof (!r) And cannot make special rules for reference types because type-checker cannot know the definition of all type synonyms Due to module system type 'a foo = 'a ref val f = ref (* val f : 'a -> 'a foo *) val r = f NONE 13

The fix val r = ref NONE (* val r :?.X1 option ref *) val _ = r := SOME "hi" val i = 1 + valof (!r) Value restriction: a variable-binding can have a polymorphic type only if the expression is a variable or value Function calls like ref NONE are neither Else get a warning and unconstrained types are filled in with dummy types (basically unusable) Not obvious this suffices to make type system sound, but it does 14

The downside As we saw previously, the value restriction can cause problems when it is unnecessary because we are not using mutation val pairwithone = List.map (fn x => (x,1)) (* does not get type 'a list -> ('a*int) list *) The type-checker does not know List.map is not making a mutable reference Saw workarounds in previous segment on partial application Common one: wrap in a function binding fun pairwithone xs = List.map (fn x => (x,1)) xs (* 'a list -> ('a*int) list *) 15

A local optimum Despite the value restriction, ML type inference is elegant and fairly easy to understand More difficult without polymorpism What type should length-of-list have? More difficult with subtyping Suppose pairs are supertypes of wider tuples Then val (y,z) = x constrains x to have at least two fields, not exactly two fields Depending on details, languages can support this, but types often more difficult to infer and understand Will study subtyping later, but not with type inference 16