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

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

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

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

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

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

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

Programming Languages Lecture 15: Recursive Types & Subtyping

Programming Languages Lecture 14: Sum, Product, Recursive Types

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

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

CSE-505: Programming Languages. Lecture 18 Existential Types. Zach Tatlock 2016

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

Lecture #13: Type Inference and Unification. Typing In the Language ML. Type Inference. Doing 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";

Recursive Types and Subtyping

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

CS 4110 Programming Languages & Logics. Lecture 27 Recursive Types

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

We defined congruence rules that determine the order of evaluation, using the following evaluation

Recursive Types and Subtyping

Harvard School of Engineering and Applied Sciences Computer Science 152

CS 4110 Programming Languages & Logics. Lecture 28 Recursive Types

CS152: Programming Languages. Lecture 7 Lambda Calculus. Dan Grossman Spring 2011

Lecture 13: Subtyping

Whereweare. CS-XXX: Graduate Programming Languages. Lecture 7 Lambda Calculus. Adding data structures. Data + Code. What about functions

CSE 505: Concepts of Programming Languages

CSE341 Autumn 2017, Final Examination December 12, 2017

CS131 Typed Lambda Calculus Worksheet Due Thursday, April 19th

CSE341 Spring 2017, Final Examination June 8, 2017

l e t print_name r = p r i n t _ e n d l i n e ( Name : ^ r. name)

λ calculus is inconsistent

CSE341 Spring 2017, Final Examination June 8, 2017

Types and Programming Languages. Lecture 5. Extensions of simple types

CS611 Lecture 33 Equirecursive types & Recursive domain equations November 19, 2001

Hiding local state in direct style: a higher-order anti-frame rule

Generic polymorphism on steroids

Part VI. Imperative Functional Programming

Subtyping. Lecture 13 CS 565 3/27/06

CSCI-GA Scripting Languages

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

Featherweight Java (FJ)

The Typed λ Calculus and Type Inferencing in ML

CSE341: Programming Languages Lecture 6 Nested Patterns Exceptions Tail Recursion. Zach Tatlock Winter 2018

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

Lecture Notes on Aggregate Data Structures

CSE505, Fall 2012, Midterm Examination October 30, 2012

CSE-321 Programming Languages 2010 Final

ML 4 Unification Algorithm

Topics Covered Thus Far. CMSC 330: Organization of Programming Languages. Language Features Covered Thus Far. Programming Languages Revisited

COMP 4161 NICTA Advanced Course. Advanced Topics in Software Verification. Toby Murray, June Andronick, Gerwin Klein

CMSC 330: Organization of Programming Languages

CS 312. Lecture April Lazy Evaluation, Thunks, and Streams. Evaluation

Lecture Notes on Data Representation

Overview. Elements of Programming Languages. Records. Named variants. Last time: Simple data structures: pairing (product types), choice (sum types)

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

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

CSE-321 Programming Languages 2011 Final

Programming Languages

Theorem Proving Principles, Techniques, Applications Recursion

CSE 341: Programming Languages

Recitation 6: System F and Existential Types : Foundations of Programming Languages

Lambda Calculi With Polymorphism

Subsumption. Principle of safe substitution

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

MLW. Henk Barendregt and Freek Wiedijk assisted by Andrew Polonsky. March 26, Radboud University Nijmegen

Lecture 9: Typed Lambda Calculus

Structural polymorphism in Generic Haskell

MPRI course 2-4 Functional programming languages Exercises

Part III. Chapter 15: Subtyping

Symmetry in Type Theory

Second-Order Type Systems

CSE 505: Programming Languages. Lecture 10 Types. Zach Tatlock Winter 2015

The story so far. Elements of Programming Languages. Pairs in various languages. Pairs

Basic Foundations of Isabelle/HOL

Supplementary Notes on Recursive Types

Lambda Calculi With Polymorphism

Shared Subtypes. Subtyping Recursive Parameterized Algebraic Data Types

Combining Proofs and Programs in a Dependently Typed Language. Certification of High-level and Low-level Programs

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

Lecture 14: Recursive Types

Functional Programming and λ Calculus. Amey Karkare Dept of CSE, IIT Kanpur

CS Lecture 6: Map and Fold. Prof. Clarkson Spring Today s music: Selections from the soundtrack to 2001: A Space Odyssey

SCHEME AND CALCULATOR 5b

Typed Compilation of Recursive Datatypes

Programming in Omega Part 1. Tim Sheard Portland State University

Lambda Calculus and Type Inference

Type Systems. Parametric Polymorphism. 1. Recall Let-Polymorphism. 1. Recall Let-Polymorphism. Lecture 9 Dec. 15th, 2004 Sebastian Maneth

Sometimes it s good to be lazy

Programming Language Features. CMSC 330: Organization of Programming Languages. Turing Completeness. Turing Machine.

CMSC 330: Organization of Programming Languages

Handout 2 August 25, 2008

CSE-321 Programming Languages 2012 Midterm

1 Introduction. 3 Syntax

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

An update on XML types

Functional Programming. Lecture 2: Algebra

Dependent types and program equivalence. Stephanie Weirich, University of Pennsylvania with Limin Jia, Jianzhou Zhao, and Vilhelm Sjöberg

A Simple Supercompiler Formally Verified in Coq

COMP 1130 Lambda Calculus. based on slides by Jeff Foster, U Maryland

Transcription:

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

Where are we System F gave us type abstraction code reuse strong abstractions different from real languages (like ML), but the right foundation This lecture: Recursive Types (different use of type variables) For building unbounded data structures Turing-completeness without a fix primitive Zach Tatlock CSE-505 2016, Lecture 20.5 2

Recursive Types We could add list types (list(τ )) and primitives ([], ::, match), but we want user-defined recursive types Intuition: type intlist = Empty Cons int * intlist Which is roughly: type intlist = unit + (int * intlist) Seems like a named type is unavoidable But that s what we thought with let rec and we used fix Analogously to fix λx. e, we ll introduce µα.τ Each α stands for entire µα.τ Zach Tatlock CSE-505 2016, Lecture 20.5 3

Mighty µ In τ, type variable α stands for µα.τ, bound by µ Examples (of many possible encodings): int list (finite or infinite): µα.unit + (int α) int list (infinite stream ): µα.int α Need laziness (thunking) or mutation to build such a thing Under CBV, can build values of type µα.unit (int α) int list list: µα.unit + ((µβ.unit + (int β)) α) Examples where type variables appear multiple times: int tree (data at nodes): µα.unit + (int α α) int tree (data at leaves): µα.int + (α α) Zach Tatlock CSE-505 2016, Lecture 20.5 4

Using µ types How do we build and use int lists (µα.unit + (int α))? We would like: Zach Tatlock CSE-505 2016, Lecture 20.5 5

Using µ types How do we build and use int lists (µα.unit + (int α))? We would like: empty list = A(()) Has type: µα.unit + (int α) Zach Tatlock CSE-505 2016, Lecture 20.5 5

Using µ types How do we build and use int lists (µα.unit + (int α))? We would like: empty list = A(()) Has type: µα.unit + (int α) cons = λx:int. λy:(µα.unit + (int α)). B((x, y)) Has type: int (µα.unit + (int α)) (µα.unit + (int α)) Zach Tatlock CSE-505 2016, Lecture 20.5 5

Using µ types How do we build and use int lists (µα.unit + (int α))? We would like: empty list = A(()) Has type: µα.unit + (int α) cons = λx:int. λy:(µα.unit + (int α)). B((x, y)) Has type: int (µα.unit + (int α)) (µα.unit + (int α)) head = λx:(µα.unit + (int α)). match x with A. A(()) By. B(y.1) Has type: (µα.unit + (int α)) (unit + int) Zach Tatlock CSE-505 2016, Lecture 20.5 5

Using µ types How do we build and use int lists (µα.unit + (int α))? We would like: empty list = A(()) Has type: µα.unit + (int α) cons = λx:int. λy:(µα.unit + (int α)). B((x, y)) Has type: int (µα.unit + (int α)) (µα.unit + (int α)) head = λx:(µα.unit + (int α)). match x with A. A(()) By. B(y.1) Has type: (µα.unit + (int α)) (unit + int) tail = λx:(µα.unit + (int α)). match x with A. A(()) By. B(y.2) Has type: (µα.unit + (int α)) (unit + µα.unit + (int α)) Zach Tatlock CSE-505 2016, Lecture 20.5 5

Using µ types How do we build and use int lists (µα.unit + (int α))? We would like: empty list = A(()) Has type: µα.unit + (int α) cons = λx:int. λy:(µα.unit + (int α)). B((x, y)) Has type: int (µα.unit + (int α)) (µα.unit + (int α)) head = λx:(µα.unit + (int α)). match x with A. A(()) By. B(y.1) Has type: (µα.unit + (int α)) (unit + int) tail = λx:(µα.unit + (int α)). match x with A. A(()) By. B(y.2) Has type: (µα.unit + (int α)) (unit + µα.unit + (int α)) But our typing rules allow none of this (yet) Zach Tatlock CSE-505 2016, Lecture 20.5 5

Using µ types (continued) For empty list = A(()), one typing rule applies: ; Γ e : τ 1 τ 2 ; Γ A(e) : τ 1 + τ 2 So we could show ; Γ A(()) : unit + (int (µα.unit + (int α))) (since F T V (int µα.unit + (int α)) = ) Zach Tatlock CSE-505 2016, Lecture 20.5 6

Using µ types (continued) For empty list = A(()), one typing rule applies: ; Γ e : τ 1 τ 2 ; Γ A(e) : τ 1 + τ 2 So we could show ; Γ A(()) : unit + (int (µα.unit + (int α))) (since F T V (int µα.unit + (int α)) = ) But we want µα.unit + (int α) Zach Tatlock CSE-505 2016, Lecture 20.5 6

Using µ types (continued) For empty list = A(()), one typing rule applies: ; Γ e : τ 1 τ 2 ; Γ A(e) : τ 1 + τ 2 So we could show ; Γ A(()) : unit + (int (µα.unit + (int α))) (since F T V (int µα.unit + (int α)) = ) But we want µα.unit + (int α) Notice: unit + (int (µα.unit + (int α))) is (unit + (int α))[(µα.unit + (int α))/α] Zach Tatlock CSE-505 2016, Lecture 20.5 6

Using µ types (continued) For empty list = A(()), one typing rule applies: ; Γ e : τ 1 τ 2 ; Γ A(e) : τ 1 + τ 2 So we could show ; Γ A(()) : unit + (int (µα.unit + (int α))) (since F T V (int µα.unit + (int α)) = ) But we want µα.unit + (int α) Notice: unit + (int (µα.unit + (int α))) is (unit + (int α))[(µα.unit + (int α))/α] The key: Subsumption recursive types are equal to their unrolling Zach Tatlock CSE-505 2016, Lecture 20.5 6

Return of subtyping Can use subsumption and these subtyping rules: roll unroll τ [(µα.τ )/α] µα.τ µα.τ τ [(µα.τ )/α] Subtyping can roll or unroll a recursive type Can now give empty-list, cons, and head the types we want: Constructors use roll, destructors use unroll Notice how little we did: One new form of type (µα.τ ) and two new subtyping rules (Skipping: Depth subtyping on recursive types is very interesting) Zach Tatlock CSE-505 2016, Lecture 20.5 7

Metatheory Despite additions being minimal, must reconsider how recursive types change STLC and System F: Erasure (no run-time effect): unchanged Termination: changed! (λx:µα.α α. x x)(λx:µα.α α. x x) In fact, we re now Turing-complete without fix (actually, can type-check every closed λ term) Safety: still safe, but Canonical Forms harder Inference: Shockingly efficient for STLC plus µ (A great contribution of PL theory with applications in OO and XML-processing languages) Zach Tatlock CSE-505 2016, Lecture 20.5 8

Syntax-directed µ types Recursive types via subsumption seems magical Instead, we can make programmers tell the type-checker where/how to roll and unroll Iso-recursive types: remove subtyping and add expressions: τ ::= µα.τ e ::= roll µα.τ e unroll e v ::= roll µα.τ v e e e e roll µα.τ e roll µα.τ e unroll e unroll e unroll (roll µα.τ v) v ; Γ e : τ [(µα.τ )/α] ; Γ roll µα.τ e : µα.τ ; Γ e : µα.τ ; Γ unroll e : τ [(µα.τ )/α] Zach Tatlock CSE-505 2016, Lecture 20.5 9

Syntax-directed, continued Type-checking is syntax-directed / No subtyping necessary Canonical Forms, Preservation, and Progress are simpler This is an example of a key trade-off in language design: Implicit typing can be impossible, difficult, or confusing Explicit coercions can be annoying and clutter language with no-ops Most languages do some of each Anything is decidable if you make the code producer give the implementation enough hints about the proof Zach Tatlock CSE-505 2016, Lecture 20.5 10

ML datatypes revealed How is µα.τ related to type t = Foo of int Bar of int * t Constructor use is a sum-injection followed by an implicit roll So Foo e is really roll t Foo(e) That is, Foo e has type t (the rolled type) A pattern-match has an implicit unroll So match e with... is really match unroll e with... This trick works because different recursive types use different tags so the type-checker knows which type to roll to Zach Tatlock CSE-505 2016, Lecture 20.5 11