Simon Peyton Jones, Stephanie Weirich, Richard Eisenberg, Dimitrios Vytiniotis Microsoft Research University of Pennsylvania April 2016.

Slides:



Advertisements
Similar presentations
Types and Programming Languages Lecture 13 Simon Gay Department of Computing Science University of Glasgow 2006/07.
Advertisements

Functional Programming Lecture 10 - type checking.
Static Contract Checking for Haskell Dana N. Xu University of Cambridge Ph.D. Supervisor: Simon Peyton Jones Microsoft Research Cambridge.
Tom Schrijvers K.U.Leuven, Belgium with Manuel Chakravarty, Martin Sulzmann and Simon Peyton Jones.
Sequence of characters Generalized form Expresses Pattern of strings in a Generalized notation.
Reconciling OO and Haskell-Style Overloading Mark Shields Simon Peyton Jones Microsoft Research Cambridge
Let should not be generalized Dimitrios Vytiniotis, Simon Peyton Jones Microsoft Research, Cambridge TLDI’1 0, Madrid, January 2010 Tom Schrijvers K.U.
Extended Static Checking for Haskell (ESC/Haskell) Dana N. Xu University of Cambridge advised by Simon Peyton Jones Microsoft Research, Cambridge.
ML Datatypes.1 Standard ML Data types. ML Datatypes.2 Concrete Datatypes  The datatype declaration creates new types  These are concrete data types,
Kathleen Fisher cs242 Reading: “A history of Haskell: Being lazy with class”,A history of Haskell: Being lazy with class Section 6.4 and Section 7 “Monads.
Type checking © Marcelo d’Amorim 2010.
© M. Winter COSC 4P41 – Functional Programming Abstract data types (ADTs) An ADT is a data type together with some functions to manipulate elements.
The Fundamental Rule for Testing Methods Every method should be tested in a program in which every other method in the testing program has already been.
Type inference and modern type systems Stephanie Weirich University of Pennsylvania.
CSE 341, Winter Type Systems Terms to learn about types: –Type –Type system –Statically typed language –Dynamically typed language –Type error –Strongly.
CATCH: Case and Termination Checker for Haskell Neil Mitchell (Supervised by Colin Runciman)
Lecture 11: Polymorphism and Dynamic Binding Polymorphism Static (compile-time) binding Dynamic (run-time) binding.
A Lightning Tour of Haskell Lecture 1, Designing and Using Combinators John Hughes.
Comp 205: Comparative Programming Languages User-Defined Types Enumerated types Parameterised types Recursive types Lecture notes, exercises, etc., can.
Slides prepared by Rose Williams, Binghamton University Chapter 5 Defining Classes II.
Generative type abstraction and type-level computation (Wrestling with System FC) Stephanie Weirich, Steve Zdancewic University of Pennsylvania Dimitrios.
Programming in Scala Chapter 1. Scala: both object-oriented and functional Scala blends –object-oriented and –functional programming in a –statically.
Type Inference: CIS Seminar, 11/3/2009 Type inference: Inside the Type Checker. A presentation by: Daniel Tuck.
Generic Programming with Dependent Types Stephanie Weirich University of Pennsylvania.
Introduction to Object Oriented Programming. Object Oriented Programming Technique used to develop programs revolving around the real world entities In.
Operators, Functions and Modules1 Pattern Matching & Recursion.
Scrap Your Boilerplate /~simonpj/papers/hmap/
CS321 Functional Programming 2 © JAS Type Checking Polymorphism in Haskell is implicit. ie the system can derive the types of all objects. This.
Announcements  If you need more review of Java…  I have lots of good resources – talk to me  Use “Additional Help” link on webpage  Weekly assignments.
Constructors CMSC 202. Object Creation Objects are created by using the operator new in statements such as… The following expression invokes a special.
Sound Haskell Dana N. Xu University of Cambridge Joint work with Simon Peyton Jones Microsoft Research Cambridge Koen Claessen Chalmers University of Technology.
1 Functional Programming Lecture 6 - Algebraic Data Types.
Object Oriented Programming
Lee CSCE 314 TAMU 1 CSCE 314 Programming Languages Interactive Programs: I/O and Monads Dr. Hyunyoung Lee.
First Order Haskell Neil Mitchell York University λ.
Scrap your boilerplate: generic programming in Haskell Ralf Lämmel, Vrije University Simon Peyton Jones, Microsoft Research.
Advanced Functional Programming Tim Sheard 1 Lecture 17 Advanced Functional Programming Tim Sheard Oregon Graduate Institute of Science & Technology Lecture:
1 Static Contract Checking for Haskell Dana N. Xu University of Cambridge Joint work with Simon Peyton Jones Microsoft Research Cambridge Koen Claessen.
C H A P T E R T H R E E Type Systems and Semantics Programming Languages – Principles and Paradigms by Allen Tucker, Robert Noonan.
Today’s lecture Review chapter 5 go over exercises.
Shifting the Blame A blame calculus with delimited control Taro Sekiyama* Atsushi Igarashi Soichiro Ueda Kyoto University Gradual typing.
1 C# - Inheritance and Polymorphism. 2 1.Inheritance 2.Implementing Inheritance in C# 3.Constructor calls in Inheritance 4.Protected Access Modifier 5.The.
Author: DoanNX Time: 45’.  OOP concepts  OOP in Java.
Functional Programming Lecture 3 - Lists Muffy Calder.
Simon Peyton Jones Microsoft Research September 2015.
Haskell With Go Faster Stripes Neil Mitchell. Catch: Project Overview Catch checks that a Haskell program won’t raise a pattern match error head [] =
GADTs meet their match George Karachalias(Ghent University, Belgium) Tom Schrijvers (KU Leuven, Belgium) Dimitrios Vytiniotis(Microsoft Research Cambridge,
Heath Carroll Bill Hanczaryk Rich Porter.  A Theory of Type Polymorphism in Programming ◦ Robin Milner (1977)  Milner credited with introducing the.
Concurrency 2 CS 2110 – Spring 2016.
Types CSCE 314 Spring 2016.
Haskell Chapter 2.
A lightening tour in 45 minutes
Data Modeling II XML Schema & JAXB Marc Dumontier May 4, 2004
Type Systems Terms to learn about types: Related concepts: Type
Continuing Chapter 11 Inheritance and Polymorphism
Microsoft Research University of Pennsylvania
Advanced Functional Programming
Extended Static Checking for Haskell (ESC/Haskell)
CSE 341 Section 5 Winter 2018.
Generic Classes and Methods
Advanced Functional Programming
Java’s Central Casting
CSEP505: Programming Languages Lecture 9: Haskell Typeclasses and Monads; Dan Grossman Autumn 2016.
Type Systems Terms to learn about types: Related concepts: Type
Subtype Substitution Principle
PROGRAMMING IN HASKELL
Static Contract Checking for Haskell
CMSC 202 Constructors Version 9/10.
Presentation transcript:

Simon Peyton Jones, Stephanie Weirich, Richard Eisenberg, Dimitrios Vytiniotis Microsoft Research University of Pennsylvania April 2016

A core calculus for Java Boiling Java down Java reduced Featherlite Java The essence of Java The core of Java Essential OOP

A core calculus for Java Boiling Java down Java reduced Featherlite Java The essence of Java The core of Java Essential OOP

A core calculus for Java Boiling Java down Java reduced Featherlite Java The essence of Java The core of Java Essential OOP Featherweight Java

All programs Programs that work Programs that are well typed Zone of Abysmal Pain

All programs Programs that work Programs that are well typed Smaller Zone of Abysmal Pain

Let’s implement this in Haskell, as a state transformer newSTRef :: a -> ST (STRef a) readSTRef :: STRef a -> ST a writeSTRef :: STRef a -> a -> ST () newtype ST a = MkST (Store -> (a,Store)) But what is a “Store”??

But what is a “Store”? It maps keys (STRefs) to values of many different types. Attempt 1: use Data.Map newtype STRef a = MkSTRef Int type Store = Map Int ???? lookupStore :: STRef s a -> Store -> Maybe a

Attempt 2: we need dynamic types, even in a statically typed language newtype STRef a = MkSTRef Int type Store = Map Int Dynamic fromDynamic :: Dynamic -> Maybe a lookupStore :: STRef a -> Store -> Maybe a lookupStore (MkSTRef key) store = case Data.Map.lookup key store of Nothing -> Nothing Just d -> fromDynamic d

Attempt 2: we need dynamic types, even in a statically typed language newtype STRef a = MkSTRef Int type Store = Map Int Dynamic fromDynamic :: Dynamic -> Maybe a lookupStore :: STRef s a -> Store -> Maybe a lookupStore (MkSTRef key) store = case Data.Map.lookup store key of Nothing -> Nothing Just d -> fromDynamic d Too polymorphic! See “Theorems for Free”

Attempt 3: enumerate the types we need data Dynamic = DInt Int | DBool Bool | DPair Dynamic Dynamic | …etc… fromDynInt :: Dynamic -> Maybe Int fromDynBool :: Dynamic -> Maybe Bool class Dyn a where fromDynamic :: Dynamic -> Maybe a lookupStore :: Dyn a => STRef a -> Store -> Maybe a lookupStore (MkSTRef key) store = case Data.Map.lookup store key of Nothing -> Nothing Just d -> fromDynamic d

Attempt 3: enumerate the types we need data Dynamic = DInt Int | DBool Bool | DPair Dynamic Dynamic | …etc…  Non-starter because it requires a closed world We want readSTRef :: STRef a -> ST a to work for any type ‘a’, including new ones  Also: converting to and fro takes a deep traversal

A Dynamic should consist of  The value itself  A runtime representation of its type data Dynamic where Dyn :: TypeRep a -> a -> Dynamic Runtime representation of the type of the value The value itself A type-indexed data structure

class Typeable a where typeRep :: TypeRep a toDynamic :: Typeable a => a -> Dynamic toDynamic x = Dyn typeRep x data Dynamic where Dyn :: TypeRep a -> a -> Dynamic  No deep traversal  Instances of Typeable are built in data Wurble a = MkWurble a | … -- Implicitly you get -- instance Typeable a => Typeable (Wurble a)

class Typeable a where typeRep :: TypeRep a toDynamic :: Typeable a => a -> Dynamic toDynamic x = Dyn typeRep x data Wurble a = MkWurble a | … -- Implicitly you get -- instance Typeable a => Typeable (Wurble a) newtype Typeable a = MkT (TypeRep a) toDynamic :: Typeable a -> a -> Dynamic toDynamic (MkT tr) x = Dyn tr x $tWurble :: Typeable a -> Typeable (Wurble a) $tWurble (MkT tra) = MkT (mkTrApp “Wurble” [tra])

data Dynamic where Dyn :: TypeRep a -> a -> Dynamic fromDynamic ::  b. Typeable b => Dynamic -> Maybe b fromDynamic (Dyn (ra :: TypeRep a) (x::a)) = let rb = typeRep :: TypeRep b in case ra == rb of True -> Just x False -> Nothing

data Dynamic where Dyn :: TypeRep a -> a -> Dynamic fromDynamic ::  b. Typeable b => Dynamic -> Maybe b fromDynamic (Dyn (ra :: TypeRep a)) (x::a) = let rb = typeRep :: TypeRep b in case ra == rb of True -> Just x False -> Nothing Type error 2 Just x :: Maybe a, but we need Maybe b Type error 1 ra :: TypeRep a but rb :: TypeRep b

eqT :: TypeRep a -> TypeRep b -> Maybe (a :=: b) data a :=: b where Refl :: a :=: a fromDynamic ::  b. Typeable b => Dynamic -> Maybe b fromDynamic (Dyn (ra :: TypeRep a)) (x::a) = let rb = typeRep :: TypeRep b in case ra `eqT` rb of Just Refl -> Just x Nothing -> Nothing Fix error 2 In here we know that a ~ b Fix error 1 compares TypeReps with different indices Refl ::  ab. (a~b) => a :=: b

eqT :: TypeRep a -> TypeRep b -> Maybe (a :=: b) data a :=: b where Refl :: a :=: a fromDynamic ::  b. Typeable b => Dynamic -> Maybe b fromDynamic (Dyn (ra :: TypeRep a)) (x::a) = do { Refl <- ra `eqT` (typeRep :: TypeRep b) ; return x } Use do-notation (convenience only)

ST library Store Dynamic, fromDynamic, toDynamic Data.Map TypeRep a, Typeable a eqT :: TypeRep a -> TypeRep b -> Maybe (a :=: b) Type- safe Trusted code base  Type-safe reflection  Small trusted code base  Smaller, more re-usable primitive than Dynamic

dynHead :: Dynamic -> Maybe Dynamic Return Nothing if the argument Dynamic turns out not to be a list

dynHead :: Dynamic -> Maybe Dynamic dynHead (Dyn (rxs :: TypeRep txs) (xs :: txs)) | …txs looks like [tx]… …rxs looks like [rx]… = Just (Dyn rx (head xs)) | otherwise = Nothing

dynHead :: Dynamic -> Maybe Dynamic dynHead (Dyn (rxs :: TypeRep txs) (xs :: txs)) | …txs looks like [tx]… …rxs looks like [rx]… = Just (Dyn rx (head xs)) | otherwise = Nothing This should be [tx] but it’s actually txs

dynHead :: Dynamic -> Maybe Dynamic dynHead (Dyn (rxs :: TypeRep txs) (xs :: txs)) = do { App rl rx <- splitApp rxs ; Refl <- rl `eqT` (typeRep :: TypeRep []) ; return (Dyn rx (head xs)) } Decompose rxs into (rl rx) Check that rl = []

dynHead :: Dynamic -> Maybe Dynamic dynHead (Dyn (rxs :: TypeRep txs) (xs :: txs)) = do { App rl rx <- splitApp rxs ; Refl <- rl `eqT` (typeRep :: TypeRep []) ; return (Dyn rx (head xs)) } data AppResult t where App :: TypeRep a -> TypeRep b -> TypeRep (a b) splitApp :: TypeRep t -> Maybe (AppResult t)

dynHead :: Dynamic -> Maybe Dynamic dynHead (Dyn (rxs :: TypeRep txs) (xs :: txs)) = do { App rl rx <- splitApp rxs ; Refl <- rl `eqT` (typeRep :: TypeRep []) ; return (Dyn rx (head xs)) } Representation of the list type constructor TypeRep ::  k. k -> * Argument can be of any kind

data AppResult t where App :: TypeRep a -> TypeRep b -> TypeRep (a b) App ::  kr kb (r::kr) (a::kb->kr) (b::kb). (r ~ a b) => TypeRep a -> TypeRep b -> TypeRep r dynHead :: Dynamic -> Maybe Dynamic dynHead (Dyn (rxs :: TypeRep txs) (xs :: txs)) = do { App rl rx <- splitApp rxs ; Refl <- rl `eqT` (typeRep :: TypeRep []) ; return (Dyn rx (head xs)) }

App ::  kr kb (r::kr) (a::kb->kr) (b::kb). (r ~ a b) => TypeRep a -> TypeRep b -> TypeRep r dynHead :: Dynamic -> Maybe Dynamic dynHead (Dyn (rxs :: TypeRep txs) (xs :: txs)) = do { App rl rx <- splitApp rxs ; Refl <- rl `eqT` (typeRep :: TypeRep []) ; return (Dyn rx (head xs)) } rl :: TypeRep (a :: kb->*) TypeRep ([] :: *->*)

App ::  kr kb (r::kr) (a::kb->kr) (b::kb). (r ~ a b) => TypeRep a -> TypeRep b -> TypeRep r dynHead :: Dynamic -> Maybe Dynamic dynHead (Dyn (rxs :: TypeRep txs) (xs :: txs)) = do { App rl rx <- splitApp rxs ; Refl <- rl `eqT` (typeRep :: TypeRep []) ; return (Dyn rx (head xs)) } rl :: TypeRep (a :: kb->*) TypeRep ([] :: *->*) Conclusion: eqT must be herero-kinded

eqT ::  k1 k1 (a::k1) (b::k2). TypeRep a -> TypeRep b -> Maybe (a :=: b) data a :=: b where Refl :: a :=: a Refl ::  k1 k2 (a::k1) (b::k2). (k1 ~ k2, a ~ b) => a :=: b a and b can have different kinds Matching against Refl gives us a kind equality as well as a type equality

 Type-safe reflection, with extensible dynamic types, and a small trusted code base  Requires some Heavy Duty Type Artillery  Type classes  GADTs and local type equalities  Kind polymorphism  Kind-heterogeneous type equalities  Local kind equalities  Type support implemented in GHC 8.0 TypeRep library changes in GHC 8.2