Advanced Features of Type Systems Concepts of Programming Languages—CoPL ’15 Sebastian Hungerecker Institute for Software Engineering and Programming Languages February 8, 2016 Sebastian Hungerecker February 8, 2016 1
Introduction ◮ Type systems turn wrong behavior into errors ◮ Static type systems turn run-time into compile-time errors ◮ Advanced features catch even more errors at compile time Sebastian Hungerecker February 8, 2016 2
Topics Dependent Types Refinement Types Uniqueness Types Sebastian Hungerecker February 8, 2016 3
Dependent Types Types depend on values. data Foo: Int -> Type where ... baz: (bar: Int) -> Foo bar ⇒ More information about types ⇒ More properties can be expressed For example: Index out of bounds Sebastian Hungerecker February 8, 2016 4
ADT in Idris data Nat : Type where Z : Nat S : Nat -> Nat Usage i: Nat = S (S (S Z)) Z = 0 S Z = 1 -- with more sugar: S (S Z) = 2 i: Nat = 3 ... Sebastian Hungerecker February 8, 2016 5
Dependent Types in Idris data Vect : Nat -> Type -> Type where Nil : Vect Z a (::) : a -> Vect n a -> Vect (S n) a Usage myVect: Vect 3 Int = 1 :: 2 :: 3 :: Nil --> compiles fine myVect: Vect 2 Int = 1 :: 2 :: 3 :: Nil --> compile error Sebastian Hungerecker February 8, 2016 6
Example: Sequential Vector ( ι Function) iotaHelper : (n: Nat) -> Vect n Nat iotaHelper Z = Nil iotaHelper (S m) = (S m) :: iotaHelper m iota : (n: Nat) -> Vect n Nat iota n = reverse (iotaHelper n) Usage iota 5 --> (1 :: 2 :: 3 :: 4 :: 5 :: Nil): Vect 5 Nat Sebastian Hungerecker February 8, 2016 7
Static Range Checking of Indices data Fin : Nat -> Type where FZ : {n: Nat} -> Fin (S n) FS : {n: Nat} -> Fin n -> Fin (S n) Usage i: Fin 2 = 0 FZ = 0 i: Fin 2 = 1 FS FZ = 1 --> compile fine FS (FS FZ) = 2 i: Fin 2 = 2 ... --> compile error Sebastian Hungerecker February 8, 2016 8
Safe Vector Access index : Fin n -> Vect n a -> a index FZ (x :: xs) = x index (FS k) (x :: xs) = index k xs Usage myVect: Vect 2 Nat = 1 :: 2 :: Nil index 1 myVect --> 2 index 2 myVect --> compile error Sebastian Hungerecker February 8, 2016 9
Safe Vector Access index : Fin n -> Vect n a -> a index FZ (x :: xs) = x index (FS k) (x :: xs) = index k xs Usage ∀ n > 1 . Fin n myVect: Vect 2 Nat = 1 :: 2 :: Nil index 1 myVect --> 2 ∀ n > 2 . Fin n index 2 myVect --> compile error Sebastian Hungerecker February 8, 2016 9
Converting Numbers to Indices natToFin : (x: Nat) -> (n: Nat) -> Maybe (Fin n) natToFin Z (S j) = Just FZ natToFin (S k) (S j) with (natToFin k j) | Just k' = Just (FS k') | Nothing = Nothing natToFin _ Z = Nothing Usage natToFin 2 3 --> Just 2: Maybe (Fin 3) natToFin 3 3 --> Nothing Sebastian Hungerecker February 8, 2016 10
Example Continuation: A “Real” Application main : IO () main = do { input <- getLine n: Nat = cast input squares = map (\x => x*x) (iota n) print squares input2 <- getLine i: Nat = cast input2 case natToFin i n of Just idx => print (index idx squares) Nothing => putStrLn "Number too large" } Sebastian Hungerecker February 8, 2016 11
Cat Sebastian Hungerecker February 8, 2016 12
Limitations of Dependent Types in Idris iotaTR : (n: Nat) -> Vect m Nat -> Vect (m+n) Nat iotaTR Z acc = acc iotaTR (S n) acc = iotaTR n (S n :: acc) iota : (n: Nat) -> Vect n Nat iota n = iotaTR n Nil Sebastian Hungerecker February 8, 2016 13
Limitations of Dependent Types in Idris iotaTR : (n: Nat) -> Vect m Nat -> Vect (m+n) Nat iotaTR Z acc = acc iotaTR (S n) acc = iotaTR n (S n :: acc) iota : (n: Nat) -> Vect n Nat iota n = iotaTR n Nil Type mismatch between Vect m Nat (Type of acc) and Vect (m + 0) Nat (Expected type) Specifically: Type mismatch between m and m + 0 Sebastian Hungerecker February 8, 2016 13
Why? Huh? m � = m +0 ? Definition of + Z + r = r (S l) + r = S (l + r) Thus ◮ 0+ x = x is trivial ◮ x +0 = x needs to be proven Sebastian Hungerecker February 8, 2016 14
Overcoming Limitations of Dependent Types in Idris iotaTR : {m: Nat} -> (n: Nat) -> Vect m Nat -> Vect (m+n) Nat iotaTR {m} n acc = case n of Z => rewrite plusZeroRightNeutral m in acc (S n') => rewrite sym (plusSuccRightSucc m n') in iotaTR n' (n :: acc) iota : (n: Nat) -> Vect n Nat iota n = iotaTR n [] Sebastian Hungerecker February 8, 2016 15
Theorem Proving plusSuccRightSucc : Claim (l : Nat) -> (r : Nat) -> ∀ ℓ ∈ N . ∀ r ∈ N . S (l + r) = l + (S r) S ( ℓ + r ) = ℓ + S ( r ) Induction Basis plusSuccRightSucc Z r = S (0+ r ) = 0+ S ( r ) refl follows from definition Inductive Step S � S ( ℓ )+ r � = � plusSuccRightSucc (S l) r = let inductiveHypot = Inductive Hypothesis S ( ℓ + r ) = ℓ + S ( r ) plusSuccRightSucc l r in proof { Def = S � S ( ℓ + r ) � intros ; � IH = S � ℓ + S ( r ) � rewrite inductiveHypot; Def = S ( ℓ )+ S ( r ) trivial ; } Sebastian Hungerecker February 8, 2016 16
Theorem Proving plusSuccRightSucc : Claim (l : Nat) -> (r : Nat) -> ∀ ℓ ∈ N . ∀ r ∈ N . S (l + r) = l + (S r) S ( ℓ + r ) = ℓ + S ( r ) Induction Basis plusSuccRightSucc Z r = S (0+ r ) = 0+ S ( r ) refl follows from definition Inductive Step 0+ r = r S � S ( ℓ )+ r � = � plusSuccRightSucc (S l) r = S ( ℓ )+ r = S ( ℓ + r ) let inductiveHypot = Inductive Hypothesis S ( ℓ + r ) = ℓ + S ( r ) plusSuccRightSucc l r in proof { Def = S � S ( ℓ + r ) � intros ; � IH = S � ℓ + S ( r ) � rewrite inductiveHypot; Def = S ( ℓ )+ S ( r ) trivial ; } Sebastian Hungerecker February 8, 2016 16
Refinement Types ◮ Dependent ADTs cool, but cumbersome ◮ Combine types with predicates type t2 = {x:t | p(x)} ◮ Automated SMT solver instead of manual theorem proving Sebastian Hungerecker February 8, 2016 17
Qube Types Built-In Types ◮ Integers: int ◮ Integer vectors: intvec n ◮ Arrays: [elementType | shapeVector] Usage let i: int = 42 let iv: intvec 3 = [13, 23, 42] let tensor: [int | [2, 2, 3] ] = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 | [2, 2, 3] ] Sebastian Hungerecker February 8, 2016 18
Qube Types Refinement Types type nat = { i: int | 0 <= i } type index n:nat = { i: nat | i < n } type natvec n:nat = { iv: intvec n | ∀ i ∈ iv. 0 <= i } type indexvec n:nat sv:(natvec n) = { nv: natvec n | ∀ i,s ∈ nv,sv. i < s } Sebastian Hungerecker February 8, 2016 19
Qube Types Usage let n: nat = 42 -- Works let n2: nat = -5 -- Error !(-5 >= 0) let idx: index n = 41 -- Works let idx2: index n = 43 -- Error !(43 < 42) let shape: natvec 3 = [2,2,3] -- Works let iv: indexvec 3 shape = [0, 1, 2] -- Works let iv2: indexvec 3 shape = [2, 1, 0] -- Error !(2 < 2) let iv3: indexvec 3 [3,2,2] = [2, 1, 0] -- Works Sebastian Hungerecker February 8, 2016 20
Safe Array Access ◮ Array access: array.[ iv ] ◮ array: [ T | shape ] ◮ iv: indexvec r shape where r is the length of shape Usage tensor.[ iv ] -- Works tensor.[ iv3 ] -- Error Sebastian Hungerecker February 8, 2016 21
Uniqueness Types And now for something completely different. . . Sebastian Hungerecker February 8, 2016 22
Uniqueness Types ◮ Value can’t be used more than once ◮ Operations need to produce new value Sebastian Hungerecker February 8, 2016 23
Example: File Handling type file fopen(name: string): unique file fwrite(text:string, f: unique file): unique file fclose(f: unique file): void Usage let f = fopen("foo.txt") let f = fwrite(f, "bar") fclose(f) Sebastian Hungerecker February 8, 2016 24
Example: File Handling type file fopen(name: string): unique file fwrite(text:string, f: unique file): unique file fclose(f: unique file): void Usage let f = fopen("foo.txt") let f = fwrite(f, "bar") fclose(f) fwrite(f, "baz") --> Error: f has already been consumed Sebastian Hungerecker February 8, 2016 24
Conclusion ◮ Type systems turn wrong behavior into errors ◮ Static type systems turn run-time into compile-time errors ⇒ Cost: (sometimes) have to write down type information ◮ Advanced features catch even more errors at compile time ⇒ Cost: even more type information required Sebastian Hungerecker February 8, 2016 25
Outlook Express What else can be guarenteed through types? ◮ NullPointerExceptions through option types ◮ Validity of generated XML by translating XML schemas to type hierachies ◮ SQL queries through row types ◮ Transactionality through monads ◮ Termination through dependent types & theorem proving Sebastian Hungerecker February 8, 2016 26
Recommend
More recommend