Lineare Typen Alexander Aumann Übersicht Gliederung Lineare Typen Lineare Logik Lineare Typen Lineare Typen Seminar Having Fun with Types Alexander Aumann TU-München Sommersemester 2011 Funktionale Programmiersprachen Seiteneffekte Direktupdates und Speichermanagement CLEAN und Uniqueness Typing Inhalt Lineare Typen Alexander Aumann Übersicht Gliederung Lineare Typen Lineare Logik Lineare Typen Inhalt des Vortrags Lineare Logik Lineare Variablen Seiteneffekte in funktionalen Programmiersprachen Direktersetzung in funtionalen Programmiersprachen Clean Funktionale Programmiersprachen Seiteneffekte Direktupdates und Speichermanagement CLEAN und Uniqueness Typing Lineare Logik Lineare Typen Alexander Aumann Übersicht Gliederung Lineare Typen Lineare Logik Ursprünglich von Jean-Yves Girard entwickelt Erweiterung/Kombination Intuitionistischer Logik und klassischer Aussagenlogik Später von Yves Lafont als “Logik über Ressourcen” interpretiert Transformation von einer Ressource in eine andere möglich Duplikation oder Beseitigung der Ressource wird eingeschränkt Lineare Logik Lineare Typen Funktionale Programmiersprachen Seiteneffekte Direktupdates und Speichermanagement CLEAN und Uniqueness Typing Was genau sind Lineare Typen? Lineare Typen Lineare Typen Alexander Aumann Übersicht Gliederung Lineare Typen Lineare Typen erlauben nur eine Referenz (keine Aliase) keine zwei Variablen auf dieselbe Ressource gleichzeitig Sobald eine Variable auf der rechten Seite einer Zuweisung erscheint, wird sie aus dem aktuellen Gültigkeitsbereich (engl.: scope) geschoben Es kann dann nicht mehr auf den Wert der Variablen zugegriffen werden Example 1 2 3 4 5 6 7 File * fileA = new File ( " foo . txt " ); filaA - > open (); fileA - > write ( " Hallo " ); File * fileB = fileA ; fileB - > close (); // .. nächste Zeile ungülti g fileA - > write ( " Hallo nochmal " ); Lineare Logik Lineare Typen Funktionale Programmiersprachen Seiteneffekte Direktupdates und Speichermanagement CLEAN und Uniqueness Typing Seiteneffekte in linearen Programmiersprachen Lineare Typen Alexander Aumann Übersicht Gliederung Lineare Typen Lineare Logik Lineare Typen Funktionale Programmiersprachen Sprachen wie Haskell, Caml, Clean Sehr elegante Programmiersprachen Entsprechen besser der mathematischen Vorstellung von Funktionen Im Gegensatz zur imperativen Programmierung keine Zustände Rein funktionale Sprachen referentiell transparent Auswertungsreihenfolge bei Ausdrücken irrelevant Aufruf einer Funktion mit gleichem Argument hat immer den gleichen Rückgabewert Funktionale Programmiersprachen Seiteneffekte Direktupdates und Speichermanagement CLEAN und Uniqueness Typing Seiteneffekte in linearen Programmiersprachen Lineare Typen Alexander Aumann Übersicht Gliederung Lineare Typen Lineare Logik Lineare Typen Funktionale Programmiersprachen Was sind Seiteneffekte? Bei Interaktion mit der Außenwelt Lesen und Schreiben von Dateien Interaktion mit der Konsole Grafische Oberflächen Seiteneffekte unabhängig vom Rückgabewert der Funktion Das Zulassen von Seiteneffekten führt zu Problemen Seiteneffekte Direktupdates und Speichermanagement CLEAN und Uniqueness Typing Seiteneffekte in linearen Programmiersprachen 1 2 3 4 5 6 7 8 9 10 11 Lineare Typen Alexander Aumann Übersicht Gliederung Lineare Typen Example function writeString ( File file , String str ) returns retFile return retFile = do Imp er a t i v e W r i t e ( file , str ) end function funkyFunc ( File file ) returns ( File , File ) return ( writeString ( file , " AB ") , writeString ( file , " CD ")) end File file = fi leFr omS ome wh e r e (" foo . txt ") ( fileA , fileB ) = funkyFunc ( file ) Probleme Was steht nun in der Datei? Auswertungsreihenfolge beachten oder Kopien ??? Lineare Logik Lineare Typen Funktionale Programmiersprachen Seiteneffekte Direktupdates und Speichermanagement CLEAN und Uniqueness Typing Seiteneffekte in linearen Programmiersprachen Lineare Typen Alexander Aumann Übersicht Gliederung Lösung: lineare Variablen! Fixieren der Auswertungsreihenfolge zerstört referentielle Transparenz Zwei unabhängige Kopien der Datei entsprechen nicht dem realen Dateisystem => lineare Variablen verhindern solche Duplikate Example 1 2 3 4 5 6 7 8 function writeString ( linear File file , String str ) returns linear File return retFile = do Imp er a t i v e W r i t e ( file , str ) end File file = fi leFr omS ome wh e r e (" foo . txt ") File fileB = writeString ( file , " Hallo ") File fileC = writeString ( fileB , " Welt !") Lineare Typen Lineare Logik Lineare Typen Funktionale Programmiersprachen Seiteneffekte Direktupdates und Speichermanagement CLEAN und Uniqueness Typing Garbage Collection Lineare Typen Alexander Aumann Übersicht Gliederung Direktersetzung Variablen sind in funktionalen Programmiersprachen immer konstant Das heißt es werden häufig lokale Kopien erstellt Nachteil zu imperativen Programmiersprachen Durch Verwendung linearer Typen kann der Compiler bei rekursiven Funktionsaufrufen den Speicherplatz der Variablen direkt ersetzen Es ist sicher, da keine weitere Referenz auf diese Variable existiert Dadurch ist kein Garbage Collector für solche, linear geschriebenen Programme nötig! Lineare Typen Lineare Logik Lineare Typen Funktionale Programmiersprachen Seiteneffekte Direktupdates und Speichermanagement CLEAN und Uniqueness Typing Garbage Collection 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 Lineare Typen Alexander Aumann Übersicht Gliederung Example (Quicksort) Lineare Typen Lineare Logik Lineare Typen (* hohe Elemente von x nach h , niedrige nach l *) let rec hilo x i h l = if x = [] then h , l else let firstx :: restx = x in if firstx < i then hilo restx i h ( firstx :: l ) else hilo restx i ( firstx :: h ) l ;; (* Liste x in die Liste l einsortieren *) let rec qs x l = if x = [] then l else let i :: restx = x in let high , low = hilo restx i [] [] in qs low ( i ::( qs high l )) ;; Funktionale Programmiersprachen Seiteneffekte Direktupdates und Speichermanagement CLEAN und Uniqueness Typing Garbage Collection 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 Lineare Typen Alexander Aumann Übersicht Example (Linearer Quicksort) Gliederung Lineare Typen (* hohe Elemente von x nach h , niedrige nach l *) let rec hilo x i h l = if - nil x then ( kill x ; h , l , i ) else dlet firstx :: restx = x in let ( truth , firstx2 , i2 ) = ( firstx l < i ) in if truth then hilo restx i2 h ( firstx2 : -: l ) else hilo restx i2 ( firstx2 : -: h ) l ;; (* Liste x in die Liste l einsortieren *) let rec qs x l = if - nil x then ( kill x ; l ) else dlet i :: restx = x in let ( high , low , i2 ) = hilo restx i [] [] in qs low ( i2 : -:( qs high l )) ;; Lineare Logik Lineare Typen Funktionale Programmiersprachen Seiteneffekte Direktupdates und Speichermanagement CLEAN und Uniqueness Typing CLEAN Lineare Typen Alexander Aumann Übersicht Was ist Clean? Clean ist eine rein funktionale, moderne Programmiersprache Hat den Ruf sehr performant zu sein Verwendet sogenannte Uniqueness-Types Uniqueness Types in Clean Sehr ähnlich zu linearen Typen Stellen sicher, dass zum Zeitpunkt der Auswertung nur eine Referenz auf sie existiert Keine Seiteneffekte beim Umgang mit Dateien, der Konsole oder der grafischen Ausgabe nötig Performanzkritische Anwendungen können unique-Arrays mit Direktupdate im Speicher verwenden Gliederung Lineare Typen Lineare Logik Lineare Typen Funktionale Programmiersprachen Seiteneffekte Direktupdates und Speichermanagement CLEAN und Uniqueness Typing Uniqueness Types Example 1 2 3 Alexander Aumann Übersicht Gliederung WriteFile : : [ Char ] * File -> * File WriteFile [ ] file = file WriteFile [ c : cs ] file = WriteFile cs ( fwritec c file ) Der * weist einem Typ das sogenannte “unique”-Attribut zu Beim Aufruf der Funktion wird garantiert, dass sie die einzige Referenz auf die Datei hält Die Datei kann später beliebig geteilt werden (< − > lineaere Typen) Sie verliert dann ihr *-Attribut und kann an Funktionen, die dieses erwarten, nicht länger übergeben werden Die folgende Funktion kompiliert nicht Example 1 2 Lineare Typen WriteToTuple : : [ Char ] File -> ( File , File ) WriteToTuple x file = (( WriteFile x file ) ,( WriteFile x file )) Lineare Typen Lineare Logik Lineare Typen Funktionale Programmiersprachen Seiteneffekte Direktupdates und Speichermanagement CLEAN und Uniqueness Typing Uniqueness Types Lineare Typen Alexander Aumann Übersicht Gliederung Wie sieht es beim Lesen aus? Eine Funktion, die nur lesend auf eine Datei zugreift, kann auch ein nicht-uniques File erhalten Damit sind die folgenden Funktionen kompilierbar Example 1 2 3 4 5 6 7 8 9 ReadXChars : : Int File -> [ Char ] ReadXChars x file | not ( readok & & ( x > 0)) = [] | otherwise = [ char : ReadXChars (x -1) fNewReadPtr ] where ( readok , char , fNewReadPtr ) = sfreadc file ReadToTuple : : Int File -> ( [ Char ] ,[ Char ] ) ReadToTuple x file = (( ReadXChars x file ) ,( ReadXChars x file )) Lineare Typen Lineare Logik Lineare Typen Funktionale Programmiersprachen Seiteneffekte Direktupdates und Speichermanagement CLEAN und Uniqueness Typing Umgang mit unique-Variablen Wie sieht das in der Praxis aus? Es gibt zahlreiche semantisch gleiche Möglichkeiten das wiederholte Schreiben in eine Datei in Clean auszudrücken Die folgenden drei sind die wichtigsten Example Möglichkeit 1 1 2 ChainedWrite : : [ Char ] [ Char ] * File -> * File ChainedWrite x y file = WriteFile y ( WriteFile x file ) Example Möglichkeit 2 1 2 3 4 ChainedWrite x y file = retfile where f il eO nc e Written = WriteFile x file retfile = WriteFile y fi le O nc eW r it te n Lineare Typen Alexander Aumann Übersicht Gliederung Lineare Typen Lineare Logik Lineare Typen Funktionale Programmiersprachen Seiteneffekte Direktupdates und Speichermanagement CLEAN und Uniqueness Typing Umgang mit unique-Variablen Lineare Typen Alexander Aumann Übersicht Das let-before Gliederung Lineare Typen Die dritte und eleganteste Möglichkeit ist das let-before (#) Lineare Logik Lineare Typen Funktionale Programmiersprachen Example 1 2 3 4 ChainedWrite x y file # fileA = WriteFile x file # fileB = WriteFile y fileA = fileB Oder sogar Example 1 2 3 4 ChainedWrite x y file # file = WriteFile x file # file = WriteFile y file = file Seiteneffekte Direktupdates und Speichermanagement CLEAN und Uniqueness Typing Das Weltbild von Clean Lineare Typen Alexander Aumann Übersicht Gliederung Lineare Typen Wie kommt man an eine Datei? Die Start-Funktion jedes Programms erhält ein “World”-Objekt Dieses ist unique -> es kann immer nur eine Welt geben Die Welt muss an Funktionen, die z.B. eine Datei öffnen übergeben werden Diese geben dann die unique-Datei zurück und die veränderte Welt Example 1 fopen : : String Int * w -> *( Bool ,* File ,* w ) | FileSystem w Lineare Logik Lineare Typen Funktionale Programmiersprachen Seiteneffekte Direktupdates und Speichermanagement CLEAN und Uniqueness Typing Zusammenfassung Lineare Typen Alexander Aumann Übersicht Gliederung Lineare Typen Lineare Logik Lineare Typen Funktionale Programmiersprachen Das können lineare Typen Lineare Typen machen den Zugriff auf Ressourcen sicher Lineare Typen verschaffen funktionalen Programmiersprachen die Möglichkeit mit der “echten Welt” zu interagieren In Clean ist dieses Konzept leicht angepasst überzeugend umgesetzt - eine tolle Sprache ;-) Seiteneffekte Direktupdates und Speichermanagement CLEAN und Uniqueness Typing