Extensible Languages for Flexible and Principled Domain Abstraction
Total Page:16
File Type:pdf, Size:1020Kb
Extensible Languages for Flexible and Principled Domain Abstraction Dissertation for the degree of Doctor of Natural Sciences Submitted by Sebastian Thore Erdweg, M.Sc., born March 14, 1985 in Frankfurt/Main Department of Mathematics and Computer Science, Philipps-Universit¨at Marburg Referees: Prof. Dr. Klaus Ostermann Dr. Eelco Visser Prof. Dr. Ralf L¨ammel Submitted November 28, 2012. Defended March 06, 2013. Marburg, 2013. Abstract Most programming languages are designed for general-purpose software development in a one-size-fits-all fashion: They provide the same set of language features and constructs for all possible applications programmers ever may want to develop. As with shoes, the one-size-fits-all solution grants a good fit to few applications only. The trend toward domain-specific languages, model-driven development, and language- oriented programming counters general-purpose languages by promoting the use of domain abstractions that facilitate domain-specific language features and constructs tailored to certain application domains. In particular, domain abstraction avoids the need for encoding domain concepts with general-purpose language features and thus allows programmers to program at the same abstraction level as they think. Unfortunately, current approaches to domain abstraction cannot deliver on the promises of domain abstraction. On the one hand, approaches that target internal domain-specific languages lack flexibility regarding the syntax, static checking, and tool support of domain abstractions, which limits the level of actually achieved domain abstraction. On the other hand, approaches that target external domain-specific languages lack important principles, such as modular reasoning and composition of domain abstractions, which inhibits the applicability of these approaches in the development of larger software systems. In this thesis, we pursue a novel approach that unifies the advantages of internal and external domain-specific languages to support flexible and principled domain abstraction. We propose library-based extensible programming languages as a basis for domain abstraction. In an extensible language, domain abstraction can be realized by extending the language with domain-specific syntax, static analysis, and tool support. This enables domain abstractions as flexible as external domain-specific languages. To ensure the com- pliance with important software-development principles, we organize language extensions as libraries and use simple import statements to activate extensions. This facilitates mo- dular reasoning (by inspecting import statements), supports the composition of domain abstractions (by importing multiple extensions), and allows uniform self-application of language extensions in the development of further extensions (by importing extensions in an extension definition). A library-based organization of extensions enables domain abstractions as principled as internal domain-specific languages. We designed and implemented SugarJ, a library-based extensible programming language on top of Java. SugarJ libraries can declare and export extensions of SugarJ's syntax, static analysis, and editor support. Thereby, a syntactic extension consists of an extended syntax and a desugaring transformation from the extended syntax into SugarJ base syntax, an analysis extension matches on part of the current file’s abstract syntax tree iii and produces a list of errors, and an editor extension declares editor services such as coloring or code completion for certain language constructs. SugarJ extensions are fully self-applicable: An extended syntax can desugar into the declaration of another extensions, an extended analysis can check the declaration of an extension, and an extended editor can assist developers in writing extensions. To process a source file with extensions, the SugarJ compiler and IDE inspect the imported libraries to determine active extensions. The compiler and IDE adapt the parser, code generator, analyzer, and editor of the source file according to the active extensions. In this thesis, we do not only describe the design and implementation of SugarJ, but also report on extensions of the original design. In particular, we designed and implemented a generalization of the SugarJ compiler that supports alternative base languages besides Java. Using this generalization, we developed the library-based extensible programming languages SugarHaskell, SugarProlog, and SugarFomega. Furthermore, we developed an extension of SugarJ that supports polymorphic domain abstraction and ensures com- munication integrity. Polymorphic domain abstraction enables programmers to provide multiple desugarings for the same domain-specific syntax. This increases the flexibility of SugarJ and supports scenarios known from model-driven development. Communication integrity specifies that components of a software system may communicate over explicit channels only. This is interesting in the context of code generation where it effective- ly prohibits the generation of implicit module dependencies. We augmented SugarJ's principles by enforcing communication integrity. On the basis of SugarJ and numerous case studies, we argue that flexible and principled domain abstraction constitutes a scalable programming model for the development of complex software systems. Zusammenfassung Die meisten Programmiersprachen werden als Universalsprachen entworfen. Unabh¨angig von der zu entwickelnden Anwendung, stellen sie die gleichen Sprachfeatures und Sprach- konstrukte zur Verfugung.¨ Solch universelle Sprachfeatures ignorieren jedoch die spezifi- schen Anforderungen, die viele Softwareprojekte mit sich bringen. Als Gegenkraft zu Universalsprachen f¨ordern dom¨anenspezifische Programmiersprachen, modellgetriebene Softwareentwicklung und sprachorientierte Programmierung die Ver- wendung von Dom¨anenabstraktion, welche den Einsatz von dom¨anenspezifischen Sprach- features und Sprachkonstrukten erm¨oglicht. Insbesondere erlaubt Dom¨anenabstraktion Programmieren auf dem selben Abstraktionsniveau zu programmieren wie zu denken und vermeidet dadurch die Notwendigkeit Dom¨anenkonzepte mit universalsprachlichen Features zu kodieren. Leider erm¨oglichen aktuelle Ans¨atze zur Dom¨anenabstraktion nicht die Entfaltung ihres ganzen Potentials. Einerseits mangelt es den Ans¨atzen fur¨ interne dom¨anenspezifische Sprachen an Flexibilit¨at bezuglich¨ der Syntax, statischer Analysen, und Werkzeugun- terstutzung,¨ was das tats¨achlich erreichte Abstraktionsniveau beschr¨ankt. Andererseits mangelt es den Ans¨atzen fur¨ externe dom¨anenspezifische Sprachen an wichtigen Prinzipien, wie beispielsweise modularem Schließen oder Komposition von Dom¨anenabstraktionen, was die Anwendbarkeit dieser Ans¨atze in der Entwicklung gr¨oßerer Softwaresysteme einschr¨ankt. Wir verfolgen in der vorliegenden Doktorarbeit einen neuartigen Ansatz, welcher die Vorteile von internen und externen dom¨anenspezifischen Sprachen vereint um flexible und prinzipientreue Dom¨anenabstraktion zu unterstutzen.¨ Wir schlagen bibliotheksbasierte erweiterbare Programmiersprachen als Grundlage fur¨ Dom¨anenabstraktion vor. In einer erweiterbaren Sprache kann Dom¨anenabstraktion durch die Erweiterung der Sprache mit dom¨anenspezifischer Syntax, statischer Analyse, und Werkzeugunterstutzung¨ erreicht werden . Dies erm¨oglicht Dom¨anenabstraktionen die selbe Flexibilit¨at wie externe dom¨anenspezifische Sprachen. Um die Einhaltung ublicher¨ Prinzipien zu gew¨ahrleisten, organisieren wir Spracherweiterungen als Bibliotheken und verwenden einfache Import-Anweisungen zur Aktivierung von Erweiterungen. Dies er- laubt modulares Schließen (durch die Inspektion der Import-Anweisungen), unterstutzt¨ die Komposition von Dom¨anenabstraktionen (durch das Importieren mehrerer Erwei- terungen), und erm¨oglicht die uniforme Selbstanwendbarkeit von Spracherweiterungen in der Entwicklung zukunftiger¨ Erweiterungen (durch das Importieren von Erweiterun- gen in einer Erweiterungsdefinition). Die Organisation von Erweiterungen in Form von Bibliotheken erm¨oglicht Dom¨anenabstraktionen die selbe Prinzipientreue wie interne dom¨anenspezifische Sprachen. v Wir haben die bibliotheksbasierte erweiterbare Programmiersprache SugarJ entworfen und implementiert. SugarJ Bibliotheken k¨onnen Erweiterungen der Syntax, der statischen Analyse, und der Werkzeugunterstutzung¨ von SugarJ deklarieren. Eine syntaktische Erweiterung besteht dabei aus einer erweiterten Syntax und einer Transformation der erweiterten Syntax in die Basissyntax von SugarJ. Eine Erweiterung der Analyse testet Teile des abstrakten Syntaxbaums der aktuellen Datei und produziert eine Liste von Feh- lern. Eine Erweiterung der Werkzeugunterstutzung¨ deklariert Dienste wie Syntaxf¨arbung oder Codevervollst¨andigung fur¨ bestimmte Sprachkonstrukte. SugarJ Erweiterungen sind vollkommen selbstanwendbar: Eine erweiterte Syntax kann in eine Erweiterungs- definition transformiert werden, eine erweiterte Analyse kann Erweiterungsdefinitionen testen, und eine erweiterte Werkzeugunterstutzung¨ kann Entwicklern beim Definieren von Erweiterungen assistieren. Um eine Quelldatei mit Erweiterungen zu verarbeiten, inspizieren der SugarJ Compiler und die SugarJ IDE die importierten Bibliotheken um die aktiven Erweiterungen zu bestimmen. Der Compiler und die IDE adaptieren den Parser, den Codegenerator, die Analyseroutine und die Werkzeugunterstutzung¨ der Quelldatei entsprechend der aktiven Erweiterungen. Wir beschreiben in der vorliegenden Doktorarbeit nicht nur das Design und die Imple-