To send content items to your account,
please confirm that you agree to abide by our usage policies.
If this is the first time you use this feature, you will be asked to authorise Cambridge Core to connect with your account.
Find out more about sending content to .

To send content to your Kindle, first ensure no-reply@cambridge.org
is added to your Approved Personal Document E-mail List under your Personal Document Settings
on the Manage Your Content and Devices page of your Amazon account. Then enter the ‘name’ part
of your Kindle email address below.
Find out more about sending to your Kindle.

Note you can select to send to either the @free.kindle.com or @kindle.com variations.
‘@free.kindle.com’ emails are free but can only be sent to your device when it is connected to wi-fi.
‘@kindle.com’ emails can be delivered even when you are not connected to wi-fi, but note that service fees apply.

By using this service, you agree that you will only keep articles for personal use, and will not openly distribute them via Dropbox, Google Drive or other file sharing services.
Please confirm that you accept the terms of use.

Volume
8 -
Issue
4
-
July 1998

Editorial

In the end, research on functional languages does little good unless
they are used
to write something other than compilers for functional languages. However,
if one
scans a typical functional programming conference or journal, one mainly
sees papers
on twists in language design, speed-ups in compiled code, clever new analyses,
or
refinements to semantic models. It much less common to see a paper that
considers
a functional language as a tool to some other practical end. We would like
to see
this change.

The Journal of Functional Programming carries, and will continue
to carry, articles
on all aspects of functional programming from lambda calculus theory to
language
design to implementation. But we have specially sought, and will continue
to seek,
papers on functional programming practice and experience.

Research and papers on practice and experience sometimes receive less
attention
because they are perceived as possessing less academic content. So we want
to
remind potential authors that we have published a number of papers on this
topic
in the past, and to spell out the criteria we apply to such papers.

Many, perhaps even most, algorithms that involve data structures
are traditionally
expressed by incremental updates of the data structures. In functional
languages,
however, incremental updates are usually both clumsy and inefficient, especially
when the data structure is an array.

In functional languages, we instead prefer to express such array algorithms
using
monolithic arrays – wholesale creation of the final answer
– both for succinctness of
expression, efficiency (only one array created) and (sometimes) implicit
parallelism.
The ease with which the solution can be reformulated of course depends
on the
problem, and varies from trivial (e.g. matrix multiplication), to challenging
(e.g.
solving linear equation systems using Gauss elimination, which in fact
can be done
by creating only two arrays, recursively defined, of which one is the answer).
Other
problems have been notoriously resistant to attack; these usually involve
some
unpredictable processing order of the elements. One such problem is graph
marking,
i.e. marking the nodes reachable from a set of roots. Hitherto, no functional
method
has been known except emulating the traditional imperative solution (King
&
Launchbury, 1995; Launchbury & Peyton Jones, 1995).

The contribution of this paper is to show how this problem, and some
related
ones, can be solved using a novel array creation primitive, lazier than
previous ones.

In this paper we give a big-step Structured Operational Semantics
(SOS), in the style of
Plotkin, Kahn and Milner, of a significant fragment of the functional programming
language
Scheme, including quote, eval, quasiquote and unquote. The SOS
formalism allows us to
discuss incrementally the various features of the language and to keep
a low mathematical
overhead, thus producing a rigorous account of the semantics of a ‘real’
programming
language, which nonetheless has a pedagogical value. More specifically,
we formalize four
strictly increasing fragments of Scheme, using a number of formal systems
which express the
evaluation of expressions, the display of output results, and the handling
of errors.

We describe a system that supports source-level integration of
ML-like functional language
code with ANSI C or Ada83 code. The system works by translating the functional
code into
type-correct, ‘vanilla’ C or Ada; it offers simple, efficient,
type-safe inter-operation between
new functional code components and ‘legacy’ third-generation-language
components. Our
translator represents a novel synthesis of techniques including user-parameterized
specification
of primitive types and operators; removal of polymorphism by code specialization;
removal of
higher-order functions using closure datatypes and interpretation; and
aggressive optimization
of the resulting first-order code, which can be viewed as encoding the
result of a closure
analysis. Programs remain fully typed at every stage of the translation
process, using only
simple, standard type systems. Target code runs at speeds comparable to
the output of current
optimizing ML compilers, even though handicapped by a conservative garbage
collector.

In type theory a proposition is represented by a type, the type
of its proofs. As a consequence,
the equality relation on a certain type is represented by a binary family
of types. Equality on
a type may be conventional or inductive. Conventional equality means that
one particular
equivalence relation is singled out as the equality, while inductive
equality – which we
also call identity – is inductively defined as the ‘smallest
reflexive relation’. It is sometimes
convenient to know that the type representing a proposition is collapsed,
in the sense that all
its inhabitants are identical. Although uniqueness of identity proofs for
an arbitrary type is
not derivable inside type theory, there is a large class of types for which
it may be proved.
Our main result is a proof that any type with decidable identity has unique
identity proofs.
This result is convenient for proving that the class of types with decidable
identities is closed
under indexed sum. Our proof of the main result is completely formalized
within a kernel
fragment of Martin-Löf's type theory and mechanized using ALF.
Proofs of auxiliary lemmas
are explained in terms of the category theoretical properties of identity.
These suggest two
coherence theorems as the result of rephrasing the main result in a context
of conventional
equality, where the inductive equality has been replaced by, in the former,
an initial category
structure and, in the latter, a smallest reflexive relation.

This paper is a tutorial on defining recursive descent parsers
in Haskell. In the spirit
of one-stop shopping, the paper combines material from three areas
into a single
source. The three areas are functional parsers (Burge, 1975; Wadler, 1985;
Hutton,
1992; Fokker, 1995), the use of monads to structure functional programs
(Wadler,
1990, 1992a, 1992b), and the use of special syntax for monadic programs
in Haskell
(Jones, 1995; Peterson et al., 1996). More specifically, the paper
shows how to define
monadic parsers using do notation in Haskell.

Of course, recursive descent parsers defined by hand lack the efficiency
of bottom-up
parsers generated by machine (Aho et al., 1986; Mogensen, 1993;
Gill and
Marlow, 1995). However, for many research applications, a simple recursive
descent
parser is perfectly sufficient. Moreover, while parser generators typically
offer a
fixed set of combinators for describing grammars, the method described
here is
completely extensible: parsers are first-class values, and we have the
full power of
Haskell available to define new combinators for special applications. The
method is
also an excellent illustration of the elegance of functional programming.