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 : intint
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 : EXPEXP
letrec
: IDENTEXPEXP
if
: EXPEXPEXP
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