Kathleen Fisher cs242 Reading: “Concepts in Programming Languages”, Chapter 6.

Slides:



Advertisements
Similar presentations
Modern Programming Languages, 2nd ed.
Advertisements

Modern Programming Languages, 2nd ed.
Type Checking, Inference, & Elaboration CS153: Compilers Greg Morrisett.
CSE341: Programming Languages Lecture 2 Functions, Pairs, Lists Dan Grossman Winter 2013.
Cs776 (Prasad)L4Poly1 Polymorphic Type System. cs776 (Prasad)L4Poly2 Goals Allow expression of “for all types T” fun I x = x I : ’a -> ’a Allow expression.
Semantic Analysis Chapter 6. Two Flavors  Static (done during compile time) –C –Ada  Dynamic (done during run time) –LISP –Smalltalk  Optimization.
Programming Languages and Paradigms
Getting started with ML ML is a functional programming language. ML is statically typed: The types of literals, values, expressions and functions in a.
Overview of Previous Lesson(s) Over View  Front end analyzes a source program and creates an intermediate representation from which the back end generates.
Names and Bindings.
ML: a quasi-functional language with strong typing Conventional syntax: - val x = 5; (*user input *) val x = 5: int (*system response*) - fun len lis =
Kathleen Fisher cs242 Reading: “Concepts in Programming Languages”, Chapter 6.
Chapter 7:: Data Types Programming Language Pragmatics
INF 212 ANALYSIS OF PROG. LANGS Type Systems Instructors: Crista Lopes Copyright © Instructors.
Various languages….  Could affect performance  Could affect reliability  Could affect language choice.
Type Checking.
Compiler Construction
Catriel Beeri Pls/Winter 2004/5 last 55 Two comments on let polymorphism I. What is the (time, space) complexity of type reconstruction? In practice –
Copyright © 2006 The McGraw-Hill Companies, Inc. Programming Languages 2nd edition Tucker and Noonan Chapter 5 Types Types are the leaven of computer programming;
CS 330 Programming Languages 10 / 16 / 2008 Instructor: Michael Eckmann.
ML: a quasi-functional language with strong typing Conventional syntax: - val x = 5; (*user input *) val x = 5: int (*system response*) - fun len lis =
Catriel Beeri Pls/Winter 2004/5 type reconstruction 1 Type Reconstruction & Parametric Polymorphism  Introduction  Unification and type reconstruction.
ISBN Chapter 9 Subprograms. Copyright © 2006 Addison-Wesley. All rights reserved.1-2 Introduction Two fundamental abstraction facilities.
CS 330 Programming Languages 10 / 24 / 2006 Instructor: Michael Eckmann.
Approaches to Typing Programming Languages Robert Dewar.
1 Type Type system for a programming language = –set of types AND – rules that specify how a typed program is allowed to behave Why? –to generate better.
Type Inference: CIS Seminar, 11/3/2009 Type inference: Inside the Type Checker. A presentation by: Daniel Tuck.
1 Chapter 5: Names, Bindings and Scopes Lionel Williams Jr. and Victoria Yan CSci 210, Advanced Software Paradigms September 26, 2010.
Chapter TwelveModern Programming Languages1 Memory Locations For Variables.
Imperative Programming
Types and Type Inference Mooly Sagiv Slides by Kathleen Fisher and John Mitchell Reading: “Concepts in Programming Languages”, Revised Chapter 6 - handout.
INF Polymorphism and Type Inference Fatemeh Kazemeyni Department of Informatics – University of Oslo Based on John C. Mitchell’s.
Types for Programs and Proofs Lecture 1. What are types? int, float, char, …, arrays types of procedures, functions, references, records, objects,...
5-1 Chapter 5: Names, Bindings, Type Checking, and Scopes Variables The Concept of Binding Type Checking Strong Typing Type Compatibility Scope and Lifetime.
March 12, ICE 1341 – Programming Languages (Lecture #6) In-Young Ko Programming Languages (ICE 1341) Lecture #6 Programming Languages (ICE 1341)
Types John Mitchell CS 242. Type A type is a collection of computable values that share some structural property. uExamples Integers Strings int  bool.
CSE 425: Data Types I Data and Data Types Data may be more abstract than their representation –E.g., integer (unbounded) vs. 64-bit int (bounded) A language.
1 Records Record aggregate of data elements –Possibly heterogeneous –Elements/slots are identified by names –Elements in same fixed order in all records.
Arithmetic Expressions
Types John Mitchell CS 242 Reading: Chapter 6. Announcements uHomework 1 due today Turn in at the end of class, OR Turn in by 5PM to the homework drop.
Polymorphism Programming Language Design and Implementation (4th Edition) by T. Pratt and M. Zelkowitz Prentice Hall, 2001 Section 7.3.
Types(1). Lecture 52 Type(1)  A type is a collection of values and operations on those values. Integer type  values..., -2, -1, 0, 1, 2,...  operations.
12/9/20151 Programming Languages and Compilers (CS 421) Elsa L Gunter 2112 SC, UIUC Based in part on slides by Mattox.
Concepts of programming languages Chapter 5 Names, Bindings, and Scopes Lec. 12 Lecturer: Dr. Emad Nabil 1-1.
Types and Programming Languages Lecture 11 Simon Gay Department of Computing Science University of Glasgow 2006/07.
How to execute Program structure Variables name, keywords, binding, scope, lifetime Data types – type system – primitives, strings, arrays, hashes – pointers/references.
Semantic Analysis II Type Checking EECS 483 – Lecture 12 University of Michigan Wednesday, October 18, 2006.
1 Structure of Compilers Lexical Analyzer (scanner) Modified Source Program Parser Tokens Semantic Analysis Syntactic Structure Optimizer Code Generator.
C H A P T E R T H R E E Type Systems and Semantics Programming Languages – Principles and Paradigms by Allen Tucker, Robert Noonan.
CS 330 Programming Languages 10 / 23 / 2007 Instructor: Michael Eckmann.
Names, Scope, and Bindings Programming Languages and Paradigms.
Types John Mitchell CS 242. Type A type is a collection of computable values that share some structural property. uExamples Integers Strings int  bool.
Chapter 1: Preliminaries Lecture # 2. Chapter 1: Preliminaries Reasons for Studying Concepts of Programming Languages Programming Domains Language Evaluation.
COMP 412, FALL Type Systems C OMP 412 Rice University Houston, Texas Fall 2000 Copyright 2000, Robert Cartwright, all rights reserved. Students.
Arvind Computer Science and Artificial Intelligence Laboratory M.I.T. L05-1 September 21, 2006http:// Types and Simple Type.
Dr. M. Al-Mulhem Introduction 1 Chapter 6 Type Systems.
Heath Carroll Bill Hanczaryk Rich Porter.  A Theory of Type Polymorphism in Programming ◦ Robin Milner (1977)  Milner credited with introducing the.
Object Lifetime and Pointers
Data Types In Text: Chapter 6.
Type Checking and Type Inference
CSE341: Programming Languages Lecture 11 Type Inference
Principles of programming languages 12: Functional programming
ML: a quasi-functional language with strong typing
Concepts of programming languages
CSCI 3370: Principles of Programming Languages Chapter 9 Subprograms
CS 242 Types John Mitchell.
CS 242 Types John Mitchell Reading: Chapter 6.
CSE341: Programming Languages Lecture 11 Type Inference
CSE341: Programming Languages Lecture 11 Type Inference
Presentation transcript:

Kathleen Fisher cs242 Reading: “Concepts in Programming Languages”, Chapter 6

 We are looking for homework graders.  If you are interested, send mail to  Need to be available approximately 5-9pm on Thursdays.  You’ll be paid Stanford’s hourly rate.  We’ll provide food “of your choice.”  Previous graders have really enjoyed it.  Great way to really learn the material.

 General discussion of types  What is a type?  Compile-time vs run-time checking  Conservative program analysis  Type inference  Good example of static analysis algorithm  Will study algorithm and examples  Polymorphism  Uniform vs non-uniform impl of polymorphism  Polymorphism vs overloading

 Thoughts to keep in mind  What features are convenient for programmer?  What other features do they prevent?  What are design tradeoffs?  Easy to write but harder to read?  Easy to write but poorer error messages?  What are the implementation costs? Architect Compiler, Runtime environ- ment Programmer Tester Diagnostic Tools Programming Language

A type is a collection of computable values that share some structural property.  Examples Integer String Int  Bool (Int  Int)  Bool  Non-examples  3, True, \x->x  Even integers  f:Int  Int | if x>3 then f(x) > x *(x+1)  Distinction between sets that are types and sets that are not types is language dependent.

 Program organization and documentation  Separate types for separate concepts  Represent concepts from problem domain  Indicate intended use of declared identifiers  Types can be checked, unlike program comments  Identify and prevent errors  Compile-time or run-time checking can prevent meaningless computations such as 3 + true – “Bill”  Support optimization  Example: short integers require fewer bits  Access record component by known offset

 JavaScript and Lisp use run-time type checking f(x) Make sure f is a function before calling f.  ML and Haskell use compile-time type checking f(x) Must have f : A  B and x : A  Basic tradeoff  Both kinds of checking prevent type errors.  Run-time checking slows down execution.  Compile-time checking restricts program flexibility. JavaScript array: elements can have different types Haskell list: all elements must have same type  Which gives better programmer diagnostics?

 In JavaScript, we can write a function like function f(x) { return x < 10 ? x : x(); } Some uses will produce type error, some will not.  Static typing always conservative if (big-hairy-boolean-expression) then f(5); else f(15); Cannot decide at compile time if run-time error will occur!

 Not safe: BCPL family, including C and C++  Casts, pointer arithmetic  Almost safe: Algol family, Pascal, Ada.  Dangling pointers.  Allocate a pointer p to an integer, deallocate the memory referenced by p, then later use the value pointed to by p.  No language with explicit deallocation of memory is fully type-safe.  Safe: Lisp, ML, Haskell, Smalltalk, JavaScript, Java  Dynamically typed: Lisp, Smalltalk, JavaScript  Statically typed: ML, Haskell, Java

 Standard type checking: int f(int x) { return x+1; }; int g(int y) { return f(y+1)*2; };  Examine body of each function. Use declared types of identifiers to check agreement.  Type inference: int f(int x) { return x+1; }; int g(int y) { return f(y+1)*2;};  Examine code without type information. Infer the most general types that could have been declared. ML and Haskell are designed to make type inference feasible.

 Types and type checking  Improved steadily since Algol 60  Eliminated sources of unsoundness.  Become substantially more expressive.  Important for modularity, reliability and compilation  Type inference  Reduces syntactic overhead of expressive types  Guaranteed to produce most general type.  Widely regarded as important language innovation  Illustrative example of a flow-insensitive static analysis algorithm

 Original type inference algorithm was invented by Haskell Curry and Robert Feys for the simply typed lambda calculus in  In 1969, Hindley extended the algorithm and proved it always produced the most general type.  In 1978, Milner independently developed equivalent algorithm, called algorithm W, during his work designing ML.  In 1982, Damas proved the algorithm was complete.  Already used in many languages: ML, Ada, C# 3.0, F#, Haskell, Visual Basic.Net 9.0, and soon in: Fortress, Perl 6, C++0x  We’ll use ML to explain the algorithm because it is the original language to use the feature and is the simplest place to start.

 Example - fun f(x) = 2 + x; > val it = fn : int  int  What is the type of f?  + has two types: int  int  int, real  real  real  2 has only one type: int  This implies + : int  int  int  From context, we need x:int  Therefore f(x:int) = 2+x has type int  int Overloaded + is unusual. Most ML symbols have unique type. In many cases, unique type may be polymorphic.

 Example -fun f(x) = 2+x; >val it = fn:int  int  What is the type of +2 Assign types to leaves : t int  int  int real  real  real : int Propagate to internal nodes and generate constraints int (t = int) int  int t  int Solve by substitution = int  int Graph for \x ->((plus 2) x)

 Apply function f to argument x: f(x)  Because f is being applied, its type (s in figure) must be a function type: domain  range.  Domain of f must be type of argument x (d in figure).  Range of f must be result type of expression (r in figure).  Solving, we get: s = d  fx : s: d : r (s = domain  range) (domain = d) (range = r)

 Function expression: \x -> e  Type of lambda abstraction (s in figure) must be a function type: domain  range.  Domain is type of abstracted variable x (d in figure).  Range is type of function body e (r in figure).  Solving, we get : s = d  r. x e : d : r : s (s = domain  range) (domain = d) (range = r)

 Example -fun f(g) = g(2); >val it = fn : (int  t)  t  What is the type of f? Assign types to leaves : int : s Propagate to internal nodes and generate constraints t (s = int  t) stst g Graph for \g  (g 2) Solve by substitution = (int  t)  t

 Function -fun f(g) = g(2); >val it = fn:(int  t)  t  Possible applications -fun isEven(x) =...; >val it = fn:int  bool -f(isEven); >val it = true : bool -fun add(x) = 2+x; >val it = fn:int  int -f(add); >val it = 4 : int

 Function -fun f(g) = g(2); >val it = fn:(int  t)  t  Incorrect use -fun not(x) = if x then false else true; >val it = fn : bool  bool -f(not); Error: operator and operand don't agree operator domain: int -> 'Z operand: bool -> bool Type error: cannot make bool  bool = int  t

 Function Definition -fun f(g,x) = g(g(x)); >val it = fn:(t  t)*t  t  Type Inference Solve by substitution = (v  v)*v  v Assign types to leaves : t : s Propagate to internal nodes and generate constraints v (s = u  v) s*t  v u (s = t  g g Graph for  g,x . g(g x)

 Datatype with type variable - datatype ‘a list = nil | cons of ‘a *(‘a list) > nil : ‘a list > cons : ‘a *(‘a list)  ‘a list  Polymorphic function - fun length nil = 0 | length (cons(x,rest)) = 1 + length(rest) > length : ‘a list  int  Type inference  Infer separate type for each clause  Combine by making two types equal (if necessary) ’a is syntax for “type variable a”

 length(cons(x,rest)) = 1 + length(rest) rest : t : ‘a * ‘a list  ‘a list : s : u : int : s * u : r (t = u  r) : int  int : w (int  int = r  w) (‘a* ‘a list  ‘a list = s * u  v) : v : p (p = v  w, p = t)

 length(cons(x,rest)) = 1 + length(rest) p = t p = v  w int  int = r  w t = u  r ‘a* ‘a list  ‘a list = s * u  v : r : w : u rest : t : ‘a * ‘a list  ‘a list : s : int : s * u : int  int : v : p Collected Constraints:

 length(cons(x,rest)) = 1 + length(rest) p = t p = v  w int  int = r  w t = u  r ‘a = s ‘a list = u ‘a list = v : r : w : u rest : t : ‘a * ‘a list  ‘a list : s : int : s * u : int  int : v : p Collected Constraints:

 length(cons(x,rest)) = 1 + length(rest) p = t p = ‘a list  w int  int = r  w t = ‘a list  r : r : w : u rest : t : ‘a * ‘a list  ‘a list : s : int : s * u : int  int : v : p Collected Constraints:

 length(cons(x,rest)) = 1 + length(rest) p = t p = ‘a list  int t = ‘a list  int : r : w : u rest : t : ‘a * ‘a list  ‘a list : s : int : s * u : int  int : v : p Collected Constraints: Result: p = ‘a list  int

 Function with multiple clauses - fun append(nil,l) = l | append(x::xs,l) = x :: append(xs,l) > append: ‘a list * ‘a list  int  Infer type of each branch  First branch: append :‘a list *‘b  ‘b  First branch: append :‘a list *‘b  ‘a list  Combine by equating types of two branches: append :‘a list *‘a list  ‘a list

 Type inference is guaranteed to produce the most general type: - fun map(f,nil) = nil | map(f, x::xs) = f(x) :: (map(f,xs)) > map:('a  'b) * 'a list  'b list  Function has many other, less general types:  map:('a  int) * 'a list  int list  map:(bool  'b) * bool list  'b list  map:(char  int) * char list  int list  Less general types are all instances of most general type, also called the principal type.

 When the Hindley/Milner type inference algorithm was developed, its complexity was unknown.  In 1989, Kanellakis, Mairson, and Mitchell proved that the problem was exponential- time complete.  Linear in practice though…

 Consider this function… fun reverse (nil) = nil | reverse (x::xs) = reverse(xs);  … and its most general type: reverse : ‘a list  ‘b list  What does this type mean? Reversing a list does not change its type, so there must be an error in the definition of reverse ! See Koenig paper on “Reading” page of CS242 site

 Type inference computes the types of expressions  Does not require type declarations for variables  Finds the most general type by solving constraints  Leads to polymorphism  Sometimes better error detection than type checking  Type may indicate a programming error even if no type error.  Some costs  More difficult to identify program line that causes error  ML requires different syntax for integer 3, real 3.0.  Natural implementation requires uniform representation sizes.  Complications regarding assignment took years to work out.  Idea can be applied to other program properties  Discover properties of program using same kind of analysis

 Haskell also uses Hindley Milner type inference.  Haskell uses type classes to support user-defined overloading, so the inference algorithm is more complicated.  ML restricts the language to ensure that no annotations are required, ever.  Haskell provides various features like polymorphic recursion for which types cannot be inferred and so the user must provide annotations.

 ML polymorphic function  Declarations require no type information.  Type inference uses type variables to type expressions.  Type inference substitutes for variables as needed to instantiate polymorphic code.  C++ function template  Programmer must declare the argument and result types of functions.  Programmers must use explicit type parameters to express polymorphism.  Function application: type checker does instantiation. ML also has module system with explicit type parameters

 ML -fun swap(x,y) = let val z = !x in x := !y; y := z end; val swap = fn : 'a ref * 'a ref -> unit  C++ template void swap(T& x, T& y){ T tmp = x; x=y; y=tmp; } Declarations look similar, but compiled very differently

 ML  Swap is compiled into one function  Typechecker determines how function can be used  C++  Swap is compiled into linkable format  Linker duplicates code for each type of use  Why the difference?  ML ref cell is passed by pointer. The local x is a pointer to value on heap, so its size is constant.  C++ arguments passed by reference (pointer), but local x is on the stack, so its size depends on the type.

 C++ polymorphic sort function template void sort( int count, T * A[count ] ) { for (int i=0; i<count-1; i++) for (int j=i+1; j<count-1; j++) if (A[j] < A[i]) swap(A[i],A[j]); }  What parts of code depend on the type?  Indexing into array  Meaning and implementation of <

 Parametric polymorphism  Single algorithm may be given many types  Type variable may be replaced by any type  if f:t  t then f:int  int, f:bool  bool,...  Overloading  A single symbol may refer to more than one algorithm  Each algorithm may have different type  Choice of algorithm determined by type context  Types of symbol may be arbitrarily different  + has types int*int  int, real*real  real, no others

 Some predefined operators are overloaded  User-defined functions must have unique type - fun plus(x,y) = x+y; This is compiled to int or real function, not both  Why is a unique type needed?  Need to compile code, so need to know which +  Efficiency of type inference  Aside: General overloading is NP-complete Two types, true and false Overloaded functions and : {true*true  true, false*true  false, …}

 Types are important in modern languages  Program organization and documentation  Prevent program errors  Provide important information to compiler  Type inference  Determine best type for an expression, based on known information about symbols in the expression  Polymorphism  Single algorithm (function) can have many types  Overloading  One symbol with multiple meanings, resolved at compile time