4,504 research outputs found
Common Subexpression Elimination in a Lazy Functional Language
Common subexpression elimination is a well-known compiler optimisation that saves time by avoiding the repetition of the same computation. To our knowledge it has not yet been applied to lazy functional programming languages, although there are several advantages. First, the referential transparency of these languages makes the identification of common subexpressions very simple. Second, more common subexpressions can be recognised because they can be of arbitrary type whereas standard common subexpression elimination only shares primitive values. However, because lazy functional languages decouple program structure from data space allocation and control flow, analysing its effects and deciding under which conditions the elimination of a common subexpression is beneficial proves to be quite difficult. We developed and implemented the transformation for the language Haskell by extending the Glasgow Haskell compiler and measured its effectiveness on real-world programs
FliPpr: A Prettier Invertible Printing System
When implementing a programming language, we often write
a parser and a pretty-printer. However, manually writing both programs
is not only tedious but also error-prone; it may happen that a pretty-printed
result is not correctly parsed. In this paper, we propose FliPpr,
which is a program transformation system that uses program inversion
to produce a CFG parser from a pretty-printer. This novel approach
has the advantages of fine-grained control over pretty-printing, and easy
reuse of existing efficient pretty-printer and parser implementations
Linear Haskell: practical linearity in a higher-order polymorphic language
Linear type systems have a long and storied history, but not a clear path
forward to integrate with existing languages such as OCaml or Haskell. In this
paper, we study a linear type system designed with two crucial properties in
mind: backwards-compatibility and code reuse across linear and non-linear users
of a library. Only then can the benefits of linear types permeate conventional
functional programming. Rather than bifurcate types into linear and non-linear
counterparts, we instead attach linearity to function arrows. Linear functions
can receive inputs from linearly-bound values, but can also operate over
unrestricted, regular values.
To demonstrate the efficacy of our linear type system - both how easy it can
be integrated in an existing language implementation and how streamlined it
makes it to write programs with linear types - we implemented our type system
in GHC, the leading Haskell compiler, and demonstrate two kinds of applications
of linear types: mutable data with pure interfaces; and enforcing protocols in
I/O-performing functions
Structure and Properties of Traces for Functional Programs
The tracer Hat records in a detailed trace the computation of a program written in the lazy functional language Haskell. The trace can then be viewed in various ways to support program comprehension and debugging. The trace was named the augmented redex trail. Its structure was inspired by standard graph rewriting implementations of functional languages. Here we describe a model of the trace that captures its essential properties and allows formal reasoning. The trace is a graph constructed by graph rewriting but goes beyond simple term graphs. Although the trace is a graph whose structure is independent of any rewriting strategy, we define the trace inductively, thus giving us a powerful method for proving its properties
- ā¦