Subtyping and Objects

Similar documents
Subtyping. Lecture 13 CS 565 3/27/06

Lecture 13: Subtyping

Part III. Chapter 15: Subtyping

Part III Chapter 15: Subtyping

Programming Languages Lecture 15: Recursive Types & Subtyping

Tradeoffs. CSE 505: Programming Languages. Lecture 15 Subtyping. Where shall we add useful completeness? Where shall we add completeness?

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

Subtyping: An introduction

CS558 Programming Languages

Harvard School of Engineering and Applied Sciences Computer Science 152

Subtyping (cont) Lecture 15 CS 565 4/3/08

Recursive Types and Subtyping

CS558 Programming Languages

Type Systems. Pierce Ch. 3, 8, 11, 15 CSE

CSCI-GA Scripting Languages

Types for References, Exceptions and Continuations. Review of Subtyping. Γ e:τ τ <:σ Γ e:σ. Annoucements. How s the midterm going?

CSE 505, Fall 2008, Final Examination 11 December 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

Subtyping (cont) Formalization of Subtyping. Lecture 15 CS 565. Inversion of the subtype relation:

CMSC 330: Organization of Programming Languages

Recursive Types and Subtyping

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

Subsumption. Principle of safe substitution

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

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

Type Checking and Type Inference

Some instance messages and methods

Week 7. Statically-typed OO languages: C++ Closer look at subtyping

ML Built-in Functions

INF 212 ANALYSIS OF PROG. LANGS Type Systems. Instructors: Crista Lopes Copyright Instructors.

On to Objects. CIS 500 Software Foundations Fall November 20. A Change of Pace. Case study: object-oriented programming

Object typing and subtypes

COS 320. Compiling Techniques

Official Survey. Cunning Plan: Focus On Objects. The Need for a Calculus. Object Calculi Summary. Why Not Use λ-calculus for OO?

Types, Type Inference and Unification

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

A Type is a Set of Values. Here we declare n to be a variable of type int; what we mean, n can take on any value from the set of all integer values.

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

UNIVERSITETET I OSLO

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

Lambda Calculi With Polymorphism

CS558 Programming Languages

Rushikesh K Joshi. Department of Computer Science and Engineering Indian Institute of Technology Bombay

Mutable References. Chapter 1

1. true / false By a compiler we mean a program that translates to code that will run natively on some machine.

Lambda Calculi With Polymorphism

Types and Type Inference

Lecture #23: Conversion and Type Inference

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

Compilation 2012 Static Type Checking

Type assignment for intersections and unions in call-by-value languages

COSE212: Programming Languages. Lecture 4 Recursive and Higher-Order Programming

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

PROGRAMMING LANGUAGE 2

COMPUTER SCIENCE TRIPOS

Argument Passing All primitive data types (int etc.) are passed by value and all reference types (arrays, strings, objects) are used through refs.

Exercise 8 Parametric polymorphism November 17, 2017

Programming Languages Fall 2013

CS4215 Programming Language Implementation. Martin Henz

L3 Programming September 19, OCaml Cheatsheet

Types for Flexible Objects

CMSC 330: Organization of Programming Languages. Operational Semantics

CS-XXX: Graduate Programming Languages. Lecture 23 Types for OOP; Static Overloading and Multimethods. Dan Grossman 2012

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

Cunning Plan. One-Slide Summary. Functional Programming. Functional Programming. Introduction to COOL #1. Classroom Object-Oriented Language

CS131 Typed Lambda Calculus Worksheet Due Thursday, April 19th

Project 6 Due 11:59:59pm Thu, Dec 10, 2015

Chapter 13: Reference. Why reference Typing Evaluation Store Typings Safety Notes

Mutation. COS 326 David Walker Princeton University

All the operations used in the expression are over integers. a takes a pair as argument. (a pair is also a tuple, or more specifically, a 2-tuple)

Programming Languages Assignment #7

Object-oriented programming in...

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

Compiler Construction I

CSCI-GA Final Exam

Checking Type Safety of Foreign Function Calls

GADTs meet Subtyping

Type Systems, Type Inference, and Polymorphism

A declaration may appear wherever a statement or expression is allowed. Limited scopes enhance readability.

Subtyping (Dynamic Polymorphism)

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

step is to see how C++ implements type polymorphism, and this Exploration starts you on that journey.

Gradual Typing for Functional Languages. Jeremy Siek and Walid Taha (presented by Lindsey Kuper)

Modal Logic: Implications for Design of a Language for Distributed Computation p.1/53

Type Inference Systems. Type Judgments. Deriving a Type Judgment. Deriving a Judgment. Hypothetical Type Judgments CS412/CS413

Checking Type Safety of Foreign Function Calls

Exercise 8 Parametric polymorphism November 18, 2016

Datatype declarations

CSE-321 Programming Languages 2010 Final

Static Type Checking. Static Type Checking. The Type Checker. Type Annotations. Types Describe Possible Values

At build time, not application time. Types serve as statically checkable invariants.

Discussion. Type 08/12/2016. Language and Type. Type Checking Subtypes Type and Polymorphism Inheritance and Polymorphism

Object Oriented Paradigm

Topics Covered Thus Far CMSC 330: Organization of Programming Languages

CSE341, Fall 2011, Lecture 26 Summary

Exercises on ML. Programming Languages. Chanseok Oh

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

Formal Semantics. Prof. Clarkson Fall Today s music: Down to Earth by Peter Gabriel from the WALL-E soundtrack

Subtyping: broad definitions. Not Subtyping: type variable instantiation. Mutable Records (half like ML, half like Java/Scala)

CS Programming Languages: Scala

Transcription:

Subtyping and Objects Massimo Merro 20 November 2017 Massimo Merro Data and Mutable Store 1 / 22

Polymorphism So far, our type systems are very rigid: there is little support to code reuse. Polymorphism Ability to use expressions at different places with different types. Ad-hoc polymorphism (overloading). e.g. in Moscow ML (but also in Java) the built in + can be used to add two integers or to add two reals. Parametric polymorphism - as in ML. Can write, for instance, a function that can take as an argument of type list α and computes its lenght (parmametric - uniformly in whatever α is). Subtype polymorphism - as in most Object-Oriented Languages. Dating back to 1960s (Simula etc.) formalized in the 1980s. We will focus on this kind of subtyping! Massimo Merro Data and Mutable Store 2 / 22

Subtyping - Motivation Let us recall the typing rules for the functional extension: (fun) (app) Γ, x : T e : T Γ (fn x : T e) : T T Γ e 1 : T T Γ e 2 : T Γ e 1 e 2 : T According to our type system: Γ (fn x : {left : int} #left x) : {left : int} int Thus, we cannot type the following: Γ (fn x : {left : int} #left x){left = 3, right = 5} Even if we are giving the function a better argument, with more structure, than it is required by the function itself! Massimo Merro Data and Mutable Store 3 / 22

Subsumption In which sense we are passing a better argument? Any value of type {left : int, right : int} can be safely used whenever a value of type {left : int} is expected! Introduce a subtyping relation between types, written T <: T, read as T is a subtype of T : an object of type T can always be used in a context where an object of type T is expected! So, for instance: {left : int, right : int} <: {left : int} <: {} The subtype relation <: is then used by introducing a subsumption rule Γ e : T T <: T (sub) Γ e : T Massimo Merro Data and Mutable Store 4 / 22

Example By an application of rule (sub) we can deduce that (sub) Γ {left = 3, right = 5} : {left : int, right : int} {left : int, right : int} <: {left : int} Γ {left = 3, right = 5} : {left : int} and type the previous expression: (app) {} (fn x : {left : int} #left x) : {left : int} int {} {left = 3, right = 5} : {left : int} {} (fn x : {left : int} #left x){left = 3, right = 5} : int Massimo Merro Data and Mutable Store 5 / 22

The Subtype relation T <: T It is a reflexive and transitive relation: (s-refl) (s-trans) T <: T T <: T T <: T T <: T Let us define subtyping for the different data structures of our language. Massimo Merro Data and Mutable Store 6 / 22

Subtyping - Records Allowing reordering of fields: (rec-perm) π a permutation of 1, 2,... k {p 1 :T 1,..., p k :T k } <: {p π(1) :T π(1),..., p π(k) :T π(k) } The subtype relation is not anti-symmetric: a preorder, not a partial order. Forgetting about fields on the right: (rec-width) {p 1 :T 1,..., p k :T k, p k+1 :T k+1,... p z :T z } <: {p 1 :T 1,..., p k :T k } If we do reordering first, we can forget about any field. Allowing subtype within fields: (rec-depth) T 1 <: T 1... T k <: T k {p 1 :T 1,..., p k :T k } <: {p 1 :T 1,..., p k:t k } Subtyping is said to be covariant on record types! Massimo Merro Data and Mutable Store 7 / 22

Example: Combining rules For instance, we can derive: (rec-d) (rec-w) (rec-w) {p : int, q : int} <: {p : int} {r : int} <: {} {x : {p:int, q:int}, y : {r:int}} <: {x : {p:int}, y : {}} Another possibility is: (trans) (w) {x : {p:int, q:int}, y : {r:int}} <: {x : {p : int, q : int}} {x : {p:int, q:int}, y : {r:int}} <: {x : {p:int}} where is: (rec-depth) (rec-width) {p : int, q : int} <: {p : int} {x : {p:int, q:int}} <: {x : {p:int}} Massimo Merro Data and Mutable Store 8 / 22

Subtyping - Functions The subtyping rule is the following: (fun-sub) T 1 :> T 1 T 2 <: T 2 T 1 T 2 <: T 1 T 2 We say that subtyping on functions is: contravariant on the left of covariant on the right of (like the rule (rec-depth)). Massimo Merro Data and Mutable Store 9 / 22

Thus, if f : T 1 T 2 then we can use f in any context where: we give f any argument of type T 1, with T 1 <: T 1 we use the result of f as it was of type T 2, with of T 2 <: T 2. For instance, if we define f in a let construct: let f : T = fn x : {p : int} {a = #p x, b = 28} in e then when typing e we must use a type environment Γ such that Γ(f ) = T = {p : int} {a : int, b : int}. By subtyping we can use f in e as it had one of the following types: basically, because {p : int} {a : int} {p : int, q : int} {a : int, b : int} {p : int, q : int} {a : int} {p : int} :> {p : int, q : int} {a : int, b : int} <: {a : int} Massimo Merro Data and Mutable Store 10 / 22

On the other hand, in the program let f : ˆT = fn x : {p : int, q : int} {a = (#p x) + (#q x)} in e when typing e we must use a type environment Γ such that: Γ(f ) = ˆT = {p : int, q : int} {a : int }. By subtyping, we can use f in e as it had, for instance, type: {p : int, q : int, r : int} {a : int} However, by no means we can use f in e as it had one of the following types: {p : int} T, for any Γ and T T {a : int, b : int}, for any Γ and T Massimo Merro Data and Mutable Store 11 / 22

Subtyping - Products and Sums Subtyping is covariant on both components of products: (prod-sub) T 1 <: T 1 T 2 <: T 2 T 1 T 2 <: T 1 T 2 Again, covariant on both components of summations (sum-sub) T 1 <: T 1 T 2 <: T 2 T 1 + T 2 <: T 1 + T 2 Massimo Merro Data and Mutable Store 12 / 22

Subtyping - References We don t introduce subtyping rules for references to avoid inconsistencies while typing. See exercises. Massimo Merro Data and Mutable Store 13 / 22

What else does it change? Semantics No change (note that we have not changed the grammar for expressions) Properties Of course, we still have Type Preservation and Progress. Implementation Type inference is now more subtle, as the typing rules are not syntax-directed. Getting a good runtime implementation is also tricky, especially with field reordering. Massimo Merro Data and Mutable Store 14 / 22

Subtyping - Down-casts The subsumption rule (sub) permits up-casting at any moment: If T <: T, any expression e of type T can be used in any context where an expression of type T is expected! How about down-casting? Suppose to add in the grammar a construct: e ::=... (T )e with the typing rule (down-cast) Γ e : T T <: T Γ (T )e : T Can we statically type-check an expression (T )e? No! This can be done only dynamically because the correctness of the down-casting depends on the real type, at runtime, of e. Massimo Merro Data and Mutable Store 15 / 22

Example on down-casting Recall that {left : int, right : int} <: {left : int} <: {} Let us suppose to have a fragment of code of the form l :=!m; e where, at runtime, at location m, there will be in the store an expression of one of the three types above. Now, can we statically type-check in e the following expression ({left : int})!l? No! Because at runtime!l could return an object of type {left : int, right : int} but {left : int} : {left : int, right : int}. Thus, down-casting can only be dynamically type-checked. Massimo Merro Data and Mutable Store 16 / 22

(Very simple) Objects let cnt : {get : unit int, inc : unit unit} = let val : ref int = ref 0 in {get = fn y:unit!val, inc = fn y:unit val :=!val + 1} in (#inc cnt)(); (#get cnt)() cnt models a simple object of type Counter = {get : unit int, inc : unit unit} with two methods: get() and inc() 1 ; val records the state (ie the value) of the counter which can be accessed only be means of the two methods. 1 For simplicity we write e() instead of e(skip). Massimo Merro Data and Mutable Store 17 / 22

Using Subtyping let cnt : {get : unit int, inc : unit unit, reset : unit unit} = let val : ref int = ref 0 in {get = fn y:unit!val, inc = fn y:unit val :=!val + 1} reset = y:unit val := 0} in (#inc cnt)(); (#get cnt)() The use of the new variable cnt is perfectly safe because now it has type ResetCounter = {get : unit int, inc : unit unit, reset : unit unit} with ResetCounter <: Counter. Massimo Merro Data and Mutable Store 18 / 22

Object Generators What about a function to generate new objects each time we wish so? let newcnt : unit {get : unit int, inc : unit unit} = fn z : unit let val : ref int = ref 0 in {get = fn y : unit!val, inc = fn y : unit val :=!val + 1} in (#inc (newcnt()))() With our simple data structures we can start programming in a object-oriented style! By the way, what about classes? Can we represent them? Massimo Merro Data and Mutable Store 19 / 22

Classes in Java (small example) Consider the following Java class: class Counter { protected int p; Counter() { this.p=0; } int get() { return this.p; } void inc() { this.p++; } }; Can we model something similar? Massimo Merro Data and Mutable Store 20 / 22

Reusing Method Code (Simple Classes) Recall the type Counter = {get : unit int, inc : unit unit}. First, make the internal state into a record: CounterRep = {p : ref int} let cntclass : CounterRep Counter = fn val : CounterRep {get = fn y:unit!(#p val), inc = fn y:unit (#p val) :=!(#p val) + 1} in let newcnt : unit Counter = fn z : unit let x : CounterRep = {p = ref 0} in cntclass x in... Massimo Merro Data and Mutable Store 21 / 22

Reusing Method Code (Simple Classes) Can we represent the following subclass in Java? class ResetCounter extends Counter { void reset() { this.p=0; } }; let resetcntclass : CounterRep ResetCounter = fn val : CounterRep let super : Counter = cntclass val in {get = #get super inc = #inc super reset = fn y:unit (#p val) := 0} in... and ResetCounter <: Counter entails CounterRep ResetCounter <: CounterRep Counter! Massimo Merro Data and Mutable Store 22 / 22