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, MSc born March 14, 1985 in Frankfurt/Main Department of Mathematics and Computer Science Philipps-Universität Marburg Referees: Prof. Dr. Klaus Ostermann Dr. Eelco Visser Prof. Dr. Ralf Lämmel Submitted November 28, 2012. Defended March 06, 2013. Marburg, 2013. Erdweg, Sebastian: Extensible Languages for Flexible and Principled Domain Abstraction Dissertation, Philipps-Universität Marburg (1180), 2013. Curriculum vitae 2007, Bachelor of Science, TU Darmstadt 2009, Master of Science, Aarhus University Cover photo by Tellerdreher Photography, 2012. Abstract Most programming languages are designed for general-purpose software deve- lopment 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 promo- ting 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 do- main 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 compliance with important software-development principles, we organize language extensions as libraries and use simple import statements to activate extensions. This facilitates modular reasoning (by inspec- ting import statements), supports the composition of domain abstractions (by iii 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 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 exten- ded 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, SugarPro- log, and SugarFomega. Furthermore, we developed an extension of SugarJ that supports polymorphic domain abstraction and ensures communication integri- ty. Polymorphic domain abstraction enables programmers to provide multiple desugarings for the same domain-specific syntax. This increases the flexibili- ty 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 effectively 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. Un- abhängig von der zu entwickelnden Anwendung, stellen sie die gleichen Sprach- features und Sprachkonstrukte zur Verfügung. Solch universelle Sprachfeatures ignorieren jedoch die spezifischen Anforderungen, die viele Softwareprojekte mit sich bringen. Als Gegenkraft zu Universalsprachen fördern domänenspezifische Program- miersprachen, modellgetriebene Softwareentwicklung und sprachorientierte Pro- grammierung die Verwendung von Domänenabstraktion, welche den Einsatz von domänenspezifischen Sprachfeatures und Sprachkonstrukten ermöglicht. Insbesondere erlaubt Domänenabstraktion Programmieren auf dem selben Ab- straktionsniveau zu programmieren wie zu denken und vermeidet dadurch die Notwendigkeit Domänenkonzepte mit universalsprachlichen Features zu kodieren. Leider ermöglichen aktuelle Ansätze zur Domänenabstraktion nicht die Ent- faltung ihres ganzen Potentials. Einerseits mangelt es den Ansätzen für interne domänenspezifische Sprachen an Flexibilität bezüglich der Syntax, statischer Analysen, und Werkzeugunterstützung, was das tatsächlich erreichte Abstrakti- onsniveau beschränkt. Andererseits mangelt es den Ansätzen für externe domä- nenspezifische Sprachen an wichtigen Prinzipien, wie beispielsweise modularem Schließen oder Komposition von Domänenabstraktionen, was die Anwendbarkeit dieser Ansätze in der Entwicklung größerer Softwaresysteme einschränkt. Wir verfolgen in der vorliegenden Doktorarbeit einen neuartigen Ansatz, welcher die Vorteile von internen und externen domänenspezifischen Sprachen vereint um flexible und prinzipientreue Domänenabstraktion zu unterstützen. Wir schlagen bibliotheksbasierte erweiterbare Programmiersprachen als Grund- lage für Domänenabstraktion vor. In einer erweiterbaren Sprache kann Domä- nenabstraktion durch die Erweiterung der Sprache mit domänenspezifischer Syntax, statischer Analyse, und Werkzeugunterstützung erreicht werden . Dies ermöglicht Domänenabstraktionen die selbe Flexibilität wie externe domänen- spezifische Sprachen. Um die Einhaltung üblicher Prinzipien zu gewährleisten, organisieren wir Spracherweiterungen als Bibliotheken und verwenden einfache Import-Anweisungen zur Aktivierung von Erweiterungen. Dies erlaubt modu- v lares Schließen (durch die Inspektion der Import-Anweisungen), unterstützt die Komposition von Domänenabstraktionen (durch das Importieren mehrerer Erweiterungen), und ermöglicht die uniforme Selbstanwendbarkeit von Spracher- weiterungen in der Entwicklung zukünftiger Erweiterungen (durch das Importie- ren von Erweiterungen in einer Erweiterungsdefinition). Die Organisation von Erweiterungen in Form von Bibliotheken ermöglicht Domänenabstraktionen die selbe Prinzipientreue wie interne domänenspezifische Sprachen. Wir haben die bibliotheksbasierte erweiterbare Programmiersprache SugarJ entworfen und implementiert. SugarJ Bibliotheken können Erweiterungen der Syntax, der statischen Analyse, und der Werkzeugunterstützung 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 Syn- taxbaums der aktuellen Datei und produziert eine Liste von Fehlern. Eine Erweiterung der Werkzeugunterstützung deklariert Dienste wie Syntaxfärbung oder Codevervollständigung für bestimmte Sprachkonstrukte. SugarJ Erweite- rungen sind vollkommen selbstanwendbar: Eine erweiterte Syntax kann in eine Erweiterungsdefinition transformiert werden, eine erweiterte Analyse kann Er- weiterungsdefinitionen testen, und eine erweiterte Werkzeugunterstützung 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 be- stimmen. Der