Docsity
Docsity

Prepare for your exams
Prepare for your exams

Study with the several resources on Docsity


Earn points to download
Earn points to download

Earn points by helping other students or get them with a premium plan


Guidelines and tips
Guidelines and tips

Type Checking and Subtyping in Object-Oriented Programming - Prof. Westley Weimer, Study notes of Programming Languages

The concepts of type checking and subtyping in object-oriented programming. It covers typing rules, typing environments, let rules, and subtyping, as well as examples and problem-solving techniques. The document also discusses the tension between flexible and restrictive type systems and the importance of expressiveness in static type systems.

Typology: Study notes

Pre 2010

Uploaded on 03/19/2009

koofers-user-efw
koofers-user-efw 🇺🇸

10 documents

1 / 76

Toggle sidebar

Related documents


Partial preview of the text

Download Type Checking and Subtyping in Object-Oriented Programming - Prof. Westley Weimer and more Study notes Programming Languages in PDF only on Docsity! #1 Type Checking Passing Out Review Forms Ask a Question: php java Searching All Topics 1 Results Returned How do I install the Pure Java SDK and run the example? Answer: Install the pure java SDK and run the example Location: http:i/knowledge.paypal.com/paypal/solution jsp?id=vs13893 Solution ID: vs13893 (6K) ely "T fibe you Harry — eves when your bead's on fire you don't complain.” #2 #5 Example: 1 + 2 ` 1 : Int ` 1 + 2 : Int ` 2 : Int #6 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: ` i : Object (i is an integer) If we can prove it, then it's true! #7 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 itself #10 Two More Rules ` not e : Bool ` e : Bool [Not] ` while e1 loop e2 pool : Object ` e1 : Bool ` e2 : T [Loop] #11 Typing: Example • Typing for while not false loop 1 + 2 * 3 pool while loop pool #12 Typing: Example • Typing for while not false loop 1 + 2 * 3 pool while loop pool not false #15 Typing: Example • Typing for while not false loop 1 + 2 * 3 pool while loop pool not false + 1: Bool : Bool #16 Typing: Example • Typing for while not false loop 1 + 2 * 3 pool while loop pool not false + 1: Bool : Bool : Int #17 Typing: Example • Typing for while not false loop 1 + 2 * 3 pool while loop pool not false + 1 * 2 : Bool : Bool : Int #20 Typing: Example • Typing for while not false loop 1 + 2 * 3 pool while loop pool not false + 1 * 2 3 : Bool : Bool : Int : Int : Int #21 Typing: Example • Typing for while not false loop 1 + 2 * 3 pool while loop pool not false + 1 * 2 3 : Bool : Bool : Int : Int : Int : Int #22 Typing: Example • Typing for while not false loop 1 + 2 * 3 pool while loop pool not false + 1 * 2 3 : Bool : Bool : Int : Int : Int : Int : Int #25 A Problem • What is the type of a variable reference? • The local structural rule does not carry enough information to give x a type. Fail. ` x : ? [Var] (x is an identifier) #26 A Solution: Put more information in the rules! • A type environment gives types for free variables – A type environment is a mapping from Object_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 – in the expression “x”, the variable “x” is free – in “let x : Int in x + y” only “y” is free – in “x + let x : Int in x + y” both “x”, “y” are free #27 Type Environments Let O be a function from Object_Identifiers to Types The sentence O ` e : T is read: Under the assumption that variables have the types given by O, it is provable that the expression e has the type T #30 Let O[T0/x] means “O modified to map x to T0 and behaving as O on all other arguments”: O[T0/x] (x) = T0 O[T0/x] (y) = O(y) (You can write O[x/T0] on tests/assignments.) O ` let x : T0 in e1 : T1 O[T0/x] ` e1 : T1 [Let-No-Init] #31 Let Example • Consider the Cool expression let x : T0 in (let y : T1 in Ex, y) + (let x : T2 in Fx, y) (where Ex, y and Fx, y are some Cool expression that contain occurrences of “x” and “y”) • Scope – of “y” is Ex, y – of outer “x” is Ex, y – of inner “x” is Fx, y • This is captured precisely in the typing rule. #32 Example of Typing “let” let x : T0 in let y : T1 in + let x : T2 in Ex, y Fx, y x AST #35 Example of Typing “let” let x : T0 in let y : T1 in + let x : T2 in Ex, y Fx, y O ` x O[T0/x] ` AST Type env. O[T0/x] ` O[T0/x] ` #36 Example of Typing “let” let x : T0 in let y : T1 in + let x : T2 in Ex, y Fx, y O ` x O[T0/x] ` (O[T0/x])[T1/y] ` AST Type env. O[T0/x] ` O[T0/x] ` #37 Example of Typing “let” let x : T0 in let y : T1 in + let x : T2 in Ex, y Fx, y O ` x O[T0/x] ` (O[T0/x])[T1/y] ` (O[T0/x])[T1/y] ` AST Type env. O[T0/x] ` O[T0/x] ` #40 Example of Typing “let” let x : T0 in let y : T1 in + let x : T2 in Ex, y Fx, y O ` x O[T0/x] ` (O[T0/x])[T1/y] ` (O[T0/x])[T1/y] ` : int AST Type env. Types : T0 O[T0/x] ` O[T0/x] ` (O[T0/x])[T2/x] ` #41 Example of Typing “let” let x : T0 in let y : T1 in + let x : T2 in Ex, y Fx, y O ` x O[T0/x] ` (O[T0/x])[T1/y] ` (O[T0/x])[T1/y] ` : int : int AST Type env. Types : T0 O[T0/x] ` O[T0/x] ` (O[T0/x])[T2/x] ` #42 Example of Typing “let” let x : T0 in let y : T1 in + let x : T2 in Ex, y Fx, y O ` x O[T0/x] ` (O[T0/x])[T1/y] ` (O[T0/x])[T1/y] ` : int : int AST Type env. Types : int : T0 O[T0/x] ` O[T0/x] ` (O[T0/x])[T2/x] ` #45 Example of Typing “let” let x : T0 in let y : T1 in + let x : T2 in Ex, y Fx, y O ` x O[T0/x] ` (O[T0/x])[T1/y] ` (O[T0/x])[T1/y] ` : int : int AST Type env. Types : int : int : int : int : T0 O[T0/x] ` O[T0/x] ` (O[T0/x])[T2/x] ` #46 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 Q: Movies (362 / 842) •In this 1992 comedy Dana Carvey and Mike Myers reprise a Saturday Night Live skit, sing Bohemian Rhapsody and say of a guitar: "Oh yes, it will be mine." #50 Let with Initialization Now consider let with initialization: This rule is weak. Why? O ` let x : T0 à e0 in e1 : T1 O ` e0 : T0 O[T0/x] ` e1 : T1 [Let-Init] #51 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 or incomplete #52 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 #55 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 #56 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 notation that captures all possible dynamic types the expression could take – A compile-time notion #57 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 (e.g., Java, Cool) #60 Subtyping Example • 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 #61 Example of Wrong Let Rule (1) • Now consider a hypothetical wrong let rule: • How is it different from the correct rule? O ` let x : T0 à e0 in e1 : T1 O ` e0 : T T · T0 O ` e1 : T1 #62 Example of Wrong Let Rule (1) • Now consider a hypothetical wrong let rule: • How is it different from the correct rule? O ` let x : T0 à e0 in e1 : T1 O ` e0 : T T · T0 O ` e1 : T1 • The following good program does not typecheck let x : Int à 0 in x + 1 • Why? #65 Example of Wrong Let Rule (3) • Now consider a hypothetical wrong let rule: • How is it different from the correct rule? O ` let x : T0 à e0 in e1 : T1 O ` e0 : T T · T0 O[T/x] ` e1 : T1 #66 Example of Wrong Let Rule (3) • Now consider a hypothetical wrong let rule: • How is it different from the correct rule? O ` let x : T0 à e0 in e1 : T1 O ` e0 : T T · T0 O[T/x] ` e1 : T1 • 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? #67 Typing Rule Notation • 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 (incomplete) (good programs are rejected) • But some good programs will be rejected anyway – The notion of a good program is undecidable #70 If-Then-Else • Consider: if e0 then e1 else e2 fi • The result can be either e1 or e2 • The dynamic type is either e1’s or e2’s type • The best we can do statically is the smallest supertype larger than the type of e1 and e2 #71 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 #72 Least Upper Bounds • Define: lub(X,Y) to be the least upper bound of X and Y. lub(X,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 • In Cool, the least upper bound of two types is their least common ancestor in the inheritance tree #75 Next Time (Post-Midterm) • Type checking method dispatch • Type checking with SELF_TYPE in COOL #76 Homework • Today: WA3 due • Wednesday: PA3 due – Parsing! • Thursday Feb 28 – Midterm 1 in Class – 2:05 - 3:15 – One page of notes (front and back) hand-written by you • Before Next Tuesday: Read Chapter 7.2
Docsity logo



Copyright © 2024 Ladybird Srl - Via Leonardo da Vinci 16, 10126, Torino, Italy - VAT 10816460017 - All rights reserved