CS 4110 Programming Languages & Logics. Lecture 28 Recursive Types

Similar documents
CS 4110 Programming Languages & Logics. Lecture 27 Recursive Types

Lecture Notes on Data Representation

1 Introduction. 3 Syntax

CS 6110 S11 Lecture 25 Typed λ-calculus 6 April 2011

CSE-321 Programming Languages 2010 Final

Lecture 14: Recursive Types

Programming Languages Lecture 15: Recursive Types & Subtyping

CSE-321 Programming Languages 2011 Final

Programming Languages Lecture 14: Sum, Product, Recursive Types

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

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

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

Recursive Types and Subtyping

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

Supplementary Notes on Recursive Types

Inductive datatypes in HOL. lessons learned in Formal-Logic Engineering

Theorem Proving Principles, Techniques, Applications Recursion

Denotational Semantics. Domain Theory

Lambda Calculus. Lecture 4 CS /26/10

Quick announcement. Midterm date is Wednesday Oct 24, 11-12pm.

Recursive Types and Subtyping

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

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

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

Derivation for the Necessity of Recursive Types and its Basic Usage

CSE-321 Programming Languages 2012 Midterm

CSE-321 Programming Languages 2010 Midterm

Type Systems Winter Semester 2006

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

The Lambda Calculus. 27 September. Fall Software Foundations CIS 500. The lambda-calculus. Announcements

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

Concepts of programming languages

λ calculus is inconsistent

1 Scope, Bound and Free Occurrences, Closed Terms

Lambda Calculus. Type Systems, Lectures 3. Jevgeni Kabanov Tartu,

CIS 500 Software Foundations Fall September 25

Lecture #23: Conversion and Type Inference

Lambda Calculus and Extensions as Foundation of Functional Programming

CSE505, Fall 2012, Midterm Examination October 30, 2012

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

CMSC 330: Organization of Programming Languages

Types and Programming Languages. Lecture 8. Recursive type

CIS 500 Software Foundations Midterm I

Structural polymorphism in Generic Haskell

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

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

Lecture #13: Type Inference and Unification. Typing In the Language ML. Type Inference. Doing Type Inference

Variables. Substitution

Introduction to Lambda Calculus. Lecture 7 CS /08/09

Overview. A normal-order language. Strictness. Recursion. Infinite data structures. Direct denotational semantics. Transition semantics

Lecture Notes on Program Equivalence

Harvard School of Engineering and Applied Sciences Computer Science 152

Programming Language Concepts: Lecture 19

Lecture Note: Types. 1 Introduction 2. 2 Simple Types 3. 3 Type Soundness 6. 4 Recursive Types Subtyping 17

CMSC 330: Organization of Programming Languages

Introduction to Lambda Calculus. Lecture 5 CS 565 1/24/08

CSE-321 Programming Languages 2014 Final

CSE 505: Concepts of Programming Languages

The Untyped Lambda Calculus

References and Exceptions. CS 565 Lecture 14 4/1/08

HOL DEFINING HIGHER ORDER LOGIC LAST TIME ON HOL CONTENT. Slide 3. Slide 1. Slide 4. Slide 2 WHAT IS HIGHER ORDER LOGIC? 2 LAST TIME ON HOL 1

CS 6110 S11 Lecture 12 Naming and Scope 21 February 2011

Introduction to the λ-calculus

CMSC 336: Type Systems for Programming Languages Lecture 4: Programming in the Lambda Calculus Acar & Ahmed 22 January 2008.

Typed Compilation Against Non-Manifest Base Classes

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

M. Snyder, George Mason University LAMBDA CALCULUS. (untyped)

ADT. Typing. Recursive Types. Java. Preliminary: syntax, operational semantics. Untyped lambda calculus. Simply typed lambda calculus

Mutable References. Chapter 1

The Untyped Lambda Calculus

Calculus of Inductive Constructions

4.6 Recursive Types. 4.6 Recursive Types 105

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

Logical Verification Course Notes. Femke van Raamsdonk Vrije Universiteit Amsterdam

The Typed λ Calculus and Type Inferencing in ML

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

Exercise 1 ( = 24 points)

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

CS 6110 S14 Lecture 38 Abstract Interpretation 30 April 2014

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

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

Shell CSCE 314 TAMU. Higher Order Functions

CSCI-GA Scripting Languages

Introduction to the Lambda Calculus

Lecture 5: The Untyped λ-calculus

Less naive type theory

Adding GADTs to OCaml the direct approach

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

Pattern Matching and Abstract Data Types

CIS 500 Software Foundations Midterm I Answer key October 8, 2003

Preuves Interactives et Applications

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

Type Checking and Type Inference

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

If a program is well-typed, then a type can be inferred. For example, consider the program

CMSC 330: Organization of Programming Languages

(Refer Slide Time: 4:00)

Note that in this definition, n + m denotes the syntactic expression with three symbols n, +, and m, not to the number that is the sum of n and m.

Exercise 1 (2+2+2 points)

Transcription:

CS 4110 Programming Languages & Logics Lecture 28 Recursive Types 7 November 2014

Announcements 2 Foster office hours 11-12pm Guest lecture by Fran on Monday

Recursive Types 3 Many languages support recursive data types Java class Tree { Tree leftchild, rightchild; int data; }

Recursive Types 3 Many languages support recursive data types Java OCaml class Tree { Tree leftchild, rightchild; int data; } type tree = Leaf Node of tree * tree * int

Recursive Types 3 Many languages support recursive data types Java OCaml class Tree { Tree leftchild, rightchild; int data; } type tree = Leaf Node of tree * tree * int Simple Types tree = unit + int tree tree

Recursive Type Equations 4 We would like the type tree to satisfy tree = unit + int tree tree

Recursive Type Equations 4 We would like the type tree to satisfy tree = unit + int tree tree In other words, we would like tree to be a solution of the equation α = unit + int α α However, no such solution exists with the types we have so far...

Unwinding Equations 5 Unwinding the equation for tree, we have: α = unit + int α α

Unwinding Equations 5 Unwinding the equation for tree, we have: α = unit + int α α = unit + int (unit + int α α) (unit + int α α)

Unwinding Equations 5 Unwinding the equation for tree, we have: α = unit + int α α = unit + int (unit + int α α) (unit + int α α) = unit + int (unit + int (unit + int α α) (unit + int α α)) (unit + int (unit + int α α) (unit + int α α))

Unwinding Equations 5 Unwinding the equation for tree, we have: α = unit + int α α = unit + int (unit + int α α) (unit + int α α) = unit + int (unit + int (unit + int α α) (unit + int α α)) (unit + int (unit + int α α) (unit + int α α)) =

Unwinding Equations Unwinding the equation for tree, we have: α = unit + int α α = unit + int (unit + int α α) (unit + int α α) = unit + int (unit + int (unit + int α α) (unit + int α α)) (unit + int (unit + int α α) (unit + int α α)) = At each level, we have a finite type with variables α and we obtain the next level by substituting the right-hand side for α 5

Infinite Types 6 If we take the limit of this process, we have an infinite tree We can think of this as an infinite labeled graph whose nodes are labeled with the type constructors, +, int, and unit. This infinite tree is a solution of our equation, and this is what we take as the type tree. More generally, over standard type constructors such as,, +, unit, and int, we can form the set of (finite) types inductively in the usual way

Example 7 For example, the type int int int can be viewed as the labeled tree int int int

Example 8 A (finite or infinite) expression with only finitely many subexpressions (up to isomorphism) is called regular For example, the infinite type int int int... is regular, since it has only two subexpressions up to isomorphism, namely itself and int

µ Types 9 We can specify infinite solutions to systems of equations using a finite syntax involving the fixpoint type constructor µ

µ Types 9 We can specify infinite solutions to systems of equations using a finite syntax involving the fixpoint type constructor µ Given an equation α = τ such that the right-hand side is not α, there is a unique solution, which is a finite or infinite regular tree

µ Types 9 We can specify infinite solutions to systems of equations using a finite syntax involving the fixpoint type constructor µ Given an equation α = τ such that the right-hand side is not α, there is a unique solution, which is a finite or infinite regular tree The solution will be infinite if α occurs in τ and will be finite (in fact it will just be τ) if α does not occur in τ

µ Types 9 We can specify infinite solutions to systems of equations using a finite syntax involving the fixpoint type constructor µ Given an equation α = τ such that the right-hand side is not α, there is a unique solution, which is a finite or infinite regular tree The solution will be infinite if α occurs in τ and will be finite (in fact it will just be τ) if α does not occur in τ We denote this unique solution by µα. τ.

µ Types 9 We can specify infinite solutions to systems of equations using a finite syntax involving the fixpoint type constructor µ Given an equation α = τ such that the right-hand side is not α, there is a unique solution, which is a finite or infinite regular tree The solution will be infinite if α occurs in τ and will be finite (in fact it will just be τ) if α does not occur in τ We denote this unique solution by µα. τ. Note that µ acts as a binding operator in type expressions

Example 10 To get a tree type satisfying our original equation, we can define tree µα. unit + int α α....and it is straightforward to extend this to mutually recursive types

Static Semantics (Equirecursive) 11 In equirecursive types we take a recursive type to be equal to its (potentially infinite) unfolding Formally, since µα. τ is a solution to α = τ, we have µα. τ = τ{µα. τ/α}.

Static Semantics (Equirecursive) In equirecursive types we take a recursive type to be equal to its (potentially infinite) unfolding Formally, since µα. τ is a solution to α = τ, we have µα. τ = τ{µα. τ/α}....and so the typing rules are simple: Γ e : τ{µα. τ/α} Γ e : µα. τ µ-intro Γ e : µα. τ Γ e : τ{µα. τ/α} µ-elim Equivalently, we can just allow substitution of equals for equals 11

Isorecursive Types 12 Another approach is to work with isorecursive types.

Isorecursive Types 12 Another approach is to work with isorecursive types. Here we do not have any infinite types, but rather the expression µα. τ is itself a type that is distinct, but isomorphic to τ{µα. τ/α}

Isorecursive Types 12 Another approach is to work with isorecursive types. Here we do not have any infinite types, but rather the expression µα. τ is itself a type that is distinct, but isomorphic to τ{µα. τ/α} The step of substituting µα. τ for α in τ is called unfolding, and the reverse operation is called folding

Isorecursive Types 12 Another approach is to work with isorecursive types. Here we do not have any infinite types, but rather the expression µα. τ is itself a type that is distinct, but isomorphic to τ{µα. τ/α} The step of substituting µα. τ for α in τ is called unfolding, and the reverse operation is called folding The conversion of elements between these two types is accomplished by explicit fold and unfold operations. unfold µα. τ : µα. τ τ{µα. τ/α} fold µα. τ : τ{µα. τ/α} µα. τ

Static Semantics (Isorecursive) 13 In the isorecursive view, the typing rules consist of a pair of introduction and elimination rules for µ-types that explicitly mention fold and unfold: Γ e : τ{µα. τ/α} Γ fold e : µα. τ µ-intro Γ e : µα. τ Γ unfold e : τ{µα. τ/α} µ-elim

Dynamic Semantics 14 We also need to augment the operational semantics: unfold (fold e) e Intuitively, to access data in a recursive type µα. τ, we need to unfold it first; but the only way that values of type µα. τ could have been created in the first place is via a fold

Example 15 Suppose we want to write a program to add a list of numbers The list type is a recursive type, which we can define as intlist µα. unit + int α.

Example 15 Suppose we want to write a program to add a list of numbers The list type is a recursive type, which we can define as intlist µα. unit + int α. Now suppose we want to add up the elements of an intlist This will be a recursive function, so we would need to take a fixpoint let sum = fix (λf:intlist intlist λl:intlist. case unfold l of (λu : unit. 0) (λp : int intlist. (#1 p) + f (#2 p)))

Encoding Numbers 16 Now that we have recursive types, we no longer need to take int as primitive, but we can define it as a recursive type

Encoding Numbers 16 Now that we have recursive types, we no longer need to take int as primitive, but we can define it as a recursive type A natural number is either 0 or a successor of a natural number:

Encoding Numbers 16 Now that we have recursive types, we no longer need to take int as primitive, but we can define it as a recursive type A natural number is either 0 or a successor of a natural number: nat µα. unit + α

Encoding Numbers 16 Now that we have recursive types, we no longer need to take int as primitive, but we can define it as a recursive type A natural number is either 0 or a successor of a natural number: nat µα. unit + α 0 fold (inl nat ())

Encoding Numbers 16 Now that we have recursive types, we no longer need to take int as primitive, but we can define it as a recursive type A natural number is either 0 or a successor of a natural number: nat µα. unit + α 0 fold (inl nat ()) 1 fold (inr nat 0)

Encoding Numbers 16 Now that we have recursive types, we no longer need to take int as primitive, but we can define it as a recursive type A natural number is either 0 or a successor of a natural number: nat µα. unit + α 0 fold (inl nat ()) 1 fold (inr nat 0) 2 fold (inr nat 1),

Encoding Numbers 16 Now that we have recursive types, we no longer need to take int as primitive, but we can define it as a recursive type A natural number is either 0 or a successor of a natural number: nat µα. unit + α 0 fold (inl nat ()) 1 fold (inr nat 0) 2 fold (inr nat 1), The successor function is: (λx : nat. fold (inr nat x)) : nat nat.

Self-Application and Ω 17 Recall Ω defined as: ω λx. xx Ω ω ω. We can now give these terms recursive types!

Self-Application and Ω 17 Recall Ω defined as: ω λx. xx Ω ω ω. We can now give these terms recursive types! x is used as a function, so it must have a type, say σ τ

Self-Application and Ω 17 Recall Ω defined as: ω λx. xx Ω ω ω. We can now give these terms recursive types! x is used as a function, so it must have a type, say σ τ But x is applied to itself, so it must also have type σ

Self-Application and Ω 17 Recall Ω defined as: ω λx. xx Ω ω ω. We can now give these terms recursive types! x is used as a function, so it must have a type, say σ τ But x is applied to itself, so it must also have type σ Hence, the type of x must satisfy the equation σ = σ τ

Self-Application and Ω 18 Putting all these pieces together, the fully typed ω term is: ω (λx : µα. (α τ). (unfold x) x) : (µα. (α τ)) τ.

Self-Application and Ω 18 Putting all these pieces together, the fully typed ω term is: ω (λx : µα. (α τ). (unfold x) x) : (µα. (α τ)) τ. We can also write ω in OCaml: # type u = Fold of (u -> u);; type u = Fold of (u -> u) # let omega = fun x -> match x with Fold f -> f x;; val omega : u -> u = <fun> # omega (Fold omega);;...runs forever until you hit control-c

Encoding λ-calculus 19 With recursive types, we can type everything in the untyped lambda calculus!

Encoding λ-calculus 19 With recursive types, we can type everything in the untyped lambda calculus! Every λ-term can be applied as a function to any other λ-term, which leads to the type: U µα. α α

Encoding λ-calculus With recursive types, we can type everything in the untyped lambda calculus! Every λ-term can be applied as a function to any other λ-term, which leads to the type: U µα. α α The full translation is as follows [[x]] x [[e 0 e 1 ]] (unfold [[e 0 ]]) [[e 1 ]] [[λx. e]] fold λx : U. [[e]]. Note that every untyped term maps to a term of type U. 19