Typsysteme
Siyuan Liu
Sept. 2000
1
Einführung
• Motivation
• Formulierung der Typsysteme
• Typisierte Lambda-Kalküle
• Mini-ML
2
Warum Typen?
1. um Inkonsistenzen zu vermeiden
Gottlob Frege (Prädikatenlogik,  1879)
Russel (1901): Paradox {X | X  X }
Whitehead & Russel: Principia Mathematica (1910-1913)
Typen verbieten X  X
Church (1930): untypisierter -Kalkül als Logik
True, False, , ... sind -Terme
{x | P}  x.P
x  M  Mx
Inkonsistenz: R := x.not (x x)  R R = not (R R)
Church (1940): „Simply Typed -Calculus“ erlaubt x x nicht.
3
2. um Programmierfehler zu vermeiden
Typ und Typsystem
Klassifikation von Typsystemen:
monomorph : Jeder Bezeichner hat genau einen Typ.
polymorph : Ein Bezeichner kann mehrere Typen haben.
statisch : Typkorrektheit wird zur Übersetzungszeit überprüft.
dynamisch : Typkorrektheit wird zur Laufzeit überprüft.
monomorph
polymorph
statisch
dynamisch
Pascal
ML, Haskell
(C++,) Java
Lisp, Smalltalk
4
3. um Spezifikationen durch Typen auszudrücken
Methode: abhängige Typen
Beispiel: mod: nat  m:nat  {k | 0  k < m}
Resultattyp hängt vom Eingabewert ab („Typtheorie“)
5
4. Typsicherheit
Tabelle 1. Sicherheit(safety)
Typisiert
Untypisiert
Sicher
ML, Java
LISP
Unsicher
C, C++
Assembler
6
Wie formuliert man Typsysteme?
1. Syntax beschreiben
Typen und Terme beschreiben
2. Typregeln definieren
M : A,
A  B,
A = B, ... (Aussagen)
static typing environments (Kontext) :
 |– M : A
 |– t : 
Schreibweise:
[x : ]
[x1 : 1, ... , xn : n]
das Überschreiben von  mit der Abbildung x  
7
Typisierte Lambda-Kalküle
1. Einfach typisierter -Kalkül ()
2. Typinferenz für 
3. Let-Polymorphismus
8
1. Einfach typisierter -Kalkül ()
Kern jeder (funktionalen) Programmiersprache:
Typen:
 ::= bool | nat | int | ... | 1  2

Basistypen
Konvention:  assoziiert nach rechts:
1  2  3  1  (2 3)
Terme:
1. implizit typisiert: jede Variable hat (implizit) einen eindeutigen Typ.
2. explizit typisiert:
t ::= x | (t1 t2) | x : .t
9
1.1 Typüberprüfung für explizit typisierte Terme
Regeln:
(Var):
(App):
(x) ist definiert
 |– x : (x)
 |– t1 : 1  2
 |– t2 : 1
 |– (t1 t2) : 2
(Abs):
[x : ] |– t : ´
 |– x : .t :   ´
Beispiele 1.1
10
Algorithmus:

Type :: Kontext  Term  Typ
Type(, x) | (A. x:A  ) = A
| otherwise fail
Type(, x:A.M) = A  Type((, x:A), M)
Type(, M N) | (B. Type(, M) = = Type(, N)  B) = B
| otherwise fail

Beispiel 1.2
11
1.2 Theorie
Definition 1.2.1 t ist typkorrekt (bzgl. ), falls es  gibt mit  |– t : 
Lemma 1.2.2 Der Typ eines typkorrekten Termes ist eindeutig bestimmt
(bzgl. Eines festen Kontextes ).
Theorem 1.2.3 (Subject Reduction)  |– t :   t  t´   |– t´ : 
(„keine Typfehler zur Laufzeit“)
Theorem 1.2.4  ( , ) auf typkorrekten Termen ist konfluent.
Theorem 1.2.5  terminiert auf typkorrekten Termen.
Korollar 1.2.6 = ist für typkorrekte Terme entscheidbar.
12
Korollar 1.2.7 Nicht alle berechenbaren Funktionen sind als typkorrekte
 -Terme darstellbar. (sogar ziemlich wenige: Polynome +
Fallunterscheidung)
Theorem 1.2.8 Jede berechenbare Funktion ist als geschlossener
typkorrekter  -Terme darstellbar, der als einzige Konstanten
Fixpunktoperatoren Y  enthält, für die die
Reduktionsregel Y t t (Y t) gilt.
(Y :      mit Polymorphie
13
2. Typinferenz für 
Typen:  ::= bool | int | ...
Basistypen
| 
Typvariablen
| 1 
Terme: untypisierte -Terme
Typinferenzregeln:
 – x : (x)
 – t1 :   – t2 : 
[x : ] – t : 2
 – (t1 t2) : 
 – (x.t) : 
Terme können verschiedene Typen haben (Polymorphie):
x.x : 
x.x : intint
Definition 2.1  :  Substitution  (von Typen für Typvariable)
mit  = () („  ist allgemeiner oder äquivalent .“)
Bsp.:
int  int        
14
Theorem 3.2  – t :   – t : |– t :  < 
„Jeder typkorrekte Term hat einen allgemeinsten Typ.“
Bsp.:
 – x.y.(y x) : 
falls [x : ] – y.(y x) :  und  =   
falls [x : , y : ] – (y x) :  und  =   
falls [x : , y : ] – y :    und [x : , y : ] – x : 
falls  =    und  = 
Also:  =    =   (  ) =   ((  )  )
15
3. Let-Polymorphismus
Terme: t ::= x | (t1 t2) | x.t | let x = t1 in t2
Semantik: let x = t1 in t2  t2[t1/x]
(wohldefiniert wegen Termination und Konfluenz von )
Typen:
 ::= bool | ... |  | ... | 1  2
Typschemata:
 ::=  
Beispiele für Typschemata:
, int, .   , , .   
aber nicht (.   )  bool (Der Allquantor tritt nicht ganz
außen auf!)
16
Typinferenzregeln (x1 : 1, ... , xn : n]):
(Var):
|– x : x)
(App):
|– t1 : 2   |– t2 : 2
|– (t1 t2) : 
(Abs):
[x : 1] |– t : 2
 |– (x.t) : 1  2
(Let):
|– t1 : 1 [x : 1] |– t2 : 2
|– let x = t1 in t2 : 2
17
Quantorenregeln:
(Elim):
|– t : 
|– t : [ /]
|– t : 
|– t : 
Wobei FV([x1 : 1 , ... , xn : n]) = i=1 FV(i)
(Intro):
falls  FV()
Beispiel 3.1
18
Problem:
Die Regeln liefern keinen Algorithmus, da Quantorenregeln nicht
syntaxgesteuert, d.h. (fast) immer anwendbar sind.
Lösung:
Integriere (Elim) mit (Var) und (Intro) mit (Let)
syntaxgesteuerte Regeln
19
(App):
|– t1 : 2  
|– t2 : 2
|– (t1 t2) : 
[x : 1] |– t : 2
(Abs):
 |– (x.t) : 1  2
(Var´):
x) = 1, ... , n.
|– x : [1/1, ... , n/n]
(Let´):
|– t1 : 
[x : 1, ... , n.] |– t2 : 2
|– let x = t1 in t2 : 2
{1, ... , n} = FV() \ FV()
Bemerkung: Typschemata kommen nur noch in  vor.
Beispiel 3.2
20
Komplexität der Typinferenz:
• ohne let: linear
• mit let: DEXPTIME-vollständig (Typen können exponentiell mit der
Größe der Terme wachsen.)
Beispiel:
let x0 = y.z.z y y
in let x1 = y.x0 (x0 y)
in ...
let xn+1 = y.xn (xn y)
in xn+1 (z.z)
21
Mini-ML
(Als Ergänzung zu den typisierten Lambda-Kalkülen)
Die neuen abstrakten Syntax von Mini-ML:
Sorten
EXP, IDENT
Konstruktoren
number
:
false
:
true
:
mlpair : EXPEXP
letrec
: IDENTEXPEXP
if
: EXPEXPEXP






EXP
EXP
EXP
EXP
EXP
EXP
22
Die statische Semantik von Mini-ML in Typol:
program ML-TC is
use ML
A, A´ : ENV;
, ´ : TYPE;
 : TYPE_SCHEME;
set TYPE is
A |– number N : int
A |– true : bool
A |– false : bool
A |– E : bool A |– E´ :  A |– E´´ : 
A |– if E then E´ else E´´ : 
A |– E :  A |– E´ : ´
A |– (E, E´) :  ´
A |– let P = Y(P.E´) in E : 
A |– letrec P = E´ in E : 
end TYPE
23
Einige Programmsbeispiele:
a)
let succ = x.x+1
in let twice = f.x.(f (f x))
in ((twice succ) 0)
b)
letrec fact = x. if x = 0 then 1 else x * fact(x-1)
in fact 4
c)
letrec (even, odd) = (x.if x = 0 then true else odd(x – 1),
x.if x = 0 then false else even(x – 1))
in even(3)
24
Literaturen
• Prof. Tobias Nipkow, Lambda-Kalkül, 4. August 1998
• Luca Cardelli, Type Systems, Digital Equipment
Corporation, Systems Research Center, 1997
• Dominique Clément, Joëlle Despeyroux, Thierry
Despeyroux, Gilles Kahn, A Simple Applicative
Language: Mini-ML, 1986
25

A. x