Typed Open Programming
Total Page:16
File Type:pdf, Size:1020Kb
Typed Open Programming A higher-order, typed approach to dynamic modularity and distribution Preliminary Version Andreas Rossberg Dissertation zur Erlangung des Grades des Doktors der Ingenieurwissenschaften der Naturwissenschaftlich-Technischen Fakult¨aten der Universit¨at des Saarlandes Saarbr¨ucken, 5. Januar 2007 Dekan: Prof. Dr. Andreas Sch¨utze Erstgutachter: Prof. Dr. Gert Smolka Zweitgutachter: Prof. Dr. Andreas Zeller ii Abstract In this dissertation we develop an approach for reconciling open programming – the development of programs that support dynamic exchange of higher-order values with other processes – with strong static typing in programming languages. We present the design of a concrete programming language, Alice ML, that consists of a conventional functional language extended with a set of orthogonal features like higher-order modules, dynamic type checking, higher-order serialisation, and concurrency. On top of these a flexible system of dynamic components and a simple but expressive notion of distribution is realised. The central concept in this design is the package, a first-class value embedding a module along with its interface type, which is dynamically checked whenever the module is extracted. Furthermore, we develop a formal model for abstract types that is not invalidated by the presence of primitives for dynamic type inspection, as is the case for the standard model based on existential quantification. For that purpose, we present an idealised language in form of an extended λ-calculus, which can express dynamic generation of types. This calculus is the first to combine and explore the interference of sealing and type inspection with higher-order singleton kinds, a feature for expressing sharing constraints on abstract types. A novel notion of abstracton kinds classifies abstract types. Higher-order type and kind coercions allow for modular translucent encapsulation of values at arbitrary type. Kurzdarstellung In dieser Dissertation entwickeln wir einen programmiersprachlichen Ansatz zur Verbindung offener Programmierung – der Entwicklung von Programmen, die das dynamische Laden und Austauschen h¨oherstufiger Werte mit anderen Prozessen erlauben – mit starker statischer Typ- isierung. Wir stellen das Design einer konkreten Programmiersprache namens Alice ML vor. Sie besteht aus einer konventionellen funktionalen Sprache, die um einen Satz orthogonaler Konzepte wie h¨oherstufige Modularisierung, dynamische Typ¨uberpr¨ufung, h¨oherstufige Serialisierung und Nebenl¨aufigkeit erweitert wurde. Darauf aufbauend ist ein flexibles System dynamischer Kom- ponenten sowie ein einfacher aber expressiver Ansatz f¨ur Verteilung verwirklicht. Zentral ist dabei das Konzept eines Pakets (package), welches ein Modul in Kombination mit seinem Schnittstellentyp in einen Wert einbettet, und bei der Extraktion des Moduls eine dynamis- che Typ¨uberpr¨ufung vornimmt. Weiterhin entwickeln wir einen theoretischen Ansatz zur Modellierung von abstrakten Typen, welcher im Gegensatz zum herk¨ommlichen formalen Modell existentieller Quantifizierung auch in Gegenwart dynamischer Typinspektion g¨ultig ist. Zu diesem Zweck definieren wir eine idealisierte Sprache in Form eines erweiterten λ-Kalk¨uls, der dynamische Typgenerierung ausdr¨ucken kann. Der Kalk¨ul kombiniert diese erstmals mit h¨oherstufigen ”Singleton Kinds, einem Sprachkonstrukt, welches Gleichheit von Typen ausdr¨ucken kann. Zur Klassifizierung abstrakter Typen werden Abstraktions-Kinds als verwandtes Konzept entwickelt. H¨oherstufige Konversionen auf Term- und Typebene erlauben zudem die nachtr¨agliche modulare Enkap- sulierung von Werten beliebigen Typs. iii Zusammenfassung Die zunehmende Verbreitung des Internets hat begonnen, die Struktur von Software nachhaltig zu ver¨andern. An die Stelle von in sich geschlossenen Programmen, die nur lokal operieren, treten mehr und mehr offene Applikationen, die dynamisch Daten mit anderen Prozessen im Netzwerk austauschen, oder von dort sogar neue Funktionalit¨at beziehen. Das offensichtlichste Beispiel f¨ur ein Programm dieser Kategorie ist ein Web-Browser. Auf programmiersprachlicher Ebene erfordert dieser Paradigmenwechsel eine verbesserte Un- terst¨utzung offener Programmierung, zu der wir Konzepte wie Modularit¨at, Dynamik, Porta- bilit¨at, Sicherheit, Verteilung und Nebenl¨aufigkeit z¨ahlen. Nur wenige existierende Sprachen sind bisher darauf ausgelegt. Zu ihnen geh¨oren vor allem die zu diesem Zweck entwickelte objektorientierte Sprache Java, die mittlerweile weite industrielle Verbreitung gefunden hat, und die im akademischen Umfeld entwickelte nebenl¨aufige Constraint-Sprache Oz. Diese setzt entsprechende Konzepte noch weitaus konsequenter um, insbesondere durch die einheitliche Repr¨asentation von Programmkomponenten und externen Daten, so dass beide beliebig gemis- cht werden k¨onnen. Diese Dissertation widmet sich einem spezifischen Aspekt offener Programmierung, der bis- lang von keinem der Vertreter auf befriedigende Weise gel¨ost wurde: der Kombination offener Programmierung mit einem expressiven, starken Typsystem. Ein Typsystem ist ein in die Pro- grammiersprache integriertes formales Werkzeug zur automatischen Verifikation bestimmter Pro- grammeigenschaften. Es weist jedem Programmkonstrukt einen Typ zu, eine logische Formel, die das bei Ausf¨uhrung des Konstrukts zu erwartende Resultat klassifiziert. Die damit m¨oglichen Konsistenzpr¨ufungen k¨onnen die Zuverl¨assigkeit von Software verbessern. Moderne Program- miersprachen bieten zudem die M¨oglichkeit, die Typstruktur um benutzerdefinierte, sogenannte abstrakte Typen zu erweitern, welche die Festlegung gewisser Zugriffsbeschr¨ankungen erlauben. Wenn die Semantik der Programmiersprache verhindert, dass diese Zugriffsbeschr¨ankungen um- gangen werden k¨onnen, so spricht man von Abstraktionssicherheit. Diese garantiert Modu- larit¨atseigenschaften und steigert damit vor allem die Wartbarkeit von Programmen. Typ¨uberpr¨ufungen erfolgen naturgem¨ass vor der Ausf¨uhrung eines Programmes, ¨ublicherweise durch den Ubersetzer¨ der verwendeten Programmiersprache. Dadurch entsteht ein inh¨arenter Konflikt mit offener Programmierung, da in einem offenen Ansatz im Allgemeinen nicht alle Programmteile vorweg bekannt sind und analysiert werden k¨onnen. Es ist deshalb unausweich- lich, bestimmte Typ¨uberpr¨ufungen in die Laufzeit des Programms zu verlagern. Ein seit langem bekannter Ansatz daf¨ur ist die Einbringung eines speziellen universellen Typs Dynamic, der Werte der Sprache gepaart mit ihrem jeweiligen Typ beinhaltet. Die Extraktion eines Wertes er- folgt explizit und erfordert die Angabe eines oder mehrerer erwarteter Zieltypen, die dynamisch abgeglichen werden. Leider haben sich Dynamics jedoch in der Praxis als zu unhandlich er- wiesen. Zudem ergeben sich durch die M¨oglichkeit des dynamischen Typabgleichs semantische Implikationen, die unter anderem die Abstraktionssicherheit abstrakter Typen beeintr¨achtigen. Wir n¨ahern uns diesen Problemen von zwei Seiten an. Zum einen beschreiben wir das Design einer konkreten Sprache names Alice ML, welche typisierte offene Programmierung erm¨oglicht. Dabei handelt es sich um einen Dialekt der funktionalen Sprache Standard ML, die durch einen relativ kleinen Satz orthogonaler und hinreichen einfacher Sprachkonstrukte erweitert wurde. Dabei handelt es sich zun¨achst um Pickling zum serialisierten Import und Export h¨oherstufiger iv Werte, verschiedene Formen von Futures f¨ur die Synchronisation nebenl¨aufiger Berechnungen, sowie Module h¨oherer Ordnung, welche die Sprache um wichtige Abstraktionsm¨oglichkeiten erg¨anzen. Die meisten dieser Konstrukte sind bekannt und f¨ur sich gut verstanden, aber bisher nicht in dieser Form und zu diesem Zweck in einem koh¨arenten Design integriert worden. Neu ist ausserdem das zentrale Konzept von Paketen (packages), welches das Kernproblem der dy- namischen Typisierung l¨ost. Es ¨ahnelt der Idee von Dynamics, jedoch werden nicht einzelne Werte, sondern komplette Module eingebettet. Die feink¨ornige Typunterscheidung weicht so einem strukturellen Inklusionstest auf Modulschnittstellen, der robust gegen¨uber Erweiterun- gen ist und eine Handhabung auf hohem Abstraktionsgrad erlaubt. Auf Grundlage dieser Ba- siskonzepte definiert die Sprache einen flexiblen, typsicheren Begriff von Komponenten, der nicht nur bedarfsgetriebenes dynamisches Laden erm¨oglicht, sondern Komponenten als Werte erster Klasse verf¨ugbar macht, die dynamisch berechnet und aus einem Prozess exportiert werden k¨onnen. Mit Hilfe dieser Idee wiederum ist ein vergleichsweise einfacher aber expressiver Ansatz f¨ur verteilte Programmierung m¨oglich, bei dem Verbindungen zwischen Prozessen durch den initialen Austausch einer dynamisch berechneten Komponente aufgebaut werden. Das Konzept von programmierbaren Komponentenmanagern erlaubt es dem Empf¨angerprozess dabei, gezielte Sicherheitsstrategien durch Einschr¨ankung der Importrechte f¨ur die empfangene Komponente zu realisieren. Eine nahezu vollst¨andige Implementation von Alice ML wurde realisiert und steht als offene Software zur Verf¨ugung. Zum anderen entwickeln wir einen theoretischen Ansatz zur Modellierung von Typabstrak- tion, der Abstraktionssicherheit auch in Gegenwart dynamischer Typinspektion sicherstellt. Zu diesem Zweck f¨uhren wir eine idealisierte Formalisierung der Sprache Alice ML ein, die auf dem polymorphen λ-Kalk¨ul basiert. Sie modelliert zentrale Konzepte des Typ- und Modulsys- tems: h¨oherstufige Typen spiegeln Polymorphismus und parametrisierte Module wider, Singleton Kinds k¨onnen