class: center, middle

Why do we need Type system ?

• To check if the program run as we expected
• How far could it go?
• Halting problem
• A meta language
• Unit testing
• a type system, namely that: in it all terms are typed.
• Could the meta language describe a structure, but not a set?
• Define structure? Algebra?
• How about Subtyping? As some of OOPL do?
• It is so hard for such a design problem
• UX is dealing with the general user, PL is serving the need of programmers

What's a Machine?

• Algorithm complexity: Abstract machine
• Turing machine
• Real CPU by instruction

Lambda Calculus

• Machine for substitution
• Assembly of functional language
• Various extensions of lambda calculus serves as the intermediate form of functional languages
• A single substitution step is called "beta reduction", or simply reduction

They come with different power

• Could it be possible I could roll my own type system?
• What if I add/remove rule to type system?
• What's normal life programming language's type system?
• The goal of type system

Hindley Milner Type Rules

\begin{aligned} e :=\ & x & \trule{Var} \\ & \lambda x. e & \trule{Lam} \\ & e\ e & \trule{App} \\ \end{aligned}

• Often a construct called "let binding" is added $$๐๐๐ a=e ๐๐ b:=(ฮปa.b)e$$
• The complete set of type functions D is arbitrary in HM, except that it must contain at least $$\rightarrow$$
• Polytypes (or type schemes) are types containing variables bound by one or more for-all quantifiers
• The quantifiers can only appear top level. No $$\forall \alpha -> \forall \alpha$$

Recursion

• Point to self
• Let rec

Type System

data Exp = EVar EVar
| ELit ELit
| EApp Exp Exp
| EAbs EVar Exp
| ELet EVar Exp Exp
deriving (Eq, Ord, Show)

Substitutable

class Substitutable a where
apply โท Subst โ a โ a
freeTvars :: a -> Set.Set TVar
instance Substitutable Type where
apply _ TInt = TInt
apply _ TBool = TBool
apply su t@(TVar a) = Map.findWithDefault t a su
apply su (t1 TArrow t2) = apply su t1 TArrow apply su t2

freeTvars TInt = Set.empty
freeTvars TBool = Set.empty
freeTvars (TVar a) = Set.singleton a
freeTvars (t1 TArrow t2) = freeTvars t1 Set.union freeTvars t2
instance Substitutable a โ Substitutable [a] where
apply = map โ apply
freeTvars = (foldr Set.union Set.empty) โ (map freeTvars)
instance Substitutable Scheme where
apply su (Forall as t) = Forall as $apply s' t where s' = foldr Map.delete su as freeTvars (Forall as t) = (freeTvars t) Set.difference (Set.fromList as) instance Substitutable TypeEnv where apply su (TypeEnv env) = TypeEnv$ Map.map (apply su) env

Inference (1)

ti โท (MonadState TIState m, MonadError String m) โ TypeEnv โ Exp โ m (Subst, Type)
ti _ (ELit (LInt _)) = return (emptySubst, TInt)
ti _ (ELit (LBool _)) = return (emptySubst, TBool)
ti (TypeEnv env) (EVar x) =โข
case Map.lookup x env of
Nothing โ throwError \$ "Unbound Variable: " โงบ show x
Just s โ doโข
v โ instantiate s
return (emptySubst, v)
ti env (EAbs x e) =โข
do tv โ freshTVar "a"
let env' = env โ (x, Forall [] tv)
(s1, t1) โ ti env' e
return (s1, (apply s1 tv) TArrow t1)

Inference (2)

ti env (EApp e1 e2) =
do tv โ freshTVar "a"
(s1, t1) โ ti env e1
(s2, t2) โ ti (apply s1 env) e2
s3 โ mgu (apply s2 t1) (TArrow t2 tv)
return (s3 after s2 after s1, apply s3 tv)
• Name shadowing $$ฮปxy.(ฮปxz.x+y)$$

Inference (3)

ti env (ELet x e1 e2) =
do (s1, t1) โ ti env e1
let env' = apply s1 env
t' = generalize env' t1
(s2, t2) โ ti (env' โ (x, t')) e2
return (s1 after s2, t2)

The peril of Let-polymorphism

lambda f : (forall A. A -> A). (f Int 1, f String "hello")