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

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

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

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

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

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

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

Programming Languages Lecture 15: Recursive Types & Subtyping

Programming Languages Lecture 14: Sum, Product, Recursive Types

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

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

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

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";

CS 4110 Programming Languages & Logics. Lecture 27 Recursive Types

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

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

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

CS 4110 Programming Languages & Logics. Lecture 28 Recursive Types

Lecture 13: Subtyping

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

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

CSE 505: Concepts of Programming Languages

Recursive Types and Subtyping

Harvard School of Engineering and Applied Sciences Computer Science 152

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)

CSE341 Autumn 2017, Final Examination December 12, 2017

CSE341 Spring 2017, Final Examination June 8, 2017

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

Subtyping. Lecture 13 CS 565 3/27/06

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

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

Lecture Notes on Aggregate Data Structures

λ calculus is inconsistent

ML 4 Unification Algorithm

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

Generic polymorphism on steroids

CS152: Programming Languages. Lecture 2 Syntax. Dan Grossman Spring 2011

Part VI. Imperative Functional Programming

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

CSCI-GA Scripting Languages

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

Featherweight Java (FJ)

The Typed λ Calculus and Type Inferencing in ML

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

CMSC 330: Organization of Programming Languages

Basic Foundations of Isabelle/HOL

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

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

Lambda Calculi With Polymorphism

MPRI course 2-4 Functional programming languages Exercises

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

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

CSE341: Programming Languages Lecture 26 Course Victory Lap. Dan Grossman Spring 2016

Lecture Notes on Data Representation

Supplementary Notes on Recursive Types

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.

Lecture 14: Recursive Types

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

Agenda. CS301 Session 11. Common type constructors. Things we could add to Impcore. Discussion: midterm exam - take-home or inclass?

CS558 Programming Languages

Lambda Calculi With Polymorphism

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

Programming Languages. Thunks, Laziness, Streams, Memoization. Adapted from Dan Grossman s PL class, U. of Washington

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

Theorem Proving Principles, Techniques, Applications Recursion

CS-XXX: Graduate Programming Languages. Lecture 22 Class-Based Object-Oriented Programming. Dan Grossman 2012

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

Subsumption. Principle of safe substitution

CSE505, Fall 2012, Midterm Examination October 30, 2012

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

Handout 2 August 25, 2008

CSE-321 Programming Languages 2010 Final

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

Lecture 9: Typed Lambda Calculus

Structural polymorphism in Generic Haskell

1 Introduction. 3 Syntax

Programming in Omega Part 1. Tim Sheard Portland State University

CS 4110 Programming Languages & Logics. Lecture 17 Programming in the λ-calculus

Sometimes it s good to be lazy

CS152: Programming Languages. Lecture 5 Pseudo-Denotational Semantics. Dan Grossman Spring 2011

A Typed Lambda Calculus for Input Sanitation

Hard deadline: 3/28/15 1:00pm. Using software development tools like source control. Understanding the environment model and type inference.

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

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

Software Verification for Java 5

Part III. Chapter 15: Subtyping

Towards a Software Model Checker for ML. Naoki Kobayashi Tohoku University

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

4.5 Pure Linear Functional Programming

CSE 413 Languages & Implementation. Hal Perkins Winter 2019 Structs, Implementing Languages (credits: Dan Grossman, CSE 341)

Symmetry in Type Theory

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

Don t Believe the Hype. CS152: Programming Languages. Lecture 21 Object-Oriented Programming. Class-based OOP. So what is OOP?

Types-2. Polymorphism

Transcription:

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

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 Future lecture (?): Existential types (dual to universal types) First-class abstract types Closely related to closures and objects Future lecture (?): Type-and-effect systems Dan Grossman CS-XXX 2012, Lecture 17 2

Recursive Types We could add list types (list(τ )) and primitives ([], ::, match), but we want user-defined recursive types Intuition: Which is roughly: type intlist = Empty Cons int * intlist 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 µα.τ Dan Grossman CS-XXX 2012, Lecture 17 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 + (α α) Dan Grossman CS-XXX 2012, Lecture 17 4

Using µ types How do we build and use int lists (µα.unit + (int α))? We would like: Dan Grossman CS-XXX 2012, Lecture 17 5

Using µ types How do we build and use int lists (µα.unit + (int α))? We would like: empty list = A(()) Has type: µα.unit + (int α) Dan Grossman CS-XXX 2012, Lecture 17 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 α)) Dan Grossman CS-XXX 2012, Lecture 17 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) Dan Grossman CS-XXX 2012, Lecture 17 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 α)) Dan Grossman CS-XXX 2012, Lecture 17 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) Dan Grossman CS-XXX 2012, Lecture 17 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 α)) = ) Dan Grossman CS-XXX 2012, Lecture 17 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 α) Dan Grossman CS-XXX 2012, Lecture 17 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 α))/α] Dan Grossman CS-XXX 2012, Lecture 17 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 Dan Grossman CS-XXX 2012, Lecture 17 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) Dan Grossman CS-XXX 2012, Lecture 17 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) Dan Grossman CS-XXX 2012, Lecture 17 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 : τ [(µα.τ )/α] Dan Grossman CS-XXX 2012, Lecture 17 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 Dan Grossman CS-XXX 2012, Lecture 17 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 Dan Grossman CS-XXX 2012, Lecture 17 11