11 research outputs found
A shortcut fusion rule for circular program calculation
Circular programs are a powerful technique to express multiple traversal algorithms as a single traversal function in a lazy setting. In this paper, we present a shortcut deforestation technique to calculate circular programs. The technique we propose takes as input the composition of two functions, such that the first builds an intermediate structure and some additional context information which are then processed by the second one, to produce the final result. Our transformation into circular programs achieves intermediate structure deforestation and multiple traversal elimination. Furthermore, the calculated programs preserve the termination properties of the original ones
Shortcut fusion rules for the derivation of circular and higher-order programs
Functional programs often combine separate parts using intermediate data structures for communicating results. Programs so defined are modular, easier to understand and maintain, but suffer from inefficiencies due to the generation of those gluing data structures. To eliminate such redundant data structures, some program transformation techniques have been proposed. One such technique is shortcut fusion, and has been studied in the context of both pure and monadic functional programs. In this paper, we study several shortcut fusion extensions, so that, alternatively, circular or higher-order programs are derived. These extensions are also provided for effect-free programs and monadic ones. Our work results in a set of generic calculation rules, that are widely applicable, and whose correctness is formally established.Fundação para a Ciência e a Tecnologi
Catamorphism-based program transformations for non-strict functional languages
In functional languages intermediate data structures are often used as glue to connect
separate parts of a program together. These intermediate data structures are useful because
they allow modularity, but they are also a cause of inefficiency: each element need to be
allocated, to be examined, and to be deallocated.
Warm fusion is a program transformation technique which aims to eliminate intermediate
data structures. Functions in a program are first transformed into the so called build-cata
form, then fused via a one-step rewrite rule, the cata-build rule. In the process of the
transformation to build-cata form we attempt to replace explicit recursion with a fixed
pattern of recursion (catamorphism).
We analyse in detail the problem of removing - possibly mutually recursive sets of -
polynomial datatypes.
Wehave implemented the warm fusion method in the Glasgow Haskell Compiler, which has
allowed practical feedback. One important conclusion is that catamorphisms and fusion
in general deserve a more prominent role in the compilation process. We give a detailed
measurement of our implementation on a suite of real application programs
Design, implementation and calculation of circular programs
Tese de doutoramento em Informática
(ramo do Conhecimento Fundamentos da Computação)Circular programming is a powerful technique to express multiple traversal
algorithms as a single traversal function in a lazy setting. Such a (virtual)
circular program may contain circular definitions, that is, arguments of function
calls that are also results of that same calls. Although circular definitions
always induce non-termination under a strict evaluation mechanism, they can
sometimes be immediately evaluated using a lazy evaluation strategy. The
lazy engine is able to compute the right evaluation order, if that order exists.
Indeed, using this style of circular programming, the programmer does not
have to concern him/herself with the definition and the scheduling of the
different traversal functions, since a single (traversal) function has to be defined.
Moreover, because there is a single traversal function, the programmer
does not have to define intermediate gluing data structures to convey values
computed in one traversal and needed in following ones, either.
In this Thesis, we present our studies on the design, implementation and
calculation of circular programs. We start by developing techniques to transform
circular programs into strict ones. Then, we introduce calculation rules
to obtain circular programs from strict equivalents, both in the context of
pure and monadic programming. Because we use calculation techniques we
guarantee that the resulting circular programs are equivalent to the strict
ones we start with. In this Thesis, we also perform a series of benchmarks
comparing the running performances of circular programs and the programs
we are able to derive from circular programs.A utilização de programas circulares na implementação de algoritmos de programação é uma técnica poderosa que permite, num paradigma lazy, implementar soluções que efectuam múltiplas travessias sobre uma ou mais estruturas de dados como um programa que efectua apenas uma travessia sobre uma única estrutura de dados. Num programa (virtualmente) circular podem ocorrer definições circulares, isto é, invocações de funções onde um argumento da invocação é, ao mesmo tempo, um resultado da mesma invocação. Embora este tipo de definições induza não terminação num paradigma estrito, a verdade é que, num paradigma lazy, elas podem ser desde logo executadas utilizando uma estratégia baseada em lazy evaluation: a máquina lazy é capaz de determinar o escalonamento correcto das computações, se ele existir. Na verdade, utilizando este método de programação, o(a) programador(a) não tem de definir nem de escalonar as diferentes travessias, uma vez que apenas uma função necessita de ser implementada. Para além disso, porque existe apenas função, e uma vez que essa função realiza apenas uma travessia, o(a) programador(a) também não é forçado a definir estruturas de dados intermédias para colar as diferentes travessias.
Nesta Tese são apresentados os nossos estudos relativos ao desenho, implementação e cálculo de programas circulares. Começamos por desenvolver técnicas de transformação de programas circulares em programas estritos. Depois apresentamos regras de cálculo que permitem obter programas circulares a partir de estritos, equivalentes, tanto no contexto de funções puras como no contexto de funções monádicas. Uma vez que, neste trabalho, utilizamos técnicas de cálculo de programas, é possível garantir a correcção da transformação que propomos. Por fim, realizamos uma bateria de testes que permitem comparar a performance de programas circulares com a dos programas que derivamos a partir deles.Fundacão para a Ciência e Tecnologia (FCT)grant No. SFRH/BD/19186/200
Bidirectional Programming and its Applications
Many problems in programming involve pairs of computations that cancel out each other’s effects; some examples include parsing/printing, embed- ding/projection, marshalling/unmarshalling, compressing/de-compressing etc. To avoid duplication of effort, the paradigm of bidirectional programming aims at to allow the programmer to write a single program that expresses both computations. Despite being a promising idea, existing studies mainly focus on the view-update problem in databases and its variants; and the impact of bidirectional programming has not reached the wider community. The goal of this thesis is to demonstrate, through concrete language designs and case studies, the relevance of bidirectional programming, in areas of computer science that have not been previously explored.
In this thesis, we will argue for the importance of bidirectional programming in programming language design and compiler implementation. As evidence for this, we will propose a technique for incremental refactoring, which relies for its correctness on a bidirectional language and its properties, and devise a framework for implementing program transformations, with bidirectional properties that allow program analyses to be carried out in the transformed program, and have the results reported in the source program.
Our applications of bidirectional programming to new areas bring up fresh challenges. This thesis also reflects on the challenges, and studies their impact to the design of bidirectional systems. We will review various design goals, including expressiveness, robustness, updatability, efficiency and easy of use, and show how certain choices, especially regarding updatability, can have significant influence on the effectiveness of bidirectional systems
Hfusion : a fusion tool based on acid rain plus extensions
When constructing programs, it is a usual practice to compose algorithms that solve simpler problems to solve a more complex one. This principle adapts so well to software development because it provides a structure to understand, design, reuse and test programs. In functional languages, algorithms are usually connected through the use of intermediate data structures, which carry the data from one algorithm to another one. The data structures impose a load on the algorithms to allocate, traverse and deallocate them. To alleviate this ine ciency, automatic program transformations have been studied, which produce equivalent programs that make less use of intermediate data structures. We present a set of automatic program transformation techniques based on algebraic laws known as Acid Rain. These techniques allow to remove intermediate data structures in programs containing primitive recursive functions, mutually recursive functions and functions with multiple recursive arguments. We also provide an experimental implementation of our techniques which allows their application on user supplied programs
HERMIT: Mechanized Reasoning during Compilation in the Glasgow Haskell Compiler
It is difficult to write programs which are both correct and fast. A promising approach, functional programming, is based on the idea of using pure, mathematical functions to construct programs. With effort, it is possible to establish a connection between a specification written in a functional language, which has been proven correct, and a fast implementation, via program transformation. When practiced in the functional programming community, this style of reasoning is still typically performed by hand, by either modifying the source code or using pen-and-paper. Unfortunately, performing such semi-formal reasoning by directly modifying the source code often obfuscates the program, and pen-and-paper reasoning becomes outdated as the program changes over time. Even so, this semi-formal reasoning prevails because formal reasoning is time-consuming, and requires considerable expertise. Formal reasoning tools often only work for a subset of the target language, or require programs to be implemented in a custom language for reasoning. This dissertation investigates a solution, called HERMIT, which mechanizes reasoning during compilation. HERMIT can be used to prove properties about programs written in the Haskell functional programming language, or transform them to improve their performance. Reasoning in HERMIT proceeds in a style familiar to practitioners of pen-and-paper reasoning, and mechanization allows these techniques to be applied to real-world programs with greater confidence. HERMIT can also re-check recorded reasoning steps on subsequent compilations, enforcing a connection with the program as the program is developed. HERMIT is the first system capable of directly reasoning about the full Haskell language. The design and implementation of HERMIT, motivated both by typical reasoning tasks and HERMIT's place in the Haskell ecosystem, is presented in detail. Three case studies investigate HERMIT's capability to reason in practice. These case studies demonstrate that semi-formal reasoning with HERMIT lowers the barrier to writing programs which are both correct and fast
Java stream optimization through program fusion
Dissertação de mestrado integrado em Computer ScienceCombining different programs or code fragments is a natural way to build larger programs.
This allows programmers to better separate a complex problem into simple parts.
Furthermore, by writing programs in a modular way, we increase code reusability.
However, these simple parts need to be connected somehow. These connections are done
via intermediate structures that communicate results between the different components,
harming performance because of the overhead introduced by the allocation and deallocation
of multiple structures.
Fusion, a very commonly used technique in functional programming, aims to remove the
creation of these unnecessary structures, as they don’t take part in the final result.
With the introduction of streams and lambda expressions, Java made its way into a more
functional programming style. Yet, these mechanisms lack optimization and the adaptation
of fusion techniques used by some compilers for functional languages could benefit the
performance of Java streams.
In this thesis, we study how functional fusion can be adapted to Java Streams.Combinar diferentes programas ou fragmentos de código é uma forma natural de construir
programas maiores. Isto permite aos programadores melhor separar um problema
complexo em partes simples. Além disso, ao escrever programas de forma modular, estamos
a aumentar a reutilização do código.
Contudo, estas partes têm de ser ligadas de alguma maneira. Estas conexões são feitas
via estruturas intermédias que comunicam os resultados entre os diferentes componentes,
prejudicando a performance com o overhead introduzido pela alocação e desalocação de várias
estruturas.
A fusão, uma técnica muito usada em programação funcional, pretende remover a criação
destas estruturas desnecessárias, uma vez que não tomam parte no resultado final.
Com a introdução de streams e expressões lambda, o Java abriu caminho para um estilo
de programação mais funcional. Mesmo assim, estes mecanismos não possuem otimização
e a adaptação de técnicas de fusão utilizadas por alguns compiladores de linguagens funcionais
poderiam beneficiar a performance das streams do Java.
Nesta dissertação, é estudado como a fusão em programação funcional pode ser adaptada
às streams do Java.This work is funded by ERDF - European Regional Development Fund through the
Operational Programme for Competitiveness and Internationalisation – COMPETE 2020
Programme and by National Funds through the FCT - Foundation for Science and Technology
within the project FCOMP-01-0124-FEDER-020484 and grant ref. BI2-2017_PTDC/EEI-ESS/5341/2014_UMINHO
Categorical semantics and composition of tree transducers
In this thesis we see two new approaches to compose tree transducers and more general to fuse functional programs. The first abroach is based on initial algebras. We prove a new variant of the acid rain theorem for mutually recursive functions where the build function is substituted by a concrete functor. Moreover, we give a symmetric form (i.e. consumer and producer have the same syntactic form) of our new acid rain theorem where fusion is composition in a category and thus in particular associative. Applying this to compose top-down tree transducers yields the same result (on a syntactic level) as the classical top-down tree transducer composition. The second approach is based on free monads and monad transformers. In the same way as monoids are used in the theory of character string automata, we use monads in the theory of tree transducers. We generalize the notion of a tree transducer defining the monadic transducer, and we prove an according fusion theorem. Moreover, we prove that homomorphic monadic transducers are semantically equivalent. The latter makes it possible to compose syntactic classes of tree transducers (or particular functional programs) by simply composing endofunctors