30
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

Advanced Features of Type Systems - Concepts of ... · Limitations of Dependent Types in Idris iotaTR: (n:Nat) ->VectmNat-> Vect(m+n)Nat iotaTRZacc=acc iotaTR(Sn)acc=iotaTRn(Sn::acc)

  • Upload
    others

  • View
    4

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Advanced Features of Type Systems - Concepts of ... · Limitations of Dependent Types in Idris iotaTR: (n:Nat) ->VectmNat-> Vect(m+n)Nat iotaTRZacc=acc iotaTR(Sn)acc=iotaTRn(Sn::acc)

Advanced Features of Type SystemsConcepts of Programming Languages—CoPL’15

Sebastian Hungerecker

Institute for Software Engineering and Programming Languages

February 8, 2016

Sebastian Hungerecker February 8, 2016 1

Page 2: Advanced Features of Type Systems - Concepts of ... · Limitations of Dependent Types in Idris iotaTR: (n:Nat) ->VectmNat-> Vect(m+n)Nat iotaTRZacc=acc iotaTR(Sn)acc=iotaTRn(Sn::acc)

Introduction

I Type systems turn wrong behavior into errorsI Static type systems turn run-time into compile-time errorsI Advanced features catch even more errors at compile time

Sebastian Hungerecker February 8, 2016 2

Page 3: Advanced Features of Type Systems - Concepts of ... · Limitations of Dependent Types in Idris iotaTR: (n:Nat) ->VectmNat-> Vect(m+n)Nat iotaTRZacc=acc iotaTR(Sn)acc=iotaTRn(Sn::acc)

Topics

Dependent Types

Refinement Types

Uniqueness Types

Sebastian Hungerecker February 8, 2016 3

Page 4: Advanced Features of Type Systems - Concepts of ... · Limitations of Dependent Types in Idris iotaTR: (n:Nat) ->VectmNat-> Vect(m+n)Nat iotaTRZacc=acc iotaTR(Sn)acc=iotaTRn(Sn::acc)

Dependent Types

Types depend on values.

data Foo: Int -> Type where ...baz: (bar: Int) -> Foo bar

⇒ More information about types

⇒ More properties can be expressedFor example: Index out of bounds

Sebastian Hungerecker February 8, 2016 4

Page 5: Advanced Features of Type Systems - Concepts of ... · Limitations of Dependent Types in Idris iotaTR: (n:Nat) ->VectmNat-> Vect(m+n)Nat iotaTRZacc=acc iotaTR(Sn)acc=iotaTRn(Sn::acc)

ADT in Idris

data Nat : Type whereZ : NatS : Nat -> Nat

Usage

i: Nat = S (S (S Z))

-- with more sugar:i: Nat = 3

Z = 0S Z = 1

S (S Z) = 2. . .

Sebastian Hungerecker February 8, 2016 5

Page 6: Advanced Features of Type Systems - Concepts of ... · Limitations of Dependent Types in Idris iotaTR: (n:Nat) ->VectmNat-> Vect(m+n)Nat iotaTRZacc=acc iotaTR(Sn)acc=iotaTRn(Sn::acc)

Dependent Types in Idris

data Vect : Nat -> Type -> Type whereNil : 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

Page 7: Advanced Features of Type Systems - Concepts of ... · Limitations of Dependent Types in Idris iotaTR: (n:Nat) ->VectmNat-> Vect(m+n)Nat iotaTRZacc=acc iotaTR(Sn)acc=iotaTRn(Sn::acc)

Example: Sequential Vector (ι Function)

iotaHelper : (n: Nat) -> Vect n NatiotaHelper Z = NiliotaHelper (S m) = (S m) :: iotaHelper m

iota : (n: Nat) -> Vect n Natiota n = reverse (iotaHelper n)

Usage

iota 5--> (1 :: 2 :: 3 :: 4 :: 5 :: Nil): Vect 5 Nat

Sebastian Hungerecker February 8, 2016 7

Page 8: Advanced Features of Type Systems - Concepts of ... · Limitations of Dependent Types in Idris iotaTR: (n:Nat) ->VectmNat-> Vect(m+n)Nat iotaTRZacc=acc iotaTR(Sn)acc=iotaTRn(Sn::acc)

Static Range Checking of Indices

data Fin : Nat -> Type whereFZ : {n: Nat} -> Fin (S n)FS : {n: Nat} -> Fin n -> Fin (S n)

Usage

i: Fin 2 = 0i: Fin 2 = 1--> compile fine

i: Fin 2 = 2--> compile error

FZ = 0FS FZ = 1

FS (FS FZ) = 2. . .

Sebastian Hungerecker February 8, 2016 8

Page 9: Advanced Features of Type Systems - Concepts of ... · Limitations of Dependent Types in Idris iotaTR: (n:Nat) ->VectmNat-> Vect(m+n)Nat iotaTRZacc=acc iotaTR(Sn)acc=iotaTRn(Sn::acc)

Safe Vector Access

index : Fin n -> Vect n a -> aindex FZ (x :: xs) = xindex (FS k) (x :: xs) = index k xs

Usage

myVect: Vect 2 Nat = 1 :: 2 :: Nil

index 1 myVect--> 2

index 2 myVect--> compile error

∀n > 1. Fin n

∀n > 2. Fin n

Sebastian Hungerecker February 8, 2016 9

Page 10: Advanced Features of Type Systems - Concepts of ... · Limitations of Dependent Types in Idris iotaTR: (n:Nat) ->VectmNat-> Vect(m+n)Nat iotaTRZacc=acc iotaTR(Sn)acc=iotaTRn(Sn::acc)

Safe Vector Access

index : Fin n -> Vect n a -> aindex FZ (x :: xs) = xindex (FS k) (x :: xs) = index k xs

Usage

myVect: Vect 2 Nat = 1 :: 2 :: Nil

index 1 myVect--> 2

index 2 myVect--> compile error

∀n > 1. Fin n

∀n > 2. Fin n

Sebastian Hungerecker February 8, 2016 9

Page 11: Advanced Features of Type Systems - Concepts of ... · Limitations of Dependent Types in Idris iotaTR: (n:Nat) ->VectmNat-> Vect(m+n)Nat iotaTRZacc=acc iotaTR(Sn)acc=iotaTRn(Sn::acc)

Converting Numbers to Indices

natToFin : (x: Nat) -> (n: Nat) -> Maybe (Fin n)natToFin Z (S j) = Just FZnatToFin (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

Page 12: Advanced Features of Type Systems - Concepts of ... · Limitations of Dependent Types in Idris iotaTR: (n:Nat) ->VectmNat-> Vect(m+n)Nat iotaTRZacc=acc iotaTR(Sn)acc=iotaTRn(Sn::acc)

Example Continuation: A “Real” Application

main : IO ()main = do {input <- getLinen: Nat = cast inputsquares = map (\x => x*x) (iota n)print squaresinput2 <- getLinei: Nat = cast input2case natToFin i n of

Just idx => print (index idx squares)Nothing => putStrLn "Number too large"

}

Sebastian Hungerecker February 8, 2016 11

Page 13: Advanced Features of Type Systems - Concepts of ... · Limitations of Dependent Types in Idris iotaTR: (n:Nat) ->VectmNat-> Vect(m+n)Nat iotaTRZacc=acc iotaTR(Sn)acc=iotaTRn(Sn::acc)

Cat

Sebastian Hungerecker February 8, 2016 12

Page 14: Advanced Features of Type Systems - Concepts of ... · Limitations of Dependent Types in Idris iotaTR: (n:Nat) ->VectmNat-> Vect(m+n)Nat iotaTRZacc=acc iotaTR(Sn)acc=iotaTRn(Sn::acc)

Limitations of Dependent Types in Idris

iotaTR : (n: Nat) -> Vect m Nat ->Vect (m+n) Nat

iotaTR Z acc = acciotaTR (S n) acc = iotaTR n (S n :: acc)

iota : (n: Nat) -> Vect n Natiota n = iotaTR n Nil

Type mismatch betweenVect m Nat (Type of acc)

and Vect (m + 0) Nat (Expected type)

Specifically: Type mismatch betweenm

and m + 0

Sebastian Hungerecker February 8, 2016 13

Page 15: Advanced Features of Type Systems - Concepts of ... · Limitations of Dependent Types in Idris iotaTR: (n:Nat) ->VectmNat-> Vect(m+n)Nat iotaTRZacc=acc iotaTR(Sn)acc=iotaTRn(Sn::acc)

Limitations of Dependent Types in Idris

iotaTR : (n: Nat) -> Vect m Nat ->Vect (m+n) Nat

iotaTR Z acc = acciotaTR (S n) acc = iotaTR n (S n :: acc)

iota : (n: Nat) -> Vect n Natiota n = iotaTR n Nil

Type mismatch betweenVect m Nat (Type of acc)

and Vect (m + 0) Nat (Expected type)

Specifically: Type mismatch betweenm

and m + 0

Sebastian Hungerecker February 8, 2016 13

Page 16: Advanced Features of Type Systems - Concepts of ... · Limitations of Dependent Types in Idris iotaTR: (n:Nat) ->VectmNat-> Vect(m+n)Nat iotaTRZacc=acc iotaTR(Sn)acc=iotaTRn(Sn::acc)

Why?

Huh?m 6=m+0?

Definition of +

Z + r = r(S l) + r = S (l + r)

ThusI 0+x= x is trivialI x+0 = x needs to be proven

Sebastian Hungerecker February 8, 2016 14

Page 17: Advanced Features of Type Systems - Concepts of ... · Limitations of Dependent Types in Idris iotaTR: (n:Nat) ->VectmNat-> Vect(m+n)Nat iotaTRZacc=acc iotaTR(Sn)acc=iotaTRn(Sn::acc)

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 ofZ =>

rewrite plusZeroRightNeutral min acc

(S n') =>rewrite sym (plusSuccRightSucc m n')in iotaTR n' (n :: acc)

iota : (n: Nat) -> Vect n Natiota n = iotaTR n []

Sebastian Hungerecker February 8, 2016 15

Page 18: Advanced Features of Type Systems - Concepts of ... · Limitations of Dependent Types in Idris iotaTR: (n:Nat) ->VectmNat-> Vect(m+n)Nat iotaTRZacc=acc iotaTR(Sn)acc=iotaTRn(Sn::acc)

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 StepplusSuccRightSucc (S l) r = S

(S(`) + r

)=Y

let inductiveHypot = Inductive HypothesisplusSuccRightSucc l r S(` + r) = ` + S(r)

in proof {

intros; YDef= S

(S(` + r)

)rewrite inductiveHypot;

IH= S(` + S(r)

)trivial; Def= S(`) + S(r)

}

0+ r = r

S(`)+ r = S(`+ r)

Sebastian Hungerecker February 8, 2016 16

Page 19: Advanced Features of Type Systems - Concepts of ... · Limitations of Dependent Types in Idris iotaTR: (n:Nat) ->VectmNat-> Vect(m+n)Nat iotaTRZacc=acc iotaTR(Sn)acc=iotaTRn(Sn::acc)

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 StepplusSuccRightSucc (S l) r = S

(S(`) + r

)=Y

let inductiveHypot = Inductive HypothesisplusSuccRightSucc l r S(` + r) = ` + S(r)

in proof {

intros; YDef= S

(S(` + r)

)rewrite inductiveHypot;

IH= S(` + S(r)

)trivial; Def= S(`) + S(r)

}

0+ r = r

S(`)+ r = S(`+ r)

Sebastian Hungerecker February 8, 2016 16

Page 20: Advanced Features of Type Systems - Concepts of ... · Limitations of Dependent Types in Idris iotaTR: (n:Nat) ->VectmNat-> Vect(m+n)Nat iotaTRZacc=acc iotaTR(Sn)acc=iotaTRn(Sn::acc)

Refinement Types

I Dependent ADTs cool, but cumbersomeI Combine types with predicatestype t2 = {x:t | p(x)}

I Automated SMT solver instead of manual theorem proving

Sebastian Hungerecker February 8, 2016 17

Page 21: Advanced Features of Type Systems - Concepts of ... · Limitations of Dependent Types in Idris iotaTR: (n:Nat) ->VectmNat-> Vect(m+n)Nat iotaTRZacc=acc iotaTR(Sn)acc=iotaTRn(Sn::acc)

Qube Types

Built-In TypesI Integers: intI Integer vectors: intvec nI Arrays: [elementType | shapeVector]

Usage

let i: int = 42let 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

Page 22: Advanced Features of Type Systems - Concepts of ... · Limitations of Dependent Types in Idris iotaTR: (n:Nat) ->VectmNat-> Vect(m+n)Nat iotaTRZacc=acc iotaTR(Sn)acc=iotaTRn(Sn::acc)

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

Page 23: Advanced Features of Type Systems - Concepts of ... · Limitations of Dependent Types in Idris iotaTR: (n:Nat) ->VectmNat-> Vect(m+n)Nat iotaTRZacc=acc iotaTR(Sn)acc=iotaTRn(Sn::acc)

Qube Types

Usage

let n: nat = 42 -- Workslet n2: nat = -5 -- Error !(-5 >= 0)

let idx: index n = 41 -- Workslet idx2: index n = 43 -- Error !(43 < 42)

let shape: natvec 3 = [2,2,3] -- Workslet 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

Page 24: Advanced Features of Type Systems - Concepts of ... · Limitations of Dependent Types in Idris iotaTR: (n:Nat) ->VectmNat-> Vect(m+n)Nat iotaTRZacc=acc iotaTR(Sn)acc=iotaTRn(Sn::acc)

Safe Array Access

I Array access: array.[ iv ]

I array: [ T | shape ]

I iv: indexvec r shape where r is the length of shape

Usage

tensor.[ iv ] -- Workstensor.[ iv3 ] -- Error

Sebastian Hungerecker February 8, 2016 21

Page 25: Advanced Features of Type Systems - Concepts of ... · Limitations of Dependent Types in Idris iotaTR: (n:Nat) ->VectmNat-> Vect(m+n)Nat iotaTRZacc=acc iotaTR(Sn)acc=iotaTRn(Sn::acc)

Uniqueness Types

And now forsomethingcompletelydifferent. . .

Sebastian Hungerecker February 8, 2016 22

Page 26: Advanced Features of Type Systems - Concepts of ... · Limitations of Dependent Types in Idris iotaTR: (n:Nat) ->VectmNat-> Vect(m+n)Nat iotaTRZacc=acc iotaTR(Sn)acc=iotaTRn(Sn::acc)

Uniqueness Types

I Value can’t be used more than onceI Operations need to produce new value

Sebastian Hungerecker February 8, 2016 23

Page 27: Advanced Features of Type Systems - Concepts of ... · Limitations of Dependent Types in Idris iotaTR: (n:Nat) ->VectmNat-> Vect(m+n)Nat iotaTRZacc=acc iotaTR(Sn)acc=iotaTRn(Sn::acc)

Example: File Handling

type file

fopen(name: string): unique filefwrite(text:string, f: unique file): unique filefclose(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

Page 28: Advanced Features of Type Systems - Concepts of ... · Limitations of Dependent Types in Idris iotaTR: (n:Nat) ->VectmNat-> Vect(m+n)Nat iotaTRZacc=acc iotaTR(Sn)acc=iotaTRn(Sn::acc)

Example: File Handling

type file

fopen(name: string): unique filefwrite(text:string, f: unique file): unique filefclose(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

Page 29: Advanced Features of Type Systems - Concepts of ... · Limitations of Dependent Types in Idris iotaTR: (n:Nat) ->VectmNat-> Vect(m+n)Nat iotaTRZacc=acc iotaTR(Sn)acc=iotaTRn(Sn::acc)

Conclusion

I Type systems turn wrong behavior into errorsI Static type systems turn run-time into compile-time errors

⇒ Cost: (sometimes) have to write down type informationI Advanced features catch even more errors at compile time

⇒ Cost: even more type information required

Sebastian Hungerecker February 8, 2016 25

Page 30: Advanced Features of Type Systems - Concepts of ... · Limitations of Dependent Types in Idris iotaTR: (n:Nat) ->VectmNat-> Vect(m+n)Nat iotaTRZacc=acc iotaTR(Sn)acc=iotaTRn(Sn::acc)

Outlook Express

What else can be guarenteed through types?I NullPointerExceptions through option typesI Validity of generated XML by translating XML schemas to type

hierachiesI SQL queries through row typesI Transactionality through monadsI Termination through dependent types & theorem proving

Sebastian Hungerecker February 8, 2016 26