23 research outputs found
Modelling homogeneous generative meta-programming
Homogeneous generative meta-programming (HGMP) enables the generation of program fragments at compile-time or run-time. We present a foundational calculus which can model both compile-time and run-time evaluated HGMP, allowing us to model, for the first time, languages such as Template Haskell. The calculus is designed such that it can be gradually enhanced with the features needed to model many of the advanced features of real languages. We demonstrate this by showing how a simple, staged type system as found in Template Haskell can be added to the calculus
Squid: Type-Safe, Hygienic, and Reusable Quasiquotes
Quasiquotes have been shown to greatly simplify the task of metaprogramming. This is in part because they hide the data structures of the intermediate representation (IR), instead allowing metaprogrammers to use the concrete syntax of the language they manipulate. Scala has had ``syntactic'' quasiquotes for a long time, but still misses a statically-typed version like in MetaOCaml, Haskell and F#. This safer flavor of quasiquotes has been particularly useful for staging and domain-specific languages. In this paper we present Squid, a metaprogramming system for Scala that fills this gap. Squid quasiquotes are novel in three ways: they are the first statically-typed quasiquotes we know that allow code inspection (via pattern matching); they are implemented purely as a macro library, without modifications to the compiler; and they are reusable in the sense that they can manipulate different IRs. Adapting (or binding) a new IR to Squid is done simply by implementing a well-defined interface in the style of object algebras (i.e., tagless-final). We detail how Squid is implemented, leveraging the metaprogramming tools already offered by Scala, and show three application examples: the definition of a binding for a DSL in the style of LMS; a safe ANF conversion; and the introduction of type-safe, hygienic macros as an alternative to the current macro system
Concrete Syntax with Black Box Parsers
Context: Meta programming consists for a large part of matching, analyzing,
and transforming syntax trees. Many meta programming systems process abstract
syntax trees, but this requires intimate knowledge of the structure of the data
type describing the abstract syntax. As a result, meta programming is
error-prone, and meta programs are not resilient to evolution of the structure
of such ASTs, requiring invasive, fault-prone change to these programs.
Inquiry: Concrete syntax patterns alleviate this problem by allowing the meta
programmer to match and create syntax trees using the actual syntax of the
object language. Systems supporting concrete syntax patterns, however, require
a concrete grammar of the object language in their own formalism. Creating such
grammars is a costly and error-prone process, especially for realistic
languages such as Java and C++. Approach: In this paper we present Concretely,
a technique to extend meta programming systems with pluggable concrete syntax
patterns, based on external, black box parsers. We illustrate Concretely in the
context of Rascal, an open-source meta programming system and language
workbench, and show how to reuse existing parsers for Java, JavaScript, and
C++. Furthermore, we propose Tympanic, a DSL to declaratively map external AST
structures to Rascal's internal data structures. Tympanic allows implementors
of Concretely to solve the impedance mismatch between object-oriented class
hierarchies in Java and Rascal's algebraic data types. Both the algebraic data
type and AST marshalling code is automatically generated. Knowledge: The
conceptual architecture of Concretely and Tympanic supports the reuse of
pre-existing, external parsers, and their AST representation in meta
programming systems that feature concrete syntax patterns for matching and
constructing syntax trees. As such this opens up concrete syntax pattern
matching for a host of realistic languages for which writing a grammar from
scratch is time consuming and error-prone, but for which industry-strength
parsers exist in the wild. Grounding: We evaluate Concretely in terms of source
lines of code (SLOC), relative to the size of the AST data type and marshalling
code. We show that for real programming languages such as C++ and Java, adding
support for concrete syntax patterns takes an effort only in the order of
dozens of SLOC. Similarly, we evaluate Tympanic in terms of SLOC, showing an
order of magnitude of reduction in SLOC compared to manual implementation of
the AST data types and marshalling code. Importance: Meta programming has
applications in reverse engineering, reengineering, source code analysis,
static analysis, software renovation, domain-specific language engineering, and
many others. Processing of syntax trees is central to all of these tasks.
Concrete syntax patterns improve the practice of constructing meta programs.
The combination of Concretely and Tympanic has the potential to make concrete
syntax patterns available with very little effort, thereby improving and
promoting the application of meta programming in the general software
engineering context
Lightweight Modular Staging: A Pragmatic Approach to Runtime Code Generation and Compiled DSLs
Good software engineering practice demands generalization and abstraction, whereas high performance demands specialization and concretization. These goals are at odds, and compilers can only rarely translate expressive high-level programs to modern hardware platforms in a way that makes best use of the available resources. Generative programming is a promising alternative to fully automatic translation. Instead of writing down the target program directly, developers write a program generator, which produces the target program as its output. The generator can be written in a high-level, generic style and still produce efficient, specialized target programs. In practice, however, developing high-quality program generators requires a very large effort that is often hard to amortize. We present Lightweight Modular Staging (LMS), a generative programming approach that lowers this effort significantly. LMS seamlessly combines program generator logic with the generated code in a single program, using only types to distinguish the two stages of execution. Through extensive use of component technology, LMS makes a reusable and extensible compiler framework available at the library level, allowing programmers to tightly integrate domain-specific abstractions and optimizations into the generation process, with common generic optimizations provided by the framework. LMS is well suited to develop embedded domain specific languages (DSLs) and has been used to develop powerful performance-oriented DSLs for demanding domains such as machine learning, with code generation for heterogeneous platforms including GPUs. LMS has also been used to generate SQL for embedded database queries and JavaScript for web applications
Lightweight Modular Staging: A Pragmatic Approach to Runtime Code Generation and Compiled DSLs
Software engineering demands generality and abstraction, performance demands specialization and concretization. Generative programming can provide both, but the effort required to develop high-quality program generators likely offsets their benefits, even if a multi-stage programming language is used. We present lightweight modular staging, a library-based multi-stage programming approach that breaks with the tradition of syntactic quasi-quotation and instead uses only types to distinguish between binding times. Through extensive use of component technology, lightweight modular staging makes an optimizing compiler framework available at the library level, allowing programmers to tightly integrate domain-specific abstractions and optimizations into the generation process. We argue that lightweight modular staging enables a form of language virtualization, i.e. allows to go from a pure-library embedded language to one that is practically equivalent to a stand-alone implementation with only modest effort
A dependently typed multi-stage calculus
Programming Languages and Systems: 17th Asian Symposium, APLAS 2019, Nusa Dua, Bali, Indonesia, December 1â4, 2019. Part of the Lecture Notes in Computer Science book series (LNCS, volume 11893). Also part of the Programming and Software Engineering book sub series (LNPSE, volume 11893).We study a dependently typed extension of a multi-stage programming language Ă la MetaOCaml, which supports quasi-quotation and cross-stage persistence for manipulation of code fragments as first-class values and an evaluation construct for execution of programs dynamically generated by this code manipulation. Dependent types are expected to bring to multi-stage programming enforcement of strong invariantâbeyond simple type safetyâon the behavior of dynamically generated code. An extension is, however, not trivial because such a type system would have to take stages of typesâroughly speaking, the number of surrounding quotationsâinto account. To rigorously study properties of such an extension, we develop λMD, which is an extension of Hanada and Igarashiâs typed calculus λâč% with dependent types, and prove its properties including preservation, confluence, strong normalization for full reduction, and progress for staged reduction. Motivated by code generators that generate code whose type depends on a value from outside of the quotations, we argue the significance of cross-stage persistence in dependently typed multi-stage programming and certain type equivalences that are not directly derived from reduction rules
Fluent APIs in Functional Languages (full version)
Fluent API is an object-oriented pattern for smart and elegant embedded DSLs.
As fluent API designs typically rely on function overloading, they are hard to
realize in functional programming languages. We show how to write functional
fluent APIs using parametric polymorphism and unification instead of
overloading. Our designs support all regular and deterministic context-free
DSLs and beyond
Building-Blocks for Performance Oriented DSLs
Domain-specific languages raise the level of abstraction in software
development. While it is evident that programmers can more easily reason about
very high-level programs, the same holds for compilers only if the compiler has
an accurate model of the application domain and the underlying target platform.
Since mapping high-level, general-purpose languages to modern, heterogeneous
hardware is becoming increasingly difficult, DSLs are an attractive way to
capitalize on improved hardware performance, precisely by making the compiler
reason on a higher level. Implementing efficient DSL compilers is a daunting
task however, and support for building performance-oriented DSLs is urgently
needed. To this end, we present the Delite Framework, an extensible toolkit
that drastically simplifies building embedded DSLs and compiling DSL programs
for execution on heterogeneous hardware. We discuss several building blocks in
some detail and present experimental results for the OptiML machine-learning
DSL implemented on top of Delite.Comment: In Proceedings DSL 2011, arXiv:1109.032
MELT - a Translated Domain Specific Language Embedded in the GCC Compiler
The GCC free compiler is a very large software, compiling source in several
languages for many targets on various systems. It can be extended by plugins,
which may take advantage of its power to provide extra specific functionality
(warnings, optimizations, source refactoring or navigation) by processing
various GCC internal representations (Gimple, Tree, ...). Writing plugins in C
is a complex and time-consuming task, but customizing GCC by using an existing
scripting language inside is impractical. We describe MELT, a specific
Lisp-like DSL which fits well into existing GCC technology and offers
high-level features (functional, object or reflexive programming, pattern
matching). MELT is translated to C fitted for GCC internals and provides
various features to facilitate this. This work shows that even huge, legacy,
software can be a posteriori extended by specifically tailored and translated
high-level DSLs.Comment: In Proceedings DSL 2011, arXiv:1109.032