Conference PaperPDF Available

A Strafunski Application Letter

Authors:

Abstract and Figures

Strafunski is a Haskell-centred software bundle for implementing language processing components—most notably program analyses and transformations. Typical application areas include program optimisation, refactoring, software metrics, software re- and reverse engineering. Strafunski started out as generic programming library complemented by generative tool support to address the concern of generic traversal over typed representations of parse trees in a scalable manner. Meanwhile, Strafunski also encompasses means of integrating external components such as parsers, pretty printers, and graph visualisation tools. In a selection of case studies, we demonstrate that typed functional programming in Haskell, augmented with Strafunski ’s support for generic traversal and external components, is very appropriate for the development of practical language processors. In particular, we discuss using Haskell for Cobol reverse engineering, Java code metrics, and Haskell re-engineering.
Content may be subject to copyright.
A preview of the PDF is not available
... In this section we introduce Ztrategic, our embedding of strategic programming using generic zippers. The embedding directly follows the work of Laemmel and Visser [17] on the Strafunski library [18]. ...
Chapter
Strategic term rewriting and attribute grammars are two powerful programming techniques widely used in language engineering. The former relies on strategies (recursion schemes) to apply term rewrite rules in defining transformations, while the latter is suitable for expressing context-dependent language processing algorithms. Each of these techniques, however, is usually implemented by its own powerful and large processor system. As a result, it makes such systems harder to extend and to combine. We present the embedding of both strategic tree rewriting and attribute grammars in a zipper-based, purely functional setting. The embedding of the two techniques in the same setting has several advantages: First, we easily combine/zip attribute grammars and strategies, thus providing language engineers the best of the two worlds. Second, the combined embedding is easier to maintain and extend since it is written in a concise and uniform setting. We show the expressive power of our library in optimizing Haskell let expressions, expressing several Haskell refactorings and solving several language processing tasks for an Oberon-0 compiler.
... In this section we introduce the embedding of strategic programming using generic zippers. Our embedding directly follows the work of Laemmel and Visser [16] on the Strafunski library [17]. Before we present the powerful and reusable strategic functions providing control on tree traversals, such as top-down, bottom-up, innermost, etc., let us show some simple basic combinators that work at the zipper level, and are the building blocks of our embedding. ...
Preprint
Full-text available
Strategic term rewriting and attribute grammars are two powerful programming techniques widely used in language engineering. The former, relies on strategies to apply term rewrite rules in defining language transformations, while the latter is suitable to express context-dependent language processing algorithms. Each of these techniques, however, is usually implemented by its own powerful and large language processor system. As a result, it makes such systems harder to extend and to combine. In this paper, we present the embedding of both strategic tree rewriting and attribute grammars in a zipper-based, purely functional setting. Zippers provide a simple, but generic tree-walk mechanism that is the building block technique we use to express the purely-functional embedding of both techniques. The embedding of the two techniques in the same setting has several advantages: First, we easily combine/zip attribute grammars and strategies, thus providing language engineers the best of the two worlds. Second, the combined embedding is easier to maintain and extend since it is written in a concise and uniform setting. This results in a very small library which is able to express advanced (static) analysis and transformation tasks. We show the expressive power of our library in optimizing |Haskell| let expressions, expressing several |Haskell| refactorings and solving several language processing tasks of the LDTA Tool Challenge.
... Statically Typed Strategies. Typing strategies was pursued by Lämmel and Visser [16] in the context of the Strafunski Haskell library for generic programming inspired by Stratego [17]. They identified the concepts of type preserving and type unifying strategies. ...
Conference Paper
Full-text available
... We also relied on the recently developed visitors library [35] to automatically generate boilerplate code for traversing and processing the abstract syntax trees. This library provides similar functionality to that found in Haskell's SYB [18] and Strafunski [19] libraries, or the Stratego/XT framework [10]. ...
Conference Paper
Full-text available
We present an abstract, set-theoretic denotational semantics for a significant subset of OCaml and its module system in order to reason about the correctness of renaming value bindings. Our abstract semantics captures information about the binding structure of programs. Crucially for renaming, it also captures information about the relatedness of different declarations that is induced by the use of various different language constructs (e.g. functors, module types and module constraints). Correct renamings are precisely those that preserve this structure. We demonstrate that our semantics allows us to prove various high-level, intuitive properties of renamings. We also show that it is sound with respect to a (domain-theoretic) denotational model of the operational behaviour of programs. This formal framework has been implemented in a prototype refactoring tool for OCaml that performs renaming.
... Strategy combinators allow the user to take a set of simple single-node rewrites, and, in a single line of code, lift them into complicated traversal patterns involving contextual and conditional rewriting. We do not discuss the design of compstrat in detail here, other than noting that it provides similar functionality to other strategy combinator libraries such as Scrap Your Boilerplate (Zhang et al. 2015), Strafunski (Lämmel and Visser 2003), and KURE (Gill 2009). ...
Article
We present a new approach for building source-to-source transformations that can run on multiple programming languages, based on a new way of representing programs called incremental parametric syntax. We implement this approach in our Cubix system, and construct incremental parametric syntaxes for C, Java, JavaScript, Lua, and Python, demonstrating three multi-language program transformations that can run on all of them. Our evaluation shows that (1) once a transformation is written, relatively little work is required to configure it for a new language (2) transformations built this way output readable code which preserve the structure of the original, according to participants in our human study, and (3) despite dealing with many languages, our transformations can still handle language corner-cases, and pass 90% of compiler test suites.
Article
Full-text available
https://deepblue.lib.umich.edu/bitstream/2027.42/155872/4/30YRefactoring.pdf
Preprint
Full-text available
Due to the growing complexity of software systems, there has been a dramatic increase and industry demand for tools and techniques on software refactoring in the last ten years, defined traditionally as a set of program transformations intended to improve the system design while preserving the behavior. Refactoring studies are expanded beyond code-level restructuring to be applied at different levels (architecture, model, requirements, etc.), adopted in many domains beyond the object-oriented paradigm (cloud computing, mobile, web, etc.), used in industrial settings and considered objectives beyond improving the design to include other non-functional requirements (e.g., improve performance, security, etc.). Thus, challenges to be addressed by refactoring work are, nowadays, beyond code transformation to include, but not limited to, scheduling the opportune time to carry refactoring, recommendations of specific refactoring activities, detection of refactoring opportunities, and testing the correctness of applied refactorings. Therefore, the refactoring research efforts are fragmented over several research communities, various domains, and objectives. To structure the field and existing research results, this paper provides a systematic literature review and analyzes the results of 3183 research papers on refactoring covering the last three decades to offer the most scalable and comprehensive literature review of existing refactoring research studies. Based on this survey, we created a taxonomy to classify the existing research, identified research trends, and highlighted gaps in the literature and avenues for further research.
Article
Full-text available
We present a new approach for building source-to-source transformations that can run on multiple programming languages, based on a new way of representing programs called incremental parametric syntax. We implement this approach in Haskell in our Cubix system, and construct incremental parametric syntaxes for C, Java, JavaScript, Lua, and Python. We demonstrate a whole-program refactoring tool that runs on all of them, along with three smaller transformations that each run on several. Our evaluation shows that (1) once a transformation is written, little work is required to configure it for a new language (2) transformations built this way output readable code which preserve the structure of the original, according to participants in our human study, and (3) our transformations can still handle language corner-cases, as validated on compiler test suites.
Article
Observing intermediate values helps to understand what is going on when your program runs. For lazy functional languages Gill presented an observation method that preserves the program’s semantics. However, users need to define for each type how its values are observed: a laborious task and a mistake can yield misleading observations and even cause non-termination. Here we define how any value can be observed based on the structure of its type by applying generic programming. Furthermore, we present an extension to specify per observation point how much to observe of a value. We discuss how to obtain behaviour dependent on class membership with type-generic programming and with meta programming.
Conference Paper
Observing intermediate values helps to understand what is going on when your program runs. Gill presented an observation method for lazy functional languages that preserves the program’s semantics. However, users need to define for each type how its values are observed: a laborious task and strictness of the program can easily be affected. Here we define how any value can be observed based on the structure of its type by applying generic programming frameworks. Furthermore we present an extension to specify per observation point how much to observe of a value. We discuss especially functional values and behaviour based on class membership in generic programming frameworks.
Article
Full-text available
XT bundles existing and newly developed program transformation libraries and tools into an open framework that supports component-based development of program transformations. We discuss the roles of XT's constituents in the development process of program transformation tools, as well as some experiences with building program transformation systems with XT.
Article
Full-text available
In previous work, we have introduced functional strategies, that is, first-class generic functions that can traverse into terms of any type while mixing uniform and type-specific behaviour. In the present paper, we give a detailed description of one particular Haskell-based model of functional strategies. This model is characterised as follows. Firstly, we employ first-class polymorphism as a form of second-order polymorphism as for the mere types of functional strategies. Secondly, we use an encoding scheme of run-time type case for mixing uniform and type-specific behaviour. Thirdly, we base all traversal on a fundamental combinator for folding over constructor applications.Using this model, we capture common strategic traversal schemes in a highly parameterised style. We study two original forms of parameterisation. Firstly, we design parameters for the specific control-flow, data-flow and traversal characteristics of more concrete traversal schemes. Secondly, we use overloading to postpone commitment to a specific type scheme of traversal. The resulting portfolio of traversal schemes can be regarded as a challenging benchmark for setups for typed generic programming.The way we develop the model and the suite of traversal schemes, it becomes clear that parameterised + typed strategic programming is best viewed as a potent combination of certain bits of parametric, intensional, polytypic, and ad-hoc polymorphism.
Article
Full-text available
Grammar deployment is the process of turning a given grammar specification into a working parser. The Grammar Deployment Kit (for short, GDK) provides tool support in this process based on grammar engineering methods. We are mainly interested in the deployment of grammars for software renovation tools, that is, tools for software re- and reverse engineering. The current version of GDK is optimized for Cobol. We assume that grammar deployment starts from an initial grammar specification which is maybe still ambiguous or even incomplete. In practice, grammar deployment binds unaffordable human resources because of the unavailability of suitable grammar specifications, the diversity of parsing technology as well as the limitations of the technology, integration problems regarding the development of software renovation functionality, and the lack of tools and adherence to firm methods for grammar engineering. GDK helps to largely automate grammar deployment because tool support for grammar adaptation and parser generation is provided. We support different parsing technologies, among them btyacc, that is, yacc with backtracking. GDK is free software.
Article
Full-text available
SmartTools is a semantic framework generator, based on XML and object technologies. Thanks to a process of automatic generation from specifications, SmartTools makes it possible to quickly develop environments dedicated to domain-specific and programming languages. Some of these specifications (XML, DTD, Schemas, XSLT) are issued from the W3C which is an important source of varied emerging domain-specific languages. SmartTools uses object technologies such as visitor patterns and aspect-oriented programming. It provides code generation adapted to the usage of those technologies to support the development of semantic analyses. In this way, we obtain at minimal cost the design and implementation of a modular development platform which is open, interactive, uniform, and most important prone to evolution.
Conference Paper
Full-text available
Lacking support for generic traversal, functional programming languages suffer from a scalability problem when applied to large-scale program transformation problems. As a solution, we introduce functional strategies: typeful generic functions that not only can be applied to terms of any type, but which also allow generic traversal into subterms. We show how strategies are modelled inside a functional language, and we present a combinator library including generic traversal combinators. We illustrate our technique of programming with functional strategies by an implementation of the extract method refactoring for Java.
Article
We present two complementary approaches to writing XML document-processing applications in a functional language.In the first approach, the generic tree structure of XML documents is used as the basis for the design of a library of combinators for generic processing: selection, generation, and transformation of XML trees.The second approach is to use a type-translation framework for treating XML document type definitions (DTDs) as declarations of algebraic data types, and a derivation of the corresponding functions for reading and writing documents as typed values in Haskell.
Chapter
This paper presents a set of tools supporting the construction of nearly every compiler phase. Design goals of this tool box have been practical usability, significantly reduced effort for compiler construction, and high quality of the generated compilers. Especially efficiency should be competitive to hand crafting. Currently modules in the target languages C and Modula-2 can be generated. First realistic applications demonstrate the excellent performance of the tools and show that the tools allow the construction of production quality compilers.
Conference Paper
The Visitor design pattern allows the encapsulation of polymorphic behavior outside the class hierarchy on which it operates. A common application of Visitor is the encapsulation of tree traversals. A clean separation can be made between the generic parts of the combinator set and the parts that are specific to a particular class hierarchy. The generic parts form a reusable framework. The generic parts form a reusable framework. The specific parts can be generated from a (tree) grammar. Due to this separation, programming with visitor combinators becomes a form of generic programming with significant reuse of (visitor) code.