Administrivia. Existential Types. CIS 500 Software Foundations Fall December 6. Administrivia. Motivation. Motivation

Similar documents
CIS 500 Software Foundations Fall December 6

CIS 500 Software Foundations Fall December 4

Lambda Calculi With Polymorphism

Lambda Calculi With Polymorphism

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

Part III. Chapter 15: Subtyping

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

Lecture 13: Subtyping

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

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

Subsumption. Principle of safe substitution

Part III Chapter 15: Subtyping

What Is Computer Science? The Scientific Study of Computation. Expressing or Describing

Subtyping. Lecture 13 CS 565 3/27/06

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

Programming Languages Fall 2014

CSE 505 Graduate PL. Fall 2013

CIS 500 Software Foundations Fall October 2

COSE212: Programming Languages. Lecture 0 Course Overview

Chapter 22: Type Reconstruction (Type Inference)

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

Resources: The slides of this lecture were derived from [Järvi], with permission of the original author, by copy & x = 1 let x = 1 in...

The Untyped Lambda Calculus

Programming with Math and Logic

Type Systems Winter Semester 2006

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

More Lambda Calculus and Intro to Type Systems

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

COS 320. Compiling Techniques

Simple Unification-based Type Inference for GADTs

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

Second-Order Type Systems

Formal Systems and their Applications

CMSC 330: Organization of Programming Languages

Lecture 15 CIS 341: COMPILERS

Types and Programming Languages. Lecture 6. Normalization, references, and exceptions

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

(Refer Slide Time: 4:00)

Introduction to Axiomatic Semantics

Simply-Typed Lambda Calculus

Operational Semantics. One-Slide Summary. Lecture Outline

The design of a programming language for provably correct programs: success and failure

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

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

The Untyped Lambda Calculus

CIS 500 Software Foundations Fall September 25

Introduction to dependent types in Coq

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

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.

The Untyped Lambda Calculus

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

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

Programming Languages Assignment #7

Lecture 9: Typed Lambda Calculus

Recursive Types and Subtyping

Mutable References. Chapter 1

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

CMSC 330: Organization of Programming Languages

Type Systems. Today. 1. Organizational Matters. 1. Organizational Matters. Lecture 1 Oct. 20th, 2004 Sebastian Maneth. 1. Organizational Matters

CS422 - Programming Language Design

Comp 411 Principles of Programming Languages Lecture 7 Meta-interpreters. Corky Cartwright January 26, 2018

This is already grossly inconvenient in present formalisms. Why do we want to make this convenient? GENERAL GOALS

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

Tracing Ambiguity in GADT Type Inference

Type Checking and Type Inference

Objects as Session-Typed Processes

Typed Lambda Calculus and Exception Handling

CS3110 Spring 2017 Lecture 9 Inductive proofs of specifications

Hoare Logic. COMP2600 Formal Methods for Software Engineering. Rajeev Goré

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

Contents. Chapter 1 SPECIFYING SYNTAX 1

Introduction to Functional Programming in Haskell 1 / 56

Symmetry in Type Theory

More Lambda Calculus and Intro to Type Systems

Assistant for Language Theory. SASyLF: An Educational Proof. Corporation. Microsoft. Key Shin. Workshop on Mechanizing Metatheory

CSc 372. Comparative Programming Languages. 2 : Functional Programming. Department of Computer Science University of Arizona

Reasoning About Programs Panagiotis Manolios

Supplementary Notes on Recursive Types

Z Notation. June 21, 2018

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

Chapter 11 :: Functional Languages

Fundamentals and lambda calculus. Deian Stefan (adopted from my & Edward Yang s CSE242 slides)

Programming Language Pragmatics

Last class. CS Principles of Programming Languages. Introduction. Outline

Higher-Order Intensional Type Analysis. Stephanie Weirich Cornell University

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

The Substitution Model

CMSC 330: Organization of Programming Languages

Topic 3: Propositions as types

Functional Programming. Big Picture. Design of Programming Languages

A Type System for Functional Traversal-Based Aspects

Lecture slides & distribution files:

CS4215 Programming Language Implementation. Martin Henz

Meeting14:Denotations

CSCI-GA Scripting Languages

The Essence of Reynolds

Paradigms of computer programming

λ calculus is inconsistent

Lecture 5 - Axiomatic semantics

7. Introduction to Denotational Semantics. Oscar Nierstrasz

Transcription:

CIS 500 Software Foundations Fall 2006 Administrivia December 6 Administrivia No recitations this week Extra office hours will be posted to the class mailing list Exam: Wednesday, Dec 20, 9 11 Location: Towne 313 (not here!) Coverage: Chapters 1 to 19, 22, and 23 of TAPL, excluding 12 and 15.6, plus reading knowledge of basic OCaml Hints: The exam is extremely likely to include... at least one question that is very similar to a homework problem from the past month at least one problem taken verbatim from a one-star exercise in TAPL at least one problem involving proofs at least one problem from chapter 22 and/or 23 (universal and existential types) but nothing too complicated Existential Types Motivation If universal quantifiers are useful in programming, then what about existential quantifiers? Motivation If universal quantifiers are useful in programming, then what about existential quantifiers? Rough intuition: Terms with universal types are functions from types to terms. Terms with existential types are pairs of a type and a term.

Concrete Intuition Existential types describe simple modules: An existentially typed value is introduced by pairing a type with a term, written {*S,t}. (The star avoids syntactic confusion with ordinary pairs.) A value {*S,t} of type { X,T} is a module with one (hidden) type component and one term component. Example: p = {*Nat, {a=5, f=λx:nat. succ(x)}} has type { X, {a:x, f:x X}} The type component of p is Nat, and the value component is a record containing a field a of type X and a field f of type X X, for some X (namely Nat). The same package p = {*Nat, {a=5, f=λx:nat. succ(x)}} also has type { X, {a:x, f:x Nat}}, since its right-hand component is a record with fields a and f of type X and X Nat, for some X (namely Nat). This example shows that there is no automatic ( best ) way to guess the type of an existential package. The programmer has to say what is intended. We re-use the ascription notation for this: p = {*Nat, {a=5, f=λx:nat. succ(x)}} as { X, {a:x, f:x X}} p1 = {*Nat, {a=5, f=λx:nat. succ(x)}} as { X, {a:x, f:x Nat}} This gives us the introduction rule for existentials: Γ t 2 : [X U]T 2 Γ {*U,t 2 } as { X,T 2 } : { X,T 2 } (T-Pack) Different representations... Note that this rule permits packages with different hidden types to inhabit the same existential type. Example: p2 = {*Nat, 0} as { X,X} p3 = {*Bool, true} as { X,X} Different representations... Note that this rule permits packages with different hidden types to inhabit the same existential type. Example: p2 = {*Nat, 0} as { X,X} p3 = {*Bool, true} as { X,X} More useful example: p4 = {*Nat, {a=0, f=λx:nat. succ(x)}} as { X, {a:x, f:x Nat}} p5 = {*Bool, {a=true, f=λx:bool. 0}} as { X, {a:x, f:x Nat}} Exercise... Here are three more variations on the same theme: p6 = {*Nat, {a=0, f=λx:nat. succ(x)}} as { X, {a:x, f:x X}} p7 = {*Nat, {a=0, f=λx:nat. succ(x)}} as { X, {a:x, f:nat X}} p8 = {*Nat, {a=0, f=λx:nat. succ(x)}} as { X, {a:nat, f:nat Nat}} In what ways are these less useful than p4 and p5? The elimination form for existentials Intuition: If an existential package is like a module, then eliminating (using) such a package should correspond to open or import. I.e., we should be able to use the components of the module, but the identity of the type component should be held abstract. Γ t 1 : { X,T 12 } Γ, X, x:t 12 t 2 : T 2 Γ let {X,x}=t 1 in t 2 : T 2 (T-Unpack) p4 = {*Nat, {a=0, f=λx:nat. succ(x)}} as { X, {a:x, f:x Nat}} p5 = {*Bool, {a=true, f=λx:bool. 0}} as { X, {a:x, f:x Nat}} Example: if p4 = {*Nat, {a=0, f=λx:nat. succ(x)}} as { X,{a:X,f:X Nat}} then let {X,x} = p4 in (x.f x.a) has type Nat (and evaluates to 1).

Abstraction However, if we try to use the a component of p4 as a number, typechecking fails: p4 = {*Nat, {a=0, f=λx:nat. succ(x)}} as { X,{a:X,f:X Nat}} Computation The computation rule for existentials is also straightforward: let {X,x}=({*T 11,v 12 } as T 1 ) in t 2 (E-UnpackPack) [X T 11 ][x v 12 ]t 2 let {X,x} = p4 in (succ x.a) = Error: argument of succ is not a number This failure makes good sense, since we saw that another package with the same existential type as p4 might use Bool or anything else as its representation type. Γ t 1 : { X,T 12 } Γ, X, x:t 12 t 2 : T 2 Γ let {X,x}=t 1 in t 2 : T 2 (T-Unpack) Example: Abstract Data Types counteradt = {*Nat, {new = 1, get = λi:nat. i, inc = λi:nat. succ(i)}} as { Counter, {new: Counter, get: Counter Nat, inc: Counter Counter}}; let {Counter,counter} = counteradt in counter.get (counter.inc counter.new); Representation independence We can substitute another implementation of counters without affecting the code that uses counters: counteradt = {*{x:nat}, {new = {x=1}, get = λi:{x:nat}. i.x, inc = λi:{x:nat}. {x=succ(i.x)}}} as { Counter, {new: Counter, get: Counter Nat, inc: Counter Counter}}; Cascaded ADTs We can use the counter ADT to define new ADTs that use counters in their internal representations: let {Counter,counter} = counteradt in let {FlipFlop,flipflop} = {*Counter, {new = counter.new, read = λc:counter. iseven (counter.get c), toggle = λc:counter. counter.inc c, reset = λc:counter. counter.new}} as { FlipFlop, {new: FlipFlop, read: FlipFlop Bool, toggle: FlipFlop FlipFlop, reset: FlipFlop FlipFlop}} in Existential Objects Counter = { X, {state:x, methods: {get:x Nat, inc:x X}}}; c = {*Nat, {state = 5, methods = {get = λx:nat. x, inc = λx:nat. succ(x)}}} as Counter; let {X,body} = c in body.methods.get(body.state); flipflop.read (flipflop.toggle (flipflop.toggle flipflop.new));

Existential objects: invoking methods More generally, we can define a little function that sends the get message to any counter: sendget = λc:counter. let {X,body} = c in body.methods.get(body.state); Invoking the inc method of a counter object is a little more complicated. If we simply do the same as for get, the typechecker complains let {X,body} = c in body.methods.inc(body.state); = Error: Scoping error! because the type variable X appears free in the type of the body of the let. Indeed, what we ve written doesn t make intuitive sense either, since the result of the inc method is a bare internal state, not an object. To satisfy both the typechecker and our informal understanding of what invoking inc should do, we must take this fresh internal state and repackage it as a counter object, using the same record of methods and the same internal state type as in the original object: c1 = let {X,body} = c in {*X, {state = body.methods.inc(body.state), methods = body.methods}} as Counter; More generally, to send the inc message to a counter, we can write: sendinc = λc:counter. let {X,body} = c in {*X, {state = body.methods.inc(body.state), methods = body.methods}} as Counter; Objects vs. ADTs The examples of ADTs and objects that we have seen in the past few slides offer a revealing way to think about the differences between classical ADTs and objects. Both can be represented using existentials With ADTs, each existential package is opened as early as possible (at creation time) With objects, the existential package is opened as late as possible (at method invocation time) These differences in style give rise to the well-known pragmatic differences between ADTs and objects: ADTs support binary operations objects support multiple representations A full-blown existential object model What we ve done so far is to give an account of object-style encapsulation in terms of existential types. To give a full model of all the core OO features we have discussed before, some significant work is required. In particular, we must add: subtyping (and bounded quantification ) type operators ( higher-order subtyping ) Recap... Where we ve been

What is software foundations? Software foundations (a.k.a. theory of programming languages ) is the study of the meaning of programs. A main goal is finding ways to describe program behaviors that are both precise and abstract. Why study software foundations? To be able to prove specific facts about particular programs (i.e., program verification) Important in some domains (safety-critical systems, hardware design, inner loops of key algorithms,...), but currently very difficult and expensive. We have not said much about this in the course. To develop intuitions for informal reasoning about programs To prove general facts about all the programs in a given programming language (e.g., safety or security properties) To understand language features (and their interactions) deeply and develop principles for better language design PL as the materials science of computer science... What I hope you got out of the course A more sophisticated perspective on programs, programming languages, and the activity of programming How to view programs and whole languages as formal, mathematical objects How to make and prove rigorous claims about them Detailed study of a range of basic language features Deep intuitions about key language properties such as type safety Familiarity with today s best tools for language design, description, and analysis Overview In this course, we concentrated on operational semantics and type systems. Part O: Background A taste of OCaml Functional programming style Part I: Basics Inductive definitions and proofs Operational semantics The lambda-calculus Evaluator implementation in OCaml Programming languages are everywhere. Most software designers are at some point language designers! Part II: Type systems Simple types Type safety preservation and progress Formal description of a variety of basic language features (records, variants, lists, casting,...) References Exceptions Subtyping Metatheory of subtyping (subtyping and typechecking algorithms) Polymorphism (universal and existential types) Part III: Object-oriented features (case studies) A simple imperative object model An direct formalization of core Java What next?

The rest of TAPL Several more core topics are covered in the second half of TAPL. Recursive types (including a rigorous treatment of induction and co-induction) More on parametric polymorphism (universal and existential types) Bounded quantification Refinement of the imperative object model ML-style type inference Type operators Higher-order bounded quantification A purely functional object model The Research Literature With this course under your belt, you are ready to directly address research papers in programming languages. This is a big area, and each sub-area has its own special techniques and notations, but you now have pretty much all the basic intuitions needed to understand these on your own. The End