Prof. Hilfinger CS164 Lecture 191 Type Checking Lecture 19 (from notes by G. Necula)

Slides:



Advertisements
Similar presentations
Optional Static Typing Guido van Rossum (with Paul Prescod, Greg Stein, and the types-SIG)
Advertisements

CPSC 388 – Compiler Design and Construction
Type Checking, Inference, & Elaboration CS153: Compilers Greg Morrisett.
Semantics Static semantics Dynamic semantics attribute grammars
- Vasvi Kakkad.  Formal -  Tool for mathematical analysis of language  Method for precisely designing language  Well formed model for describing and.
1 Mooly Sagiv and Greta Yorsh School of Computer Science Tel-Aviv University Modern Compiler Design.
CS7100 (Prasad)L16-7AG1 Attribute Grammars Attribute Grammar is a Framework for specifying semantics and enables Modular specification.
INF 212 ANALYSIS OF PROG. LANGS Type Systems Instructors: Crista Lopes Copyright © Instructors.
1 Semantic Description of Programming languages. 2 Static versus Dynamic Semantics n Static Semantics represents legal forms of programs that cannot be.
CS 355 – Programming Languages
Compiler Construction
1 Chapter 4 Language Fundamentals. 2 Identifiers Program parts such as packages, classes, and class members have names, which are formally known as identifiers.
Context-Free Grammars Lecture 7
CS 330 Programming Languages 09 / 18 / 2007 Instructor: Michael Eckmann.
4/25/08Prof. Hilfinger CS164 Lecture 371 Global Optimization Lecture 37 (From notes by R. Bodik & G. Necula)
3/3/2008Prof. Hilfinger CS164 Lecture 171 Type Checking Lecture 17 (P. N. Hilfinger and G. Necula)
Type Checking in Cool Alex Aiken (Modified by Mooly Sagiv)
Prof. Fateman CS 164 Lecture 131 Types Lecture 13.
CS 330 Programming Languages 09 / 16 / 2008 Instructor: Michael Eckmann.
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.
Describing Syntax and Semantics
Cs164 Prof. Bodik, Fall Symbol Tables and Static Checks Lecture 14.
Cormac Flanagan University of California, Santa Cruz Hybrid Type Checking.
CSE341: Programming Languages Lecture 11 Type Inference Dan Grossman Winter 2013.
Types in programming languages What are types, and why do we need them? Types in programming languages1.
CS784 (Prasad)L167AG1 Attribute Grammars Attribute Grammar is a Framework for specifying semantics and enables Modular specification.
Prof. Necula CS 164 Lectures Semantic Analysis Typechecking in COOL Lecture 7.
1 Introduction to Parsing Lecture 5. 2 Outline Regular languages revisited Parser overview Context-free grammars (CFG’s) Derivations.
COP4020 Programming Languages
CSC3315 (Spring 2009)1 CSC 3315 Programming Languages Hamid Harroud School of Science and Engineering, Akhawayn University
Adapted from Prof. Necula UCB CS 1641 Overview of COOL ICOM 4029 Lecture 2 ICOM 4029 Fall 2008.
Chapter Twenty-ThreeModern Programming Languages1 Formal Semantics.
Type Systems CS Definitions Program analysis Discovering facts about programs. Dynamic analysis Program analysis by using program executions.
ISBN Chapter 3 Describing Semantics -Attribute Grammars -Dynamic Semantics.
CS 363 Comparative Programming Languages Semantics.
Formal Semantics Chapter Twenty-ThreeModern Programming Languages, 2nd ed.1.
Chapter 12 Support for Object oriented Programming.
Looping and Counting Lecture 3 Hartmut Kaiser
© Kenneth C. Louden, Chapter 11 - Functional Programming, Part III: Theory Programming Languages: Principles and Practice, 2nd Ed. Kenneth C. Louden.
Introduction to Parsing
Arvind Computer Science and Artificial Intelligence Laboratory M.I.T. L06-1 September 26, 2006http:// Type Inference September.
ISBN Chapter 3 Describing Semantics.
Chapter 3 Part II Describing Syntax and Semantics.
Programming Languages and Design Lecture 3 Semantic Specifications of Programming Languages Instructor: Li Ma Department of Computer Science Texas Southern.
Semantics In Text: Chapter 3.
CS536 Semantic Analysis Introduction with Emphasis on Name Analysis 1.
12/9/20151 Programming Languages and Compilers (CS 421) Elsa L Gunter 2112 SC, UIUC Based in part on slides by Mattox.
1 / 48 Formal a Language Theory and Describing Semantics Principles of Programming Languages 4.
CS536 Types 1. Roadmap Back from our LR Parsing Detour Name analysis – Static v dynamic – Scope Today – Type checking 2 Scanner Parser Tokens Semantic.
Types and Programming Languages Lecture 11 Simon Gay Department of Computing Science University of Glasgow 2006/07.
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.
CS412/413 Introduction to Compilers Radu Rugina Lecture 13 : Static Semantics 18 Feb 02.
1 Introduction to Parsing. 2 Outline l Regular languages revisited l Parser overview Context-free grammars (CFG ’ s) l Derivations.
Soundness of Types Ensuring that a type system is not broken.
CMSC 330: Organization of Programming Languages Operational Semantics.
CS7120 (Prasad)L13-1-Lambda-Opt1 Typed Lambda Calculus Adapted from Lectures by Profs Aiken and Necula of Univ. of California at Berkeley.
Types and Programming Languages Lecture 3 Simon Gay Department of Computing Science University of Glasgow 2006/07.
Prof. Necula CS 164 Lecture 171 Operational Semantics of Cool ICOM 4029 Lecture 10.
Arvind Computer Science and Artificial Intelligence Laboratory M.I.T. L05-1 September 21, 2006http:// Types and Simple Type.
CSE 332: C++ Exceptions Motivation for C++ Exceptions Void Number:: operator/= (const double denom) { if (denom == 0.0) { // what to do here? } m_value.
LECTURE 10 Semantic Analysis. REVIEW So far, we’ve covered the following: Compilation methods: compilation vs. interpretation. The overall compilation.
Lecture 9 Symbol Table and Attributed Grammars
Type Checking and Type Inference
Introduction to Parsing
Semantic Analysis with Emphasis on Name Analysis
Corky Cartwright January 18, 2017
Compiler Design 18. Object Oriented Semantic Analysis (Symbol Tables, Type Checking) Kanat Bolazar March 30, 2010.
Lecture 15 (Notes by P. N. Hilfinger and R. Bodik)
ICOM 4029 Fall 2003 Lecture 2 (Adapted from Prof. Necula UCB CS 164)
Presentation transcript:

Prof. Hilfinger CS164 Lecture 191 Type Checking Lecture 19 (from notes by G. Necula)

Prof. Hilfinger CS164 Lecture 192 Administrivia Test run this evening around midnight Test is next Wednesday at 6 in 306 Soda Please let me know soon if you need an alternative time for the test. Please use bug-submit to submit problems/questions Review session Sunday in 310 Soda 4-6PM

Prof. Hilfinger CS164 Lecture 193 Types What is a type? –The notion varies from language to language Consensus –A set of values –A set of operations on those values Classes are one instantiation of the modern notion of type

Prof. Hilfinger CS164 Lecture 194 Why Do We Need Type Systems? Consider the assembly language fragment addi $r1, $r2, $r3 What are the types of $r1, $r2, $r3?

Prof. Hilfinger CS164 Lecture 195 Types and Operations Most operations are legal only for values of some types –It doesn’t make sense to add a function pointer and an integer in C –It does make sense to add two integers –But both have the same assembly language implementation!

Prof. Hilfinger CS164 Lecture 196 Type Systems A language’s type system specifies which operations are valid for which types The goal of type checking is to ensure that operations are used with the correct types –Enforces intended interpretation of values, because nothing else will! Type systems provide a concise formalization of the semantic checking rules

Prof. Hilfinger CS164 Lecture 197 What Can Types do For Us? Can detect certain kinds of errors Memory errors: –Reading from an invalid pointer, etc. Violation of abstraction boundaries: class FileSystem { open(x : String) : File { … } … } class Client { f(fs : FileSystem) { File fdesc <- fs.open(“foo”) … } -- f cannot see inside fdesc ! }

Prof. Hilfinger CS164 Lecture 198 Type Checking Overview Three kinds of languages: –Statically typed: All or almost all checking of types is done as part of compilation (C, Java, Cool) –Dynamically typed: Almost all checking of types is done as part of program execution (Scheme) –Untyped: No type checking (machine code)

Prof. Hilfinger CS164 Lecture 199 The Type Wars Competing views on static vs. dynamic typing Static typing proponents say: –Static checking catches many programming errors at compile time –Avoids overhead of runtime type checks Dynamic typing proponents say: –Static type systems are restrictive –Rapid prototyping easier in a dynamic type system

Prof. Hilfinger CS164 Lecture 1910 The Type Wars (Cont.) In practice, most code is written in statically typed languages with an “escape” mechanism –Unsafe casts in C, native methods in Java, unsafe modules in Modula-3

Prof. Hilfinger CS164 Lecture 1911 Type Inference Type Checking is the process of checking that the program obeys the type system Often involves inferring types for parts of the program –Some people call the process type inference when inference is necessary

Prof. Hilfinger CS164 Lecture 1912 Rules of Inference We have seen two examples of formal notation specifying parts of a compiler –Regular expressions (for the lexer) –Context-free grammars (for the parser) The appropriate formalism for type checking is logical rules of inference

Prof. Hilfinger CS164 Lecture 1913 Why Rules of Inference? Inference rules have the form If Hypothesis is true, then Conclusion is true Type checking computes via reasoning If E 1 and E 2 have certain types, then E 3 has a certain type Rules of inference are a compact notation for “If-Then” statements

Prof. Hilfinger CS164 Lecture 1914 From English to an Inference Rule The notation is easy to read (with practice) Start with a simplified system and gradually add features Building blocks –Symbol  is “and” –Symbol  is “if-then” –x:T is “x has type T”

Prof. Hilfinger CS164 Lecture 1915 From English to an Inference Rule (2) If e 1 has type Int and e 2 has type Int, then e 1 + e 2 has type Int (e 1 has type Int  e 2 has type Int)  e 1 + e 2 has type Int (e 1 : Int  e 2 : Int)  e 1 + e 2 : Int

Prof. Hilfinger CS164 Lecture 1916 From English to an Inference Rule (3) The statement (e 1 : Int  e 2 : Int)  e 1 + e 2 : Int is a special case of ( Hypothesis 1 ...  Hypothesis n )  Conclusion This is an inference rule

Prof. Hilfinger CS164 Lecture 1917 Notation for Inference Rules By tradition inference rules are written Type rules have hypotheses and conclusions of the form:  e : T  means “we can prove that...”  Hypothesis 1 …  Hypothesis n |- Conclusion

Prof. Hilfinger CS164 Lecture 1918 Two Rules |- i : Int [Int] |- e 1 : Int |- e 2 : Int |- e 1 + e 2 : Int [Add] (i is an integer)

Prof. Hilfinger CS164 Lecture 1919 Two Rules (Cont.) These rules give templates describing how to type integers and + expressions By filling in the templates, we can produce complete typings for expressions We can fill the template with ANY expression! Logic nerds: Why is the following correct? |- true : Int |- false : Int |- true + false : Int

Prof. Hilfinger CS164 Lecture 1920 Example: |- 1 : Int|- 2 : Int | : Int

Prof. Hilfinger CS164 Lecture 1921 Soundness A type system is sound if –Whenever |- e : T –Then e evaluates to a value of type T We only want sound rules –But some sound rules are better than others; here’s one that’s not very useful: |- i : Any (i is an integer)

Prof. Hilfinger CS164 Lecture 1922 Type Checking Proofs Type checking proves facts e : T –One type rule is used for each kind of expression In the type rule used for a node e: –The hypotheses are the proofs of types of e’s subexpressions –The conclusion is the proof of type of e

Prof. Hilfinger CS164 Lecture 1923 Rules for Constants |- False : Bool [Bool] |- s : String [String] (s is a string constant)

Prof. Hilfinger CS164 Lecture 1924 Object Creation Example |- T() : T [New] (T denotes a class with parameterless constructor)

Prof. Hilfinger CS164 Lecture 1925 Two More Rules (Not From Pyth) |- e : Bool |- not e : Bool [Not] |- e 1 : Bool |- e 2 : T |- while e 1 loop e 2 pool : Object [Loop]

Prof. Hilfinger CS164 Lecture 1926 Typing: Example Typing for while not false loop * 3 pool while loop pool not false + 1 * 2 3 : Bool : Int : Object

Prof. Hilfinger CS164 Lecture 1927 Typing Derivations The typing reasoning can be expressed as a tree: |- false : Bool |- 1 : Int |- 2 : Int |- 3 : Int |- 2 * 3 : Int |- not false : Bool| * 3: Int |- while not false loop * 3 : Object The root of the tree is the whole expression Each node is an instance of a typing rule Leaves are the rules with no hypotheses

Prof. Hilfinger CS164 Lecture 1928 A Problem What is the type of a variable reference? This rules does not have enough information to give a type. –We need a hypothesis of the form “we are in the scope of a declaration of x with type T”) |- x : ? [Var] (x is an identifier)

Prof. Hilfinger CS164 Lecture 1929 A Solution: Put more information in the rules! A type environment gives types for free variables –A type environment is a mapping from Identifiers to Types –A variable is free in an expression if: The expression contains an occurrence of the variable that refers to a declaration outside the expression –E.g. in the expression “x”, the variable “x” is free –E.g. in “(lambda (x) (+ x y))” only “y” is free –E.g. in “(+ x (lambda (x) (+ x y))” both “x” and “y” are free

Prof. Hilfinger CS164 Lecture 1930 Type Environments Let O be a function from Identifiers to Types The sentence O |- e : T is read: Under the assumption that variables in the current scope have the types given by O, it is provable that the expression e has the type T

Prof. Hilfinger CS164 Lecture 1931 Modified Rules The type environment is added to the earlier rules: O |- i : Int [Int] O |- e 1 : Int O |- e 2 : Int O |- e 1 + e 2 : Int [Add] (i is an integer)

Prof. Hilfinger CS164 Lecture 1932 New Rules And we can write new rules: O |- x : T [Var](if O(x) = T)

Prof. Hilfinger CS164 Lecture 1933 Lambda (from Python) O[Any/x] means “O modified to map x to Any and behaving as O on all other arguments”: O[Any/x] (x) = Any O[Any/x] (y) = O(y), x and y distinct O[Any/x] |- e 1 : T 1 O |- lambda x: e 1 : Any ->T 1 [Lambda]

Prof. Hilfinger CS164 Lecture 1934 Let (From the COOL Language) Let statement creates a variable x with given type T 0 that is then defined throughout e 1 O[T 0 /x] |- e 1 : T 1 O |- let x : T 0 in e 1 : T 1 [Let-No-Init]

Prof. Hilfinger CS164 Lecture 1935 Let. Example. Consider the Cool expression let x : T 0 in (let y : T 1 in E x, y ) + (let x : T 2 in F x, y ) (where E x, y and F x, y are some Cool expression that contain occurrences of “x” and “y”) Scope –of “y” is E x, y –of outer “x” is E x, y –of inner “x” is F x, y This is captured precisely in the typing rule.

Prof. Hilfinger CS164 Lecture 1936 Let Example. let x : int in let y : Str in + let x : Str in E x, y len( ) O |- x O[int/x] |- AST Type env. Types : int O[int/x] |- (O[int/x])[Str/y] |- (O[int/x])[Str/x] |- x : int : Str (O[int/x])[Str/y] |- (O[int/x])[Str/x] |- (O(len) = Str  Int) : int

Prof. Hilfinger CS164 Lecture 1937 Notes The type environment gives types to the free identifiers in the current scope The type environment is passed down the AST from the root towards the leaves Types are computed up the AST from the leaves towards the root

Prof. Hilfinger CS164 Lecture 1938 Let with Initialization COOL also has a let with initialization (I’ll let you guess what it’s supposed to mean): This rule is weak (i.e. too conservative). Why? O |- e 0 : T 0 O[T 0 /x] |- e 1 : T 1 O |- let x : T 0  e 0 in e 1 : T 1 [Let-Init]

Prof. Hilfinger CS164 Lecture 1939 Let with Initialization Consider the example: class C inherits P { … } … let x : P  new C in … … The previous let rule does not allow this code –We say that the rule is too weak

Prof. Hilfinger CS164 Lecture 1940 Subtyping Define a relation X  Y on classes to say that: –An object of type X could be used when one of type Y is acceptable, or equivalently –X conforms with Y –In Cool this means that X is a subclass of Y Define a relation  on classes X  X X  Y if X inherits from Y X  Z if X  Y and Y  Z

Prof. Hilfinger CS164 Lecture 1941 Let with Initialization (Again) Both rules for let are sound But more programs type check with the latter O |- e 0 : T T  T 0 O[T 0 /x] |- e 1 : T 1 O |- let x : T 0  e 0 in e 1 : T 1 [Let-Init]

Prof. Hilfinger CS164 Lecture 1942 Let with Subtyping. Notes. There is a tension between –Flexible rules that do not constrain programming –Restrictive rules that ensure safety of execution

Prof. Hilfinger CS164 Lecture 1943 Expressiveness of Static Type Systems A static type system enables a compiler to detect many common programming errors The cost is that some correct programs are disallowed –Some argue for dynamic type checking instead –Others argue for more expressive static type checking But more expressive type systems are also more complex

Prof. Hilfinger CS164 Lecture 1944 Dynamic And Static Types The dynamic type of an object is the class C that is used in the “new C” expression that creates the object –A run-time notion –Even languages that are not statically typed have the notion of dynamic type The static type of an expression is a notion that captures all possible dynamic types the expression could take –A compile-time notion

Prof. Hilfinger CS164 Lecture 1945 Dynamic and Static Types. (Cont.) In early type systems the set of static types correspond directly with the dynamic types Soundness theorem: for all expressions E  dynamic_type(E) = static_type(E) (in all executions, E evaluates to values of the type inferred by the compiler) This gets more complicated in advanced type systems

Prof. Hilfinger CS164 Lecture 1946 Dynamic and Static Types A variable of static type A can hold values of static type B, if B  A class A(Object): … class B(A): … def Main(): x: A x = A() … x  B() … x has static type A Here, x’s value has dynamic type A Here, x’s value has dynamic type B

Prof. Hilfinger CS164 Lecture 1947 Dynamic and Static Types Soundness theorem:   E. dynamic_type(E)  static_type(E) Why is this Ok? –For E, compiler uses static_type(E) (call it C) –All operations that can be used on an object of type C can also be used on an object of type C’  C Such as fetching the value of an attribute Or invoking a method on the object –Subclasses can only add attributes or methods –Methods can be redefined but with same type !

Prof. Hilfinger CS164 Lecture 1948 Let. Examples. Consider the following Cool class definitions Class A { a() : Int { 0 }; } Class B inherits A { b() : Int { 1 }; } An instance of B has methods “a” and “b” An instance of A has method “a” –A type error occurs if we try to invoke method “b” on an instance of A

Prof. Hilfinger CS164 Lecture 1949 Example of Wrong Let Rule (1) Now consider a hypothetical let rule: How is it different from the correct rule? O |- e 0 : T T  T 0 O |- e 1 : T 1 O |- let x : T 0  e 0 in e 1 : T 1 The following good program does not typecheck let x : Int  0 in x + 1 And some bad programs do typecheck foo(x : B) : Int { let x : A  new A in A.b() }

Prof. Hilfinger CS164 Lecture 1950 Example of Wrong Let Rule (2) Now consider another hypothetical let rule: How is it different from the correct rule? O |- e 0 : T T 0  T O[T 0 /x] |- e 1 : T 1 O |- let x : T 0  e 0 in e 1 : T 1 The following bad program is well typed let x : B  new A in x.b() Why is this program bad?

Prof. Hilfinger CS164 Lecture 1951 Example of Wrong Let Rule (3) Now consider another hypothetical let rule: How is it different from the correct rule? O |- e 0 : T T  T 0 O[T/x] |- e 1 : T 1 O |- let x : T 0  e 0 in e 1 : T 1 The following good program is not well typed let x : A  new B in {… x  new A; x.a(); } Why is this program not well typed?

Prof. Hilfinger CS164 Lecture 1952 Comments The typing rules use very concise notation They are very carefully constructed Virtually any change in a rule either: –Makes the type system unsound (bad programs are accepted as well typed) –Or, makes the type system less usable (good programs are rejected) But some good programs will be rejected anyway –The notion of a good program is undecidable

Prof. Hilfinger CS164 Lecture 1953 Assignment More uses of subtyping: To the left, rule for languages with assignment expressions; to the right, assignment statements O(id) = T 0 O |- e 1 : T 1 T 1  T 0 O |- id  e 1 : T 1 O(id) = T 0 O |- e 1 : T 1 T 1  T 0 O |- id  e 1 : void

Prof. Hilfinger CS164 Lecture 1954 Assignment in Pyth Pyth rule is looser than most. Doesn’t by itself guarantee runtime type correctness, so check will be needed in some cases. O(id) = T 0 O |- e 1 : T 1 T 1  T 0  T 0  T 1 O |- id  e 1 : Void

Prof. Hilfinger CS164 Lecture 1955 Function call in Pyth Parameter passing resembles assignment Taking just the single-parameter case: O |- e 0 : T 1  T 2 O |- e 1 : T 3 T 1  T 3  T 3  T 1 O |- e 0 (e 1 ) : T 2

Prof. Hilfinger CS164 Lecture 1956 Conditional Expression Consider: if e 0 then e 1 else e 2 fi or e 0 ? e 1 : e 2 in C The result can be either e 1 or e 2 The dynamic type is either e 1 ’s or e 2 ’s type The best we can do statically is the smallest supertype larger than the type of e 1 and e 2

Prof. Hilfinger CS164 Lecture 1957 If-Then-Else example Consider the class hierarchy … and the expression if … then new A else new B fi Its type should allow for the dynamic type to be both A or B –Smallest supertype is P P A B

Prof. Hilfinger CS164 Lecture 1958 Least Upper Bounds lub(X,Y), the least upper bound of X and Y, is Z if –X  Z  Y  Z Z is an upper bound –X  Z’  Y  Z’  Z  Z’ Z is least among upper bounds Typically, the least upper bound of two types is their least common ancestor in the inheritance tree

Prof. Hilfinger CS164 Lecture 1959 If-Then-Else Revisited [If-Then-Else] O |- e 0 : Bool O |- e 1 : T 1 O |- e 2 : T 2 O |- if e 0 then e 1 else e 2 fi : lub(T 1, T 2 )