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