Recursive Types and Subtyping

Similar documents
Recursive Types and Subtyping

Programming Languages Lecture 15: Recursive Types & Subtyping

Programming Languages Lecture 14: Sum, Product, Recursive Types

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

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

Subtyping. Lecture 13 CS 565 3/27/06

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

Simply-Typed Lambda Calculus

Part III. Chapter 15: Subtyping

Second-Order Type Systems

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

CSCI-GA Scripting Languages

Part III Chapter 15: Subtyping

CS 4110 Programming Languages & Logics. Lecture 28 Recursive Types

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

Formal Systems and their Applications

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

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

CS558 Programming Languages

Subsumption. Principle of safe substitution

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

Lambda Calculi With Polymorphism

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

Type Checking and Type Inference

CSE-505: Programming Languages. Lecture 20.5 Recursive Types. Zach Tatlock 2016

Lambda Calculi With Polymorphism

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

Lecture 13: Subtyping

Subtyping and Objects

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

Denotational Semantics. Domain Theory

More Lambda Calculus and Intro to Type Systems

Polymorphic lambda calculus Princ. of Progr. Languages (and Extended ) The University of Birmingham. c Uday Reddy

G Programming Languages Spring 2010 Lecture 6. Robert Grimm, New York University

Types and Type Inference

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

CS 4110 Programming Languages & Logics. Lecture 27 Recursive Types

The Substitution Model

Lecture Overview. [Scott, chapter 7] [Sebesta, chapter 6]

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

Data Types. Every program uses data, either explicitly or implicitly to arrive at a result.

COS 320. Compiling Techniques

COMP 181. Agenda. Midterm topics. Today: type checking. Purpose of types. Type errors. Type checking

More Lambda Calculus and Intro to Type Systems

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

Object-Oriented Languages and Object-Oriented Design. Ghezzi&Jazayeri: OO Languages 1

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

More Lambda Calculus and Intro to Type Systems

Overloading, Type Classes, and Algebraic Datatypes

CS 242. Fundamentals. Reading: See last slide

Software System Design and Implementation

CS152: Programming Languages. Lecture 23 Advanced Concepts in Object-Oriented Programming. Dan Grossman Spring 2011

CS558 Programming Languages

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

COSE212: Programming Languages. Lecture 3 Functional Programming in OCaml

CS558 Programming Languages

Once Upon a Polymorphic Type

Lecture #23: Conversion and Type Inference

Graphical Untyped Lambda Calculus Interactive Interpreter

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

CSE-321 Programming Languages 2010 Final

Shared Subtypes. Subtyping Recursive Parameterized Algebraic Data Types

Programming Languages

Types. Type checking. Why Do We Need Type Systems? Types and Operations. What is a type? Consensus

The Substitution Model. Nate Foster Spring 2018

In Our Last Exciting Episode

Type Systems, Type Inference, and Polymorphism

Introduction to System F. Lecture 18 CS 565 4/20/09

Haskell 98 in short! CPSC 449 Principles of Programming Languages

Harvard School of Engineering and Applied Sciences Computer Science 152

Mutable References. Chapter 1

CS558 Programming Languages

Functional Programming and Haskell

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

Type Systems COMP 311 Rice University Houston, Texas

cs242 Kathleen Fisher Reading: Concepts in Programming Languages, Chapter 6 Thanks to John Mitchell for some of these slides.

Lecture Notes on Program Equivalence

Lesson 11 Universal Types. Universal Types and System F

CS 360: Programming Languages Lecture 12: More Haskell

TYPES, VALUES AND DECLARATIONS

Types. What is a type?

Type Checking and Type Equality

Semantic Analysis and Type Checking

Lambda Calculus and Type Inference

(Refer Slide Time: 4:00)

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

GADTs meet Subtyping

GADTs. Wouter Swierstra. Advanced functional programming - Lecture 7. Faculty of Science Information and Computing Sciences

Verifying Program Invariants with Refinement Types

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

CSCE 314 Programming Languages. Type System

Types and Type Inference

(Advanced) topics in Programming Languages

CMSC 330: Organization of Programming Languages

1 Introduction. 3 Syntax

Lists. Michael P. Fourman. February 2, 2010

Polymorphism and System-F (OV)

CMSC 336: Type Systems for Programming Languages Lecture 5: Simply Typed Lambda Calculus Acar & Ahmed January 24, 2008

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

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

Transcription:

Recursive Types and Subtyping #1

One-Slide Summary Recursive types (e.g., list) make the typed lambda calculus as powerful as the untyped lambda calculus. If is a subtype of then any expression of type can be used in a context that expects a ; this is called subsumption. A conversion is a function that converts between types. A subtyping system should be coherent. #2

Recursive Types: Lists We want to define recursive data structures Example: lists A list of elements of type (a list) is either empty or it is a pair of a and a list list = unit + ( list) This is a recursive equation. We take its solution to be the smallest set of values L that satisfies the equation L = { * } [ (T L) where T is the set of values of type Another interpretation is that the recursive equation is taken up-to (modulo) set isomorphism #3

Recursive Types We introduce a recursive type constructor mu t. The type variable t is bound in This stands for the solution to the equation t ' (t is isomorphic with ) Example: list = t. (unit + t) This also allows unnamed recursive types We introduce syntactic (sugary) operations for the conversion between t. and [ t. /t] e.g. between list and unit + ( list) e ::= fold t. e unfold t. e ::= t t. #4

Example with Recursive Types Lists list nil = t. (unit + t) = fold list (injl *) cons = x:. L: list. fold list injr (x, L) A list length function length = L: list. case (unfold list L) of injl x ) 0 injr y ) 1 + length (snd y) (At home ) Verify that : list nil cons :! list! list length : list! int #5

Type Rules for Recursive Types The typing rules are syntax directed Often, for syntactic simplicity, the fold and unfold operators are omitted This makes type checking somewhat harder #6

Dynamics of Recursive Types We add a new form of values v ::= fold t. v The purpose of fold is to ensure that the value has the recursive type and not its unfolding The evaluation rules: The folding annotations are for type checking only They can be dropped after type checking #7

Recursive Types in ML The language ML uses a simple syntactic trick to avoid having to write the explicit fold and unfold In ML recursive types are bundled with union types type t = C1 of 1 C2 of 2... Cn of n (* t can appear in i *) e.g., type intlist = Nil of unit Cons of int * intlist When the programmer writes the compiler treats it as Cons (5, l) foldintlist (injr (5, l)) When the programmer writes case e of Nil )... Cons (h, t) )... the compiler treats it as case unfoldintlist e of Nil )... Cons (h,t) )... #8

Encoding Call-by-Value -calculus in F1 So far, F1 was so weak that we could not encode non-terminating computations Cannot encode recursion Cannot write the x.x x (self-application) The addition of recursive types makes typed -calculus as expressive as untyped calculus! We could show a conversion algorithm from call-by-value untyped -calculus to call-byvalue F1 #9

Smooth Transition And now, on to subtyping... #10

Introduction to Subtyping We can view types as denoting sets of values Subtyping is a relation between types induced by the subset relation between value sets Informal intuition: If is a subtype of then any expression with type also has type (e.g., Z µ R, 12Z ) 12R) If is a subtype of then any expression of type can be used in a context that expects a We write < to say that is a subtype of Subtyping is reflexive and transitive #11

Cunning Plan For Subtyping Formalize Subtyping Requirements Subsumption Create Safe Subtyping Rules Pairs, functions, references, etc. Most easy thing we try will be wrong Subtyping Coercions When is a subtyping system correct? #12

Subtyping Examples FORTRAN introduced int < real 5 + 1.5 is well-typed in many languages PASCAL had [1..10] < [0..15] < int Subtyping is a fundamental property of object-oriented languages If S is a subclass of C then an instance of S can be used where an instance of C is expected subclassing ) subtyping philosophy #13

Subsumption Formalize the requirements on subtyping Rule of subsumption If < then an expression of type has type But now type safety may be in danger: If we say that int < (int! int) Then we can prove that 11 8 is well typed! There is a way to construct the subtyping relation to preserve type safety #14

Subtyping in POPL/PLDI 14 Backpack: Retrofitting Haskell with Interfaces Getting F-Bounded Polymorphism into Shape Optimal Inference of Fields in Row-Polymorphic Records Polymorphic Functions with Set-Theoretic Types (Part 1: Syntax, Semantics, and Evaluation) (out of space on slide) #15

Defining Subtyping The formal definition of subtyping is by derivation rules for the judgment < We start with subtyping on the base types e.g. int < real or nat < int These rules are language dependent and are typically based directly on types-as-sets arguments We then make subtyping a preorder (reflexive and transitive) Then we build-up subtyping for larger types #16

Subtyping for Pairs Try Show (informally) that whenever a s s can be used, a t t can also be used: Consider the context H = H [fst ²] expecting a s s Then H expects a s Because t < s then H accepts a t Take e : t t. Then fst e : t so it works in H Thus e works in H The case of snd ² is similar #17

Subtyping for Records Several subtyping relations for records Depth subtyping e.g., {f1 = int, f2 = int} < {f1 = real, f2 = int} Width subtyping E.g., {f1 = int, f2 = int} < {f2 = int} Models subclassing in OO languages Or, a combination of the two #18

Subtyping for Functions Example Use: rounded_sqrt :R!Z actual_sqrt :R!R Since Z < R, rounded_sqrt < actual_sqrt So if I have code like this: float result = rounded_sqrt(5); // 2 I can replace it like this: float result = actual_sqrt(5); // 2.23 and everything will be fine. #19

Q: General (455 / 842) This numerical technique for finding solutions to boundary-value problems was initially developed for use in structural analysis in the 1940's. The subject is represented by a model consisting of a number of linked simplified representations of discrete regions. It is often used to determine stress and displacement in mechanical systems.

Computer Science This American Turing-award winner is known for his visionary and pioneering contributions to Computer Graphics, and for Sketchpad, an early predecessor to the GUI. He created the first virtual reality display, and a graphics line clipping algorithm. His students include Alan Kay (Smalltalk), Henri Gouraud (shading), Frank Crow (anti-aliasing), and Edwin Catmull (Pixar). When asked, "How could you possibly have done the first interactive graphics program, the first non-procedural programming language, the first object oriented software system, all in one year?" He replied: "Well, I didn't know it was hard."

Subtyping for Functions What do you think of this rule? #22

Subtyping for Functions This rule is unsound Let = f : int! bool (and assume int < real) We show using the above rule that ` f 5.0 : bool But this is wrong since 5.0 is not a valid argument of f #23

Correct Function Subtyping We say that! is covariant in the result type and contravariant in the argument type Informal correctness argument: Pick f :! f expects an argument of type It also accepts an argument of type < f returns a value of type Which can also be viewed as a (since < ) Hence f can be used as! #24

More on Contravariance Consider the subtype relationships: int! real real! real int! int real! int In what sense (f 2 real! int) ) (f 2 int! int)? real! int has a larger domain! (recall the set theory (arg,result) pair encoding for functions) This suggests that subtype-as-subset interpretation is not straightforward We ll return to this issue (after these commercial messages ) #25

Subtyping References Try covariance Example: assume < The following holds (if we assume the above rule): x :, y : ref, f :! int ` y := x; f (! y) Unsound: f is called on a but is defined only on Java has covariant arrays! If we want covariance of references we can recover type safety with a runtime check for each y := x The actual type of x matches the actual type of y But this is generally considered a bad design #26

Subtyping References (Part 2) Contravariance? Example: assume < The following holds (if we assume the above rule): x :, y : ref, f :! int ` y := x; f (! y) Unsound: f is called on a but is defined only on References are invariant No subtyping for references (unless we are prepared to add run-time checks) hence, arrays should be invariant hence, mutable records should be invariant #27

Subtyping Recursive Types Recall list = t.(unit + t) We would like list < list whenever < Covariance? This is wrong if t occurs contravariantly in Take = t.t!int and = t.t!real Above rule says that < We have '!int and '!real < would mean covariant function type! How can we get safe subtyping for lists? #28

Subtyping Recursive Types The correct rule Means assume t < s and use that to prove < We add as an assumption that the type variables stand for types with the desired subtype relationship Before we assumed they stood for the same type! Verify that now subtyping works properly for lists There is no subtyping between t.t!int and t.t! real (recall: #29

Conversion Interpretation The subset interpretation of types leads to an abstract modeling of the operational behavior e.g., we say int < real even though an int could not be directly used as a real in the concrete x86 implementation (cf. IEEE 754 bit patterns) The int needs to be converted to a real We can get closer to the machine with a conversion interpretation of subtyping We say that < when there is a conversion function that converts values of type to values of type Conversions also help explain issues such as contravariance But: must be careful with conversions #30

Conversions Examples: nat < int with conversion x.x int < real with conversion 2 s comp! IEEE The subset interpretation is a special case when all conversions are identity functions Write < ) C(, ) to say that C(, ) is the conversion function from subtype to If C(, ) is expressed in F1 then C(, ) :! #31

Issues with Conversions Consider the expression printreal 1 typed as follows: we convert 1 to real: printreal (C(int,real) 1) But we can also have another type derivation: with conversion (C(real -> unit, int -> unit) printreal) 1 Which one is right? What do they mean? #32

Introducing Conversions We can compile a language with subtyping into one without subtyping by introducing conversions The process is similar to type checking `e: )e Expression e has type and its conversion is e Rules for the conversion process: #33

Coherence of Conversions Questions and Concerns: Can we build arbitrary subtype relations just because we can write conversion functions? Is real < int just because the floor function is a conversion? What is the conversion from real!int to int!int? What are the restrictions on conversion functions? A system of conversion functions is coherent if whenever we have < < then C(, ) C(, ) = x.x = C(, ) C(, ) (= composed with) Example: if b is a bool then (float)b == (float)((int)b) otherwise we end up with confusing uses of subsumption #34

Example of Coherence We want the following subtyping relations: int < real ) x:int. toieee x real < int ) x:real. floor x For this system to be coherent we need C(int, real) C(real, int) C(real, int) = x.x, and C(int, real) = x.x This requires that 8x : real. ( toieee (floor x) = x ) which is not true #35

Building Conversions We start from conversions on basic types #36

Comments With the conversion view we see why we do not necessarily want to impose antisymmetry for subtyping Can have multiple representations of a type We want to reserve type equality for representation equality < and also < (are interconvertible) but not necessarily = e.g., Modula-3 has packed and unpacked records We ll encounter subtyping again for object-oriented languages Serious difficulties there due to recursive types #37

Homework How's that project going? #38